mirror of
https://github.com/aljazceru/breez-sdk-docs.git
synced 2025-12-20 23:34:19 +01:00
add python examples
This commit is contained in:
@@ -71,7 +71,7 @@ if let Some(node_state) = sdk.node_info()? {
|
|||||||
<div slot="title">Swift</div>
|
<div slot="title">Swift</div>
|
||||||
<section>
|
<section>
|
||||||
|
|
||||||
The first step is to register a new node
|
The first step is to register a new node. In order to do that a seed is needed.
|
||||||
## Registering a new node
|
## Registering a new node
|
||||||
```swift
|
```swift
|
||||||
do {
|
do {
|
||||||
@@ -113,8 +113,8 @@ class SDKListener: EventListener {
|
|||||||
var config = defaultConfig(envType: EnvironmentType.production)
|
var config = defaultConfig(envType: EnvironmentType.production)
|
||||||
|
|
||||||
// Customize the config object according to your needs
|
// Customize the config object according to your needs
|
||||||
config.apiKey = "your API key";
|
config.apiKey = "your API key"
|
||||||
config.workingDir = "path to an existing directory";
|
config.workingDir = "path to an existing directory"
|
||||||
|
|
||||||
do {
|
do {
|
||||||
let sdk = try initServices(config: config, seed: seed, creds: credentials, listener: SDKListener());
|
let sdk = try initServices(config: config, seed: seed, creds: credentials, listener: SDKListener());
|
||||||
@@ -140,7 +140,7 @@ do {
|
|||||||
<div slot="title">React Native</div>
|
<div slot="title">React Native</div>
|
||||||
<section>
|
<section>
|
||||||
|
|
||||||
The first step is to register a new node
|
The first step is to register a new node. In order to do that a seed is needed.
|
||||||
## Registering a new node
|
## Registering a new node
|
||||||
```typescript
|
```typescript
|
||||||
try {
|
try {
|
||||||
@@ -224,10 +224,6 @@ try {
|
|||||||
Uint8List seed = await mnemonicToSeed("<mnemonics words>");
|
Uint8List seed = await mnemonicToSeed("<mnemonics words>");
|
||||||
GreenlightCredentials credentials = await recoverNode(network: Network.Bitcoin, seed: seed, config: config);
|
GreenlightCredentials credentials = await recoverNode(network: Network.Bitcoin, seed: seed, config: config);
|
||||||
```
|
```
|
||||||
|
|
||||||
Once the credentials are retrieved they should be saved in a secured storage.
|
|
||||||
The next step is to initialize the SDK and start the node:
|
|
||||||
|
|
||||||
## Initializing the SDK
|
## Initializing the SDK
|
||||||
```dart
|
```dart
|
||||||
// SDK events listener
|
// SDK events listener
|
||||||
@@ -254,7 +250,6 @@ try {
|
|||||||
// handle error
|
// handle error
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
At any point we can fetch our balance from the Greenlight node:
|
At any point we can fetch our balance from the Greenlight node:
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
@@ -267,6 +262,65 @@ try {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
</section>
|
</section>
|
||||||
|
<div slot="title">Python</div>
|
||||||
|
<section>
|
||||||
|
|
||||||
|
The first step is to register a new node. In order to do that a seed is needed.
|
||||||
|
|
||||||
|
## Registering a new node
|
||||||
|
```python
|
||||||
|
try :
|
||||||
|
seed = mnemonic_to_seed("<mnemonics words>")
|
||||||
|
invite_code = "<your greenlight invite code>"
|
||||||
|
|
||||||
|
# register_node takes either greenlight credentials (certifate & key) or invite code.
|
||||||
|
# At this example we are using the invite code option.
|
||||||
|
credentials = register_node(Network.BITCOIN, seed, inviteCode)
|
||||||
|
except Exception as error:
|
||||||
|
# Handle error
|
||||||
|
```
|
||||||
|
|
||||||
|
## Recovering an existing node
|
||||||
|
```python
|
||||||
|
seed = mnemonic_to_seed("<mnemonics words>")
|
||||||
|
credentials = recover_node(Network.BITCOIN, seed)
|
||||||
|
```
|
||||||
|
|
||||||
|
Once the credentials are retrieved they should be saved in a secured storage.
|
||||||
|
The next step is to initialize the SDK and start the node:
|
||||||
|
|
||||||
|
## Initializing the SDK
|
||||||
|
```python
|
||||||
|
# SDK events listener
|
||||||
|
class SDKListener(breez_sdk.EventListener):
|
||||||
|
def on_event(self, event):
|
||||||
|
print(event)
|
||||||
|
|
||||||
|
# Create the default config
|
||||||
|
config = default_config(EnvironmentType.PRODUCTION)
|
||||||
|
|
||||||
|
# Customize the config object according to your needs
|
||||||
|
config.api_key = "your API key"
|
||||||
|
config.working_dir = "path to an existing directory"
|
||||||
|
|
||||||
|
try:
|
||||||
|
sdk_services = init_services(config,seed,creds,SDKListener())
|
||||||
|
sdk_services.start()
|
||||||
|
except Exception as error:
|
||||||
|
# Handle error
|
||||||
|
```
|
||||||
|
|
||||||
|
At any point we can fetch our balance from the Greenlight node:
|
||||||
|
|
||||||
|
```python
|
||||||
|
try:
|
||||||
|
node_info = node_info()
|
||||||
|
ln_balance = node_info.channels_balance_msat
|
||||||
|
onchain_balance = node_info.onchain_balance_msat
|
||||||
|
except Exception as error:
|
||||||
|
# Handle error
|
||||||
|
```
|
||||||
|
</section>
|
||||||
</custom-tabs>
|
</custom-tabs>
|
||||||
|
|
||||||
You are now ready to receive a Lightning [payment](payments.md).
|
You are now ready to receive a Lightning [payment](payments.md).
|
||||||
|
|||||||
@@ -52,3 +52,6 @@ dependencies:
|
|||||||
breez_sdk:
|
breez_sdk:
|
||||||
path: <relative-path-to>/breez-sdk/libs/sdk-flutter
|
path: <relative-path-to>/breez-sdk/libs/sdk-flutter
|
||||||
```
|
```
|
||||||
|
## Python
|
||||||
|
|
||||||
|
Currently python is not acceable as a package and is needed to build it from soruce. Please visit [sdk-core](https://github.com/breez/breez-sdk/tree/main/libs/sdk-bindings#python) project for instructions.
|
||||||
|
|||||||
@@ -100,6 +100,30 @@ try {
|
|||||||
</section>
|
</section>
|
||||||
</custom-tab>
|
</custom-tab>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
<div slot="title">Python</div>
|
||||||
|
<section>
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Endpoint can also be of the form:
|
||||||
|
# keyauth://domain.com/auth?key=val
|
||||||
|
lnurlAuthUrl = "lnurl1dp68gurn8ghj7mr0vdskc6r0wd6z7mrww4excttvdankjm3lw3skw0tvdankjm3xdvcn6vtp8q6n2dfsx5mrjwtrxdjnqvtzv56rzcnyv3jrxv3sxqmkyenrvv6kve3exv6nqdtyv43nqcmzvdsnvdrzx33rsenxx5unqc3cxgeqgntfgu"
|
||||||
|
|
||||||
|
try:
|
||||||
|
parsed_input = parse_input(lnurl_auth_url)
|
||||||
|
|
||||||
|
if isinstance(parsed_input, breez_sdk.InputType.LN_URL_AUTH):
|
||||||
|
result = sdk_services.lnurl_auth(parsed_input.data)
|
||||||
|
if result.is_ok():
|
||||||
|
print("Successfully authenticated")
|
||||||
|
else:
|
||||||
|
print("Failed to authenticate")
|
||||||
|
except Exception as error:
|
||||||
|
# Handle error
|
||||||
|
```
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
## Supported Specs
|
## Supported Specs
|
||||||
|
|
||||||
- [LUD-01](https://github.com/lnurl/luds/blob/luds/01.md) LNURL bech32 encoding
|
- [LUD-01](https://github.com/lnurl/luds/blob/luds/01.md) LNURL bech32 encoding
|
||||||
|
|||||||
@@ -85,10 +85,27 @@ try {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
</section>
|
</section>
|
||||||
|
<div slot="title">Python</div>
|
||||||
|
<section>
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Endpoint can also be of the form:
|
||||||
|
# lnurlp://domain.com/lnurl-pay?key=val
|
||||||
|
# lnurl1dp68gurn8ghj7mr0vdskc6r0wd6z7mrww4excttsv9un7um9wdekjmmw84jxywf5x43rvv35xgmr2enrxanr2cfcvsmnwe3jxcukvde48qukgdec89snwde3vfjxvepjxpjnjvtpxd3kvdnxx5crxwpjvyunsephsz36jf
|
||||||
|
lnurl_pay_url = "lightning@address.com"
|
||||||
|
|
||||||
|
try:
|
||||||
|
parsed_input = breez_sdk.parse_input(lnurl_pay_url)
|
||||||
|
if isinstance(parsed_input, breez_sdk.InputType.LN_URL_PAY):
|
||||||
|
amount_sats = parsed_input.data.min_sendable
|
||||||
|
result = sdk_service.pay_lnurl(parsed_input.data, amount_sats, "comment")
|
||||||
|
except Exception as error:
|
||||||
|
# Handle error
|
||||||
|
```
|
||||||
|
</section>
|
||||||
</custom-tab>
|
</custom-tab>
|
||||||
|
|
||||||
## Supported Specs
|
## Supported Specs
|
||||||
|
|
||||||
- [LUD-01](https://github.com/lnurl/luds/blob/luds/01.md) LNURL bech32 encoding
|
- [LUD-01](https://github.com/lnurl/luds/blob/luds/01.md) LNURL bech32 encoding
|
||||||
- [LUD-06](https://github.com/lnurl/luds/blob/luds/06.md) `payRequest` spec
|
- [LUD-06](https://github.com/lnurl/luds/blob/luds/06.md) `payRequest` spec
|
||||||
- [LUD-16](https://github.com/lnurl/luds/blob/luds/16.md) LN Address
|
- [LUD-16](https://github.com/lnurl/luds/blob/luds/16.md) LN Address
|
||||||
|
|||||||
@@ -84,6 +84,23 @@ try {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
</section>
|
</section>
|
||||||
|
<div slot="title">Python</div>
|
||||||
|
<section>
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Endpoint can also be of the form:
|
||||||
|
# lnurlw://domain.com/lnurl-withdraw?key=val
|
||||||
|
lnurl_withdraw_url = "lnurl1dp68gurn8ghj7mr0vdskc6r0wd6z7mrww4exctthd96xserjv9mn7um9wdekjmmw843xxwpexdnxzen9vgunsvfexq6rvdecx93rgdmyxcuxverrvcursenpxvukzv3c8qunsdecx33nzwpnvg6ryc3hv93nzvecxgcxgwp3h33lxk"
|
||||||
|
|
||||||
|
try:
|
||||||
|
parsed_input = parse_input(lnurl_withdraw_url)
|
||||||
|
if isinstance(parsed_input, breez_sdk.InputType.LN_URL_WITHDRAW):
|
||||||
|
amount_sats = parsed_input.data.min_withdrawable
|
||||||
|
result = sdk_service.withdraw_lnurl(parsed_input.data, amount_sats, "comment")
|
||||||
|
except Exception as error:
|
||||||
|
# Handle error
|
||||||
|
```
|
||||||
|
</section>
|
||||||
</custom-tab>
|
</custom-tab>
|
||||||
|
|
||||||
## Supported Specs
|
## Supported Specs
|
||||||
|
|||||||
@@ -136,5 +136,38 @@ try {
|
|||||||
// handle error
|
// handle error
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
</section>
|
||||||
|
<div slot="title">Python</div>
|
||||||
|
<section>
|
||||||
|
|
||||||
|
## Receiving Lightning Payments
|
||||||
|
Breez SDK doesn't require you to open a channel and set up your inbound liquidity.
|
||||||
|
Breez SDK automatically connects your node to the LSP peer and you can now receive payments:
|
||||||
|
|
||||||
|
```python
|
||||||
|
try:
|
||||||
|
invoice = sdk_services.receive_payment(3000, "Invoice for 3000 sats")
|
||||||
|
except Exception as error:
|
||||||
|
# Handle error
|
||||||
|
```
|
||||||
|
|
||||||
|
## Sending Lightning Payments
|
||||||
|
```python
|
||||||
|
bolt11 = "..."
|
||||||
|
try:
|
||||||
|
sdk_services.send_payment(bolt11, 3000)
|
||||||
|
except Exception as error:
|
||||||
|
# Handle error
|
||||||
|
```
|
||||||
|
|
||||||
|
## Sending Spontaneous Lightning Payments
|
||||||
|
```python
|
||||||
|
let node_id = "..."
|
||||||
|
try:
|
||||||
|
sdk_services.send_spontaneous_payment(node_id, 3000)
|
||||||
|
except Exception as error:
|
||||||
|
# Handle error
|
||||||
|
```
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
</custom-tabs>
|
</custom-tabs>
|
||||||
@@ -144,7 +144,7 @@ try {
|
|||||||
```
|
```
|
||||||
</section>
|
</section>
|
||||||
<div slot="title">Dart</div>
|
<div slot="title">Dart</div>
|
||||||
<section>x
|
<section>
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
try {
|
try {
|
||||||
@@ -156,7 +156,6 @@ try {
|
|||||||
// handle error
|
// handle error
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Once you've sent the funds to the above address, the SDK will monitor this address for unspent confirmed outputs and use a trustless submarine swap to receive these into your Lightning node. You can always monitor the status of the current in-progress swap using the following code:
|
Once you've sent the funds to the above address, the SDK will monitor this address for unspent confirmed outputs and use a trustless submarine swap to receive these into your Lightning node. You can always monitor the status of the current in-progress swap using the following code:
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
@@ -166,7 +165,6 @@ try {
|
|||||||
// handle error
|
// handle error
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The process of receiving funds via an on-chain address is trustless and uses a submarine swap. This means there are two ways to spend the sent funds:
|
The process of receiving funds via an on-chain address is trustless and uses a submarine swap. This means there are two ways to spend the sent funds:
|
||||||
|
|
||||||
1. Either by a preimage that is exposed when the Lightning payment is completed - this is the positive case where the swap was successful.
|
1. Either by a preimage that is exposed when the Lightning payment is completed - this is the positive case where the swap was successful.
|
||||||
@@ -198,4 +196,54 @@ try {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
</section>
|
</section>
|
||||||
|
<div slot="title">Python</div>
|
||||||
|
<section>
|
||||||
|
|
||||||
|
```python
|
||||||
|
try:
|
||||||
|
swap_info = sdk_services.receive_onchain()
|
||||||
|
# Send your funds to the below bitcoin address
|
||||||
|
address = sdk_services.swap_info.bitcoin_address
|
||||||
|
except Exception as error:
|
||||||
|
# Handle error
|
||||||
|
```
|
||||||
|
|
||||||
|
Once you've sent the funds to the above address, the SDK will monitor this address for unspent confirmed outputs and use a trustless submarine swap to receive these into your Lightning node. You can always monitor the status of the current in-progress swap using the following code:
|
||||||
|
|
||||||
|
```python
|
||||||
|
try:
|
||||||
|
swap_info = sdk_services.in_progress_swap()
|
||||||
|
except Exception as error:
|
||||||
|
# Handle error
|
||||||
|
```
|
||||||
|
|
||||||
|
The process of receiving funds via an on-chain address is trustless and uses a submarine swap. This means there are two ways to spend the sent funds:
|
||||||
|
|
||||||
|
1. Either by a preimage that is exposed when the Lightning payment is completed - this is the positive case where the swap was successful.
|
||||||
|
2. Or by your node when the swap didn't complete within a certain timeout - this is the negative case where your node will execute a refund.
|
||||||
|
|
||||||
|
In order to execute a refund, you need to supply an on-chain address to where the refunded amount will be sent. The following code will retrieve the refundable swaps:
|
||||||
|
|
||||||
|
|
||||||
|
Once you have a refundable swap in hand, use the following code to execute a refund:
|
||||||
|
|
||||||
|
```python
|
||||||
|
try:
|
||||||
|
refundables = sdk_services.list_refundables()
|
||||||
|
except Exception as error:
|
||||||
|
# Handle error
|
||||||
|
```
|
||||||
|
|
||||||
|
Once you have a refundable swap in hand, use the follwing code to execute a refund:
|
||||||
|
|
||||||
|
```python
|
||||||
|
destination_address = "..."
|
||||||
|
sat_per_vbyte = <refund tx fee rate>
|
||||||
|
|
||||||
|
try:
|
||||||
|
sdk_services.refund(refundable.bitcoin_address, destination_address, sat_per_vbyte)
|
||||||
|
except Exception as error:
|
||||||
|
# Handle error
|
||||||
|
```
|
||||||
|
</section>
|
||||||
</custom-tabs>
|
</custom-tabs>
|
||||||
@@ -169,7 +169,6 @@ try {
|
|||||||
// handle error
|
// handle error
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The reverse swap will involve two on-chain transactions, for which the mining fees can only be estimated. They will happen
|
The reverse swap will involve two on-chain transactions, for which the mining fees can only be estimated. They will happen
|
||||||
automatically once the process is started, but the last two values above are these estimates to help you get a picture
|
automatically once the process is started, but the last two values above are these estimates to help you get a picture
|
||||||
of the total costs.
|
of the total costs.
|
||||||
@@ -180,7 +179,6 @@ Fetching the fees also tells you what is the range of amounts you can send:
|
|||||||
print(`Minimum amount, in sats: ${currentFees.min}`);
|
print(`Minimum amount, in sats: ${currentFees.min}`);
|
||||||
print(`Maximum amount, in sats: ${currentFees.max}`);
|
print(`Maximum amount, in sats: ${currentFees.max}`);
|
||||||
```
|
```
|
||||||
|
|
||||||
Once you checked the fees are acceptable, you can start the reverse swap:
|
Once you checked the fees are acceptable, you can start the reverse swap:
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
@@ -198,7 +196,6 @@ try {
|
|||||||
// handle error
|
// handle error
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Starting the reverse swap will trigger a HODL invoice payment, which will only be settled if the entire swap completes.
|
Starting the reverse swap will trigger a HODL invoice payment, which will only be settled if the entire swap completes.
|
||||||
This means you will see an outgoing pending payment in your list of payments, which locks those funds until the invoice
|
This means you will see an outgoing pending payment in your list of payments, which locks those funds until the invoice
|
||||||
is either settled or cancelled. This will happen automatically at the end of the reverse swap.
|
is either settled or cancelled. This will happen automatically at the end of the reverse swap.
|
||||||
@@ -216,6 +213,57 @@ try {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
</section>
|
</section>
|
||||||
|
<div slot="title">Python</div>
|
||||||
|
<section>
|
||||||
|
|
||||||
|
```python
|
||||||
|
try:
|
||||||
|
current_fees = sdk_services.fetch_reverse_swap_fees()
|
||||||
|
print("Percentage fee for the reverse swap service: ", current_fees.fees_percentage)
|
||||||
|
print("Estimated miner fees in sats for locking up funds: ", current_fees.fees_lockup)
|
||||||
|
print("Estimated miner fees in sats for claiming funds: ", current_fees.fees_claim)
|
||||||
|
except Exception as error:
|
||||||
|
# Handle error
|
||||||
|
```
|
||||||
|
|
||||||
|
The reverse swap will involve two on-chain transactions, for which the mining fees can only be estimated. They will happen
|
||||||
|
automatically once the process is started, but the last two values above are these estimates to help you get a picture
|
||||||
|
of the total costs.
|
||||||
|
|
||||||
|
Fetching the fees also tells you what is the range of amounts you can send:
|
||||||
|
|
||||||
|
```python
|
||||||
|
print("Minimum amount, in sats: ", current_fees.min)
|
||||||
|
print("Maximum amount, in sats: ", current_fees.max)
|
||||||
|
```
|
||||||
|
|
||||||
|
Once you checked the fees are acceptable, you can start the reverse swap:
|
||||||
|
|
||||||
|
```python
|
||||||
|
destination_address = "bc1.."
|
||||||
|
amount_sat = current_fees.min
|
||||||
|
|
||||||
|
try:
|
||||||
|
sdk.send_onchain(amount_sat, destination_address, current_fees.fees_hash)
|
||||||
|
except Exception as error:
|
||||||
|
# Handle erorr
|
||||||
|
```
|
||||||
|
|
||||||
|
Starting the reverse swap will trigger a HODL invoice payment, which will only be settled if the entire swap completes.
|
||||||
|
This means you will see an outgoing pending payment in your list of payments, which locks those funds until the invoice
|
||||||
|
is either settled or cancelled. This will happen automatically at the end of the reverse swap.
|
||||||
|
|
||||||
|
You can check its status with:
|
||||||
|
|
||||||
|
```python
|
||||||
|
try:
|
||||||
|
reverse_swaps = sdk_services.in_progress_reverse_swaps()
|
||||||
|
for rs in reverse_swaps:
|
||||||
|
print("Reverse swap ",rs.id , " in progress, status is ", rs.status)
|
||||||
|
except Exception as error:
|
||||||
|
# Handle erorr
|
||||||
|
```
|
||||||
|
</section>
|
||||||
</custom-tabs>
|
</custom-tabs>
|
||||||
If the reverse swap is successful, you'll get the on-chain payment on your destination address and the HODL invoice will
|
If the reverse swap is successful, you'll get the on-chain payment on your destination address and the HODL invoice will
|
||||||
change from pending to settled.
|
change from pending to settled.
|
||||||
|
|||||||
Reference in New Issue
Block a user