Skip to content

Commit e55fe2b

Browse files
Lightspark Engjklein24
authored andcommitted
Project import generated by Copybara.
GitOrigin-RevId: ac063da874fb6a6541fa6403e8a7674aa8178a7b
1 parent c3154a2 commit e55fe2b

2 files changed

Lines changed: 315 additions & 2 deletions

File tree

copy.bara.sky

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@ core.workflow(
4545
mode = "SQUASH",
4646

4747
origin_files = glob(
48-
["python-sdk/**", "copy.bara.sky"],
49-
exclude = ["python-sdk/examples/internal_example.py", "python-sdk/RELEASE-internal.md"],
48+
["python-sdk/**", "copy.bara.sky"]
5049
),
5150

5251
authoring = authoring.pass_thru("Lightspark Eng <engineering@lightspark.com>"),

examples/two_node_example.py

Lines changed: 314 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,314 @@
1+
# Copyright ©, 2022-present, Lightspark Group, Inc. - All Rights Reserved
2+
3+
import logging
4+
import math
5+
import os
6+
from datetime import datetime, timedelta
7+
8+
import lightspark
9+
10+
logger = logging.getLogger("lightspark")
11+
logger.setLevel(logging.DEBUG)
12+
13+
14+
#################################################################
15+
## MODIFY THOSE VARIABLES BEFORE RUNNING THE EXAMPLE
16+
#################################################################
17+
##
18+
## We defined those variables as environment variables, but if you are just
19+
## running the example locally, feel free to just set the values in Python.
20+
##
21+
## First, initialize your client ID and client secret. Those are available
22+
## in your account at https://app.lightspark.com/api_config
23+
api_token_client_id = os.environ.get("LIGHTSPARK_API_TOKEN_CLIENT_ID")
24+
api_token_client_secret = os.environ.get("LIGHTSPARK_API_TOKEN_CLIENT_SECRET")
25+
26+
##
27+
## Using the Lightspark web app, you need to create 2 nodes on the REGTEST
28+
## network, and open a channel between them. We are going to send and receive
29+
## payments between those 2 nodes in this example.
30+
## Enter their names and passwords in the variables below:
31+
##
32+
node_1_name = os.environ.get("LIGHTSPARK_EXAMPLE_NODE_1_NAME")
33+
node_1_password = os.environ.get("LIGHTSPARK_EXAMPLE_NODE_1_PASSWORD")
34+
node_2_name = os.environ.get("LIGHTSPARK_EXAMPLE_NODE_2_NAME")
35+
node_2_password = os.environ.get("LIGHTSPARK_EXAMPLE_NODE_2_PASSWORD")
36+
##
37+
################################################
38+
39+
# Let's start by creating a client
40+
41+
assert api_token_client_secret
42+
assert api_token_client_id
43+
assert node_1_name
44+
assert node_1_password
45+
assert node_2_name
46+
assert node_2_password
47+
48+
client = lightspark.LightsparkSyncClient(
49+
api_token_client_id=api_token_client_id,
50+
api_token_client_secret=api_token_client_secret,
51+
base_url=os.environ.get("LIGHTSPARK_EXAMPLE_BASE_URL"),
52+
)
53+
54+
# Get some fee estimates for Bitcoin (L1) transactions
55+
56+
fee_estimate = client.get_bitcoin_fee_estimate(
57+
bitcoin_network=lightspark.BitcoinNetwork.REGTEST
58+
)
59+
print(
60+
f"Fees for a fast transaction {fee_estimate.fee_fast.preferred_currency_value_approx} {fee_estimate.fee_fast.preferred_currency_unit}."
61+
)
62+
print(
63+
f"Fees for a cheap transaction {fee_estimate.fee_min.preferred_currency_value_approx} {fee_estimate.fee_min.preferred_currency_unit}."
64+
)
65+
print("")
66+
67+
# List your account's lightning nodes
68+
69+
account = client.get_current_account()
70+
print(f"Your account name is {account.name}.")
71+
print("")
72+
73+
74+
api_tokens_connection = account.get_api_tokens()
75+
print(f"You initially have {str(api_tokens_connection.count)} active API tokens.")
76+
print("")
77+
78+
(api_token, client_secret) = client.create_api_token(name="Test token", test_mode=True)
79+
print(f"Created API token {api_token.id}.")
80+
81+
api_tokens_connection = account.get_api_tokens()
82+
print(f"You now have {str(api_tokens_connection.count)} active API tokens.")
83+
print("")
84+
85+
client.delete_api_token(api_token_id=api_token.id)
86+
print(f"Deleted API token {api_token.id}.")
87+
88+
api_tokens_connection = account.get_api_tokens()
89+
print(f"You now have {str(api_tokens_connection.count)} active API tokens.")
90+
print("")
91+
92+
# Check our account's conductivity on REGTEST
93+
94+
print(
95+
f"Your account's conductivity on REGTEST is {account.get_conductivity(bitcoin_networks=[lightspark.BitcoinNetwork.REGTEST])}/10."
96+
)
97+
print("")
98+
99+
# Check your account's local and remote balances for REGTEST
100+
local_balance = account.get_local_balance(
101+
bitcoin_networks=[lightspark.BitcoinNetwork.REGTEST]
102+
)
103+
remote_balance = account.get_remote_balance(
104+
bitcoin_networks=[lightspark.BitcoinNetwork.REGTEST]
105+
)
106+
if local_balance and remote_balance:
107+
print(
108+
f"Your local balance is {local_balance.preferred_currency_value_approx} {local_balance.preferred_currency_unit}, your remote balance is {remote_balance.preferred_currency_value_approx} {remote_balance.preferred_currency_unit}."
109+
)
110+
111+
nodes_connection = account.get_nodes(
112+
first=50, bitcoin_networks=[lightspark.BitcoinNetwork.REGTEST]
113+
)
114+
if nodes_connection is None:
115+
raise Exception("Unable to fetch the nodes.")
116+
117+
print(f"You have {nodes_connection.count} nodes.")
118+
119+
node_1_id = None
120+
node_1_public_key = None
121+
node_2_id = None
122+
123+
for node in nodes_connection.entities:
124+
if node:
125+
print(f" - {node.display_name} ({node.status})")
126+
if node.display_name == node_1_name:
127+
node_1_id = node.id
128+
node_1_public_key = node.public_key
129+
elif node.display_name == node_2_name:
130+
node_2_id = node.id
131+
print("")
132+
133+
if node_1_id is None or node_2_id is None:
134+
raise Exception("Couldn't find the nodes.")
135+
136+
# List the transactions for our account
137+
138+
transactions_connection = account.get_transactions(
139+
first=100, bitcoin_network=lightspark.BitcoinNetwork.REGTEST
140+
)
141+
print(
142+
f"There is a total of {transactions_connection.count} transaction(s) on this account:"
143+
)
144+
deposit_transaction_id = None
145+
for transaction in transactions_connection.entities:
146+
print(
147+
f" - {transaction.typename} at {str(transaction.created_at)}: {transaction.amount.preferred_currency_value_approx} {transaction.amount.preferred_currency_unit.name} ({transaction.status.name})"
148+
)
149+
if transaction.typename == "Deposit":
150+
deposit_transaction_id = transaction.id
151+
152+
fees = None
153+
if (
154+
isinstance(transaction, lightspark.OutgoingPayment)
155+
or isinstance(transaction, lightspark.Withdrawal)
156+
or isinstance(transaction, lightspark.Deposit)
157+
or isinstance(transaction, lightspark.ChannelOpeningTransaction)
158+
or isinstance(transaction, lightspark.ChannelClosingTransaction)
159+
):
160+
fees = transaction.fees
161+
if fees:
162+
print(
163+
f" Paid {fees.preferred_currency_value_approx} {fees.preferred_currency_unit.name} in fees."
164+
)
165+
print("")
166+
167+
# Fetch transactions using pagination
168+
page_size = 10
169+
iterations = 0
170+
has_next = True
171+
after = None
172+
while has_next and iterations < 30:
173+
iterations += 1
174+
transactions_connection = account.get_transactions(
175+
first=page_size, bitcoin_network=lightspark.BitcoinNetwork.REGTEST, after=after
176+
)
177+
num = len(transactions_connection.entities)
178+
print(f"We got {num} transactions for the page (iteration #{iterations})")
179+
if transactions_connection.page_info.has_next_page:
180+
has_next = True
181+
after = transactions_connection.page_info.end_cursor
182+
print(" And we have another page!")
183+
else:
184+
has_next = False
185+
print(" And we're done!")
186+
print("")
187+
188+
189+
# Get the transactions that happened in the past day on REGTEST
190+
191+
transactions_connection = account.get_transactions(
192+
bitcoin_network=lightspark.BitcoinNetwork.REGTEST,
193+
after_date=datetime.now() - timedelta(hours=24),
194+
)
195+
print(f"We had {transactions_connection.count} transactions in the past 24 hours.")
196+
197+
# Get details for a transaction
198+
199+
assert deposit_transaction_id is not None
200+
deposit = client.get_entity(deposit_transaction_id, lightspark.Deposit)
201+
print("Details of deposit transaction")
202+
print(deposit)
203+
print("")
204+
205+
# Generate a payment request
206+
207+
invoice = client.create_invoice(
208+
node_id=node_1_id,
209+
amount_msats=42000,
210+
memo="Pizza!",
211+
)
212+
print(f"Invoice created from {node_1_name}:")
213+
print(f"Encoded invoice = {invoice.data.encoded_payment_request}")
214+
print("")
215+
216+
# Decode the payment request
217+
decoded_request = client.get_decoded_payment_request(
218+
encoded_payment_request=invoice.data.encoded_payment_request
219+
)
220+
assert isinstance(decoded_request, lightspark.InvoiceData)
221+
print("Decoded payment request:")
222+
print(" destination_public_key = " + str(decoded_request.destination.public_key))
223+
print(
224+
" amount = "
225+
+ str(decoded_request.amount.preferred_currency_value_approx)
226+
+ " "
227+
+ str(decoded_request.amount.preferred_currency_unit.name)
228+
)
229+
print(" memo = " + str(decoded_request.memo))
230+
print("")
231+
232+
# Let's send the payment.
233+
234+
# First, we need to recover the signing key.
235+
client.recover_node_signing_key(node_id=node_2_id, node_password=node_2_password)
236+
print(f"{node_2_name}'s signing key has been loaded.")
237+
238+
# Then we can send the payment
239+
payment = client.pay_invoice(
240+
node_id=node_2_id,
241+
encoded_invoice=invoice.data.encoded_payment_request,
242+
timeout_secs=60,
243+
maximum_fees_msats=500,
244+
)
245+
print(f"Payment to the invoice done with ID = {payment.id}")
246+
print("")
247+
248+
# Next let's try sending a payment to a node without an invoice
249+
assert node_1_public_key
250+
payment = client.send_payment(
251+
node_id=node_2_id,
252+
destination_public_key=node_1_public_key,
253+
amount_msats=2000,
254+
timeout_secs=60,
255+
maximum_fees_msats=500,
256+
)
257+
print(f"Payment directly to node without invoice done with ID = {payment.id}")
258+
print("")
259+
260+
# Get a wallet address
261+
address = client.create_node_wallet_address(node_id=node_1_id)
262+
print(f"Got a bitcoin address for {node_1_name}: {address}")
263+
print("")
264+
265+
# Withdraw funds!
266+
# TODO: Uncomment when withrawals are working again.
267+
# withdrawal = client.request_withdrawal(
268+
# node_id=node_2_id,
269+
# amount_sats=1000,
270+
# bitcoin_address=address,
271+
# withdrawal_mode=lightspark.WithdrawalMode.WALLET_THEN_CHANNELS,
272+
# )
273+
# print(f"Money was withdrawn with ID = {withdrawal.id}")
274+
# print("")
275+
276+
# Fetch the channels for Node 1
277+
node_1 = client.get_entity(
278+
node_1_id,
279+
lightspark.LightsparkNode,
280+
)
281+
if node_1 is None:
282+
raise Exception("Couldn't find node 1!")
283+
284+
channels_connection = node_1.get_channels(first=10)
285+
print(f"{node_1_name} has {channels_connection.count} channel(s):")
286+
for channel in channels_connection.entities:
287+
if channel.remote_node_id:
288+
remote_node = client.get_entity(channel.remote_node_id, lightspark.Node)
289+
alias = remote_node.alias if remote_node else "UNKNOWN"
290+
if channel.local_balance and channel.remote_balance:
291+
print(
292+
f" - With {alias}. Local/remote balance = {channel.local_balance.preferred_currency_value_approx} {channel.local_balance.preferred_currency_unit}/{channel.remote_balance.preferred_currency_value_approx} {channel.remote_balance.preferred_currency_unit}"
293+
)
294+
print("")
295+
296+
# Issue an arbitrary GraphQL request
297+
298+
result = client.execute_graphql_request(
299+
document="""
300+
query Test($networks: [BitcoinNetwork!]!) {
301+
current_account {
302+
name
303+
nodes(bitcoin_networks: $networks) {
304+
count
305+
}
306+
}
307+
}
308+
""",
309+
variables={"networks": [lightspark.BitcoinNetwork.REGTEST]},
310+
)
311+
312+
name = result["current_account"]["name"]
313+
count = result["current_account"]["nodes"]["count"]
314+
print(f"The account {name} has {count} nodes on the REGTEST network.")

0 commit comments

Comments
 (0)