mirror of
https://github.com/aljazceru/breez-sdk-docs.git
synced 2025-12-17 22:04:21 +01:00
Merge pull request #28 from breez/rn-lsp-fees
Add connecting LSPs, fiat currencies and calculating fees sections for RN
This commit is contained in:
@@ -3,12 +3,13 @@
|
||||
<custom-tabs category="lang">
|
||||
<div slot="title">Swift</div>
|
||||
<section>
|
||||
|
||||
Based on the API key provided to the Breez SDK, a default LSP is selected for your node to provide liquidity to it. To get the information about the selected LSP you can do the following:
|
||||
|
||||
```swift
|
||||
do {
|
||||
let lspId = let lspId = try sdk.lspId()
|
||||
let lspInfo = try sdk.fetchLspInfo(lspId: lspID!)
|
||||
let lspId = try sdk.lspId()
|
||||
let lspInfo = try sdk.fetchLspInfo(lspId: lspId!)
|
||||
} catch {
|
||||
// Handle error
|
||||
}
|
||||
@@ -18,14 +19,38 @@ When you have selected an LSP you may then connect to it.
|
||||
|
||||
```swift
|
||||
do {
|
||||
try sdk.connectLsp(lspId: lspID!)
|
||||
try sdk.connectLsp(lspId: lspId!)
|
||||
} catch {
|
||||
// Handle error
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
||||
<div slot="title">React Native</div>
|
||||
<section>
|
||||
|
||||
Based on the API key provided to the Breez SDK, a default LSP is selected for your node to provide liquidity to it. To get the information about the selected LSP you can do the following:
|
||||
|
||||
```typescript
|
||||
try {
|
||||
const lspId = await lspId()
|
||||
const lspInfo = await fetchLspInfo(lspId)
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
```
|
||||
|
||||
When you have selected an LSP you may then connect to it.
|
||||
|
||||
```typescript
|
||||
try {
|
||||
await connectLsp(lspId)
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
||||
<div slot="title">Dart</div>
|
||||
<section>
|
||||
|
||||
|
||||
@@ -1,11 +1,32 @@
|
||||
# Supporting fiat currencies
|
||||
|
||||
<custom-tabs category="lang">
|
||||
<div slot="title">React Native</div>
|
||||
<section>
|
||||
In order to list the availiable fiat currencies.
|
||||
|
||||
```typescript
|
||||
try {
|
||||
const fiatCurrencyList = await listFiatCurrencies()
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
```
|
||||
|
||||
To get the current BTC rate for the currencies.
|
||||
|
||||
```typescript
|
||||
try {
|
||||
const fiatRatesMap = fetchFiatRates()
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
```
|
||||
</section>
|
||||
<div slot="title">Dart</div>
|
||||
<section>
|
||||
|
||||
|
||||
In order to list the availiable fiat currencies.
|
||||
|
||||
```dart
|
||||
try {
|
||||
List<FiatCurrency> fiatCurrencyList = await listFiatCurrencies();
|
||||
@@ -18,7 +39,7 @@ To get the current BTC rate for the currencies.
|
||||
|
||||
```dart
|
||||
try {
|
||||
Map<String, Rate> fiatRatesMap = fetchFiatRates();
|
||||
Map<String, Rate> fiatRatesMap = fetchFiatRates();
|
||||
// print your desired rate
|
||||
print(fiatRatesMap["USD"]?.value);
|
||||
} catch(e) {
|
||||
@@ -26,11 +47,10 @@ try {
|
||||
}
|
||||
```
|
||||
</section>
|
||||
<div slot="title">python</div>
|
||||
<div slot="title">Python</div>
|
||||
<section>
|
||||
|
||||
|
||||
In order to list the availiable fiat currencies.
|
||||
|
||||
```python
|
||||
try:
|
||||
fiat_currencies = sdk_services.list_fiat_currencies()
|
||||
@@ -43,12 +63,24 @@ To get the current BTC rate for the currencies.
|
||||
|
||||
```python
|
||||
try:
|
||||
fiat_rates = sdk_services.sdk_services.fetch_fiat_rates()
|
||||
fiat_rates = sdk_services.fetch_fiat_rates()
|
||||
# print your desired rate
|
||||
except Exception as error:
|
||||
# Handle error
|
||||
```
|
||||
</section>
|
||||
<div slot="title">Go</div>
|
||||
<section>
|
||||
In order to list the availiable fiat currencies.
|
||||
|
||||
```go
|
||||
fiatCurrencies, err := sdkServices.ListFiatCurrencies()
|
||||
```
|
||||
|
||||
To get the current BTC rate for the currencies.
|
||||
|
||||
```go
|
||||
fiatRates, err := sdkServices.FetchFiatRates()
|
||||
```
|
||||
</section>
|
||||
</custom-tabs>
|
||||
@@ -127,7 +127,7 @@ try {
|
||||
// Connect to the Breez SDK make it ready for use
|
||||
const sdkServices = await connect(config, seed);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
console.log(error)
|
||||
}
|
||||
```
|
||||
|
||||
@@ -139,7 +139,7 @@ try {
|
||||
const lnBalance = nodeInfo.channelsBalanceMsat;
|
||||
const onchainBalance = nodeInfo.onchainBalanceMsat;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
console.log(error)
|
||||
}
|
||||
```
|
||||
</section>
|
||||
|
||||
@@ -97,7 +97,7 @@ do {
|
||||
|
||||
```typescript
|
||||
try {
|
||||
const swapInfo = await receiveOnchain();
|
||||
const swapInfo = await receiveOnchain()
|
||||
|
||||
// Send your funds to the below bitcoin address
|
||||
const address = swapInfo.bitcoinAddress;
|
||||
@@ -328,11 +328,11 @@ async fn calculate_fees_for_amount(amount_msat: u64) -> Result<u64> {
|
||||
// We calculate the dynamic fees in millisatoshis rounded to satoshis.
|
||||
let channel_dynamic_fee_msat =
|
||||
amount_msat * lsp_info.channel_fee_permyriad as u64 / 10_000 / 1000 * 1000;
|
||||
let fee_sat = max(
|
||||
let fee_msat = max(
|
||||
lsp_info.channel_minimum_fee_msat as u64,
|
||||
channel_dynamic_fee_msat,
|
||||
);
|
||||
Ok(fee_sat)
|
||||
)
|
||||
Ok(fee_msat)
|
||||
}
|
||||
```
|
||||
|
||||
@@ -347,29 +347,28 @@ To calculate the fees for a channel being opened by the LSP:
|
||||
|
||||
```swift
|
||||
func calculateChannelOpeningFee(amountMsats: Int64) -> Int64? {
|
||||
var channelOpeningFeeNeeded = isChannelOpeningFeeNeeded(amountMsats: amountMsats)
|
||||
if channelOpeningFeeNeeded {
|
||||
return calculateFeesForAmount(amountMsats: amountMsats)
|
||||
}
|
||||
return nil
|
||||
var channelOpeningFeeNeeded = isChannelOpeningFeeNeeded(amountMsats: amountMsats)
|
||||
if channelOpeningFeeNeeded {
|
||||
return calculateFeesForAmount(amountMsats: amountMsats)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
```
|
||||
|
||||
How to detect if open channel fees are needed:
|
||||
```swift
|
||||
func isChannelOpeningFeeNeeded(amountMsats: Int64) -> Bool {
|
||||
do {
|
||||
let nodeInfo = try sdk.nodeInfo()
|
||||
do {
|
||||
let nodeInfo = try sdk.nodeInfo()
|
||||
|
||||
if let inboundLiquidityMsats = nodeInfo?.inboundLiquidityMsats {
|
||||
return inboundLiquidityMsats <= amountMsats
|
||||
}
|
||||
|
||||
} catch {
|
||||
// Handle error
|
||||
}
|
||||
return false
|
||||
if let inboundLiquidityMsats = nodeInfo?.inboundLiquidityMsats {
|
||||
return inboundLiquidityMsats <= amountMsats
|
||||
}
|
||||
} catch {
|
||||
// Handle error
|
||||
}
|
||||
return false
|
||||
}
|
||||
```
|
||||
|
||||
LSP fees are calculated in two ways, either by a minimum fee set by the LSP or by a fee per myriad calculated based on the amount being received. If the fee calculated from the fee per myriad is less than the minimum fee, the minimum fee is used.
|
||||
@@ -384,12 +383,12 @@ func calculateFeesForAmount(amountMsats: Int64) -> Int64? {
|
||||
|
||||
// We calculate the dynamic fees in millisatoshis rounded to satoshis.
|
||||
let channelDynamicFeeMsat = amountMsats * lspInfo!.channelFeePermyriad / 10_000 / 1000 * 1000
|
||||
let feeSat = max(lspInfo!.channelMinimumFeeMsat,channelDynamicFeeMsat)
|
||||
let feeMsat = max(lspInfo!.channelMinimumFeeMsat, channelDynamicFeeMsat)
|
||||
|
||||
return feeSat
|
||||
return feeMsat
|
||||
}
|
||||
} catch {
|
||||
// Handle error
|
||||
// Handle error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -397,6 +396,60 @@ func calculateFeesForAmount(amountMsats: Int64) -> Int64? {
|
||||
|
||||
</section>
|
||||
|
||||
<div slot="title">React Native</div>
|
||||
<section>
|
||||
|
||||
When the amount to be received exceeds the inbound liquidity of the node, a new channel will be opened by the LSP in order for the node to receive it. This can checked by retrieving the NodeState from the SDK and comparing the inbound liquidity to the amount to be received. If the amount is greater or equal to the inbound liquidity, a new channel opening is required.
|
||||
|
||||
To calculate the fees for a channel being opened by the LSP:
|
||||
|
||||
```typescript
|
||||
const calculateChannelOpeningFee = async (amountMsats: number): number => {
|
||||
const channelOpeningFeeNeeded = await isChannelOpeningFeeNeeded(amountMsats)
|
||||
if (channelOpeningFeeNeeded) {
|
||||
return calculateFeesForAmount(amountMsats)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
```
|
||||
|
||||
How to detect if open channel fees are needed:
|
||||
```typescript
|
||||
const isChannelOpeningFeeNeeded = async (amountMsats: number): boolean => {
|
||||
try {
|
||||
const nodeInfo = await nodeInfo()
|
||||
return nodeInfo.inboundLiquidityMsats <= amountMsats
|
||||
} catch (error) {
|
||||
// handle error
|
||||
}
|
||||
return false
|
||||
}
|
||||
```
|
||||
|
||||
LSP fees are calculated in two ways, either by a minimum fee set by the LSP or by a fee per myriad calculated based on the amount being received. If the fee calculated from the fee per myriad is less than the minimum fee, the minimum fee is used.
|
||||
|
||||
This information can be retrieved for each LSP and then calculated:
|
||||
|
||||
```typescript
|
||||
const calculateFeesForAmount = async (amountMsats: number): number => {
|
||||
try {
|
||||
const id = await lspId()
|
||||
const lspInfo = await fetchLspInfo(id)
|
||||
|
||||
// We calculate the dynamic fees in millisatoshis rounded to satoshis.
|
||||
const channelDynamicFeeMsat = amountMsats * lspInfo.channelFeePermyriad / 10000 / 1000 * 1000
|
||||
const feeMsat = Math.max(lspInfo.channelMinimumFeeMsat, channelDynamicFeeMsat)
|
||||
|
||||
return feeMsat
|
||||
} catch (error) {
|
||||
// handle error
|
||||
}
|
||||
return 0
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
<div slot="title">Dart</div>
|
||||
<section>
|
||||
|
||||
@@ -417,7 +470,7 @@ How to detect if open channel fees are needed:
|
||||
// Assumes nodeState isn't empty
|
||||
bool isChannelOpeningFeeNeeded(int amountMsat) async {
|
||||
NodeState? nodeState = await getNodeState();
|
||||
return amountMsat >= nodeState.inboundLiquidityMsats;
|
||||
return amountMsat >= nodeState.inboundLiquidityMsats;
|
||||
}
|
||||
```
|
||||
|
||||
@@ -476,9 +529,9 @@ def calculate_fees_for_amount(amount_msats):
|
||||
# We calculate the dynamic fees in millisatoshis rounded to satoshis.
|
||||
channel_dynamic_fee = amount_msats * lsp_info.channel_minimum_fee_msat * lsp_info.channel_fee_permyriad / 10000 // 10000 * 10000
|
||||
|
||||
fee_sat = max(lsp_info.channel_minimum_fee_msat, channel_dynamic_fee)
|
||||
fee_msat = max(lsp_info.channel_minimum_fee_msat, channel_dynamic_fee)
|
||||
|
||||
return fee_sat
|
||||
return fee_msat
|
||||
```
|
||||
</section>
|
||||
|
||||
@@ -493,7 +546,7 @@ To calculate the fees for a channel being opened by the LSP:
|
||||
func CalculateChannelOpeningFee(amountMsats uint64) (uint64, error) {
|
||||
isChannelOpeningFeeNeeded := isChannelOpeningFeeNeeded(amountMsats)
|
||||
if !isChannelOpeningFeeNeeded {
|
||||
return 0, fmt.Errorf("Channel not needed")
|
||||
return 0, fmt.Errorf("Channel not needed")
|
||||
}
|
||||
return calculateFeesForAmount(amountMsats), nil
|
||||
}
|
||||
@@ -504,7 +557,7 @@ How to detect if open channel fees are needed:
|
||||
func isChannelOpeningFeeNeeded(amountMsats uint64) bool {
|
||||
nodeInfo, err := sdkServices.NodeInfo()
|
||||
if err != nil {
|
||||
// Handle error
|
||||
// Handle error
|
||||
}
|
||||
return nodeInfo.InboundLiquidityMsats <= amountMsats
|
||||
}
|
||||
@@ -516,24 +569,25 @@ This information can be retrieved for each LSP and then calculated:
|
||||
|
||||
```go
|
||||
func calculateFeesForAmount(amountMsats uint64) uint64 {
|
||||
lspId, err := sdkServices.LspId()
|
||||
if err != nil {
|
||||
log.Printf("received error %#v", err)
|
||||
}
|
||||
lspInfo, err := sdkServices.FetchLspInfo(*lspId)
|
||||
if err != nil {
|
||||
log.Printf("received error %#v", err)
|
||||
}
|
||||
// We calculate the dynamic fees in millisatoshis rounded to satoshis
|
||||
channelDynamicFeeMSat := amountMsats * uint64(lspInfo.ChannelFeePermyriad) / 10000 / 1000 * 1000
|
||||
lspId, err := sdkServices.LspId()
|
||||
if err != nil {
|
||||
// Handle error
|
||||
}
|
||||
|
||||
var feeSat uint64
|
||||
if channelDynamicFeeMSat >= uint64(lspInfo.ChannelMinimumFeeMsat) {
|
||||
feeSat = channelDynamicFeeMSat
|
||||
} else {
|
||||
feeSat = uint64(lspInfo.ChannelMinimumFeeMsat)
|
||||
}
|
||||
return uint64(feeSat)
|
||||
lspInfo, err := sdkServices.FetchLspInfo(*lspId)
|
||||
if err != nil {
|
||||
// Handle error
|
||||
}
|
||||
|
||||
// We calculate the dynamic fees in millisatoshis rounded to satoshis
|
||||
channelDynamicFeeMsats := amountMsats * uint64(lspInfo.ChannelFeePermyriad) / 10000 / 1000 * 1000
|
||||
feeMsats := uint64(lspInfo.ChannelMinimumFeeMsat)
|
||||
|
||||
if channelDynamicFeeMsats >= feeMsats {
|
||||
feeMsats = channelDynamicFeeMsats
|
||||
}
|
||||
|
||||
return feeMsats
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user