Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Customizing the SDK

Using the SDK Builder gives you more control over the initialization and modular components used when the SDK is running. Below you can find examples of initializing the SDK using the SDK Builder and implementing modular components:

Rust
// Construct the seed using mnemonic words or entropy bytes
let mnemonic = "<mnemonic words>".to_string();
let seed = Seed::Mnemonic {
    mnemonic,
    passphrase: None,
};

// Create the default config
let mut config = default_config(Network::Mainnet);
config.api_key = Some("<breez api key>".to_string());

// Build the SDK using the config, seed and default storage
let builder = SdkBuilder::new(config, seed).with_default_storage("./.data".to_string());
// You can also pass your custom implementations:
// let builder = builder.with_storage(<your storage implementation>)
// let builder = builder.with_real_time_sync_storage(<your real-time sync storage implementation>)
// let builder = builder.with_chain_service(<your chain service implementation>)
// let builder = builder.with_rest_client(<your rest client implementation>)
// let builder = builder.with_key_set(<your key set type>, <use address index>, <account number>)
// let builder = builder.with_payment_observer(<your payment observer implementation>);
let sdk = builder.build().await?;
Swift
// Construct the seed using mnemonic words or entropy bytes
let mnemonic = "<mnemonic words>"
let seed = Seed.mnemonic(mnemonic: mnemonic, passphrase: nil)

// Create the default config
var config = defaultConfig(network: Network.mainnet)
config.apiKey = "<breez api key>"

// Build the SDK using the config, seed and default storage
let builder = SdkBuilder(config: config, seed: seed)
await builder.withDefaultStorage(storageDir: "./.data")
// You can also pass your custom implementations:
// await builder.withStorage(<your storage implementation>)
// await builder.withRealTimeSyncStorage(<your real-time sync storage implementation>)
// await builder.withChainService(<your chain service implementation>)
// await builder.withRestClient(<your rest client implementation>)
// await builder.withKeySet(<your key set type>, <use address index>, <account number>)
// await builder.withPaymentObserver(<your payment observer implementation>)
let sdk = try await builder.build()
Kotlin
// Construct the seed using mnemonic words or entropy bytes
val mnemonic = "<mnemonic words>"
val seed = Seed.Mnemonic(mnemonic, null)

// Create the default config
val config = defaultConfig(Network.MAINNET)
config.apiKey = "<breez api key>"

try {
    // Build the SDK using the config, seed and default storage
    val builder = SdkBuilder(config, seed)
    builder.withDefaultStorage("./.data")
    // You can also pass your custom implementations:
    // builder.withStorage(<your storage implementation>)
    // builder.withRealTimeSyncStorage(<your real-time sync storage implementation>)
    // builder.withChainService(<your chain service implementation>)
    // builder.withRestClient(<your rest client implementation>)
    // builder.withKeySet(<your key set type>, <use address index>, <account number>)
    // builder.withPaymentObserver(<your payment observer implementation>)
    val sdk = builder.build()
} catch (e: Exception) {
    // handle error
}
C#
// Construct the seed using mnemonic words or entropy bytes
var mnemonic = "<mnemonic words>";
var seed = new Seed.Mnemonic(mnemonic: mnemonic, passphrase: null);
// Create the default config
var config = BreezSdkSparkMethods.DefaultConfig(Network.Mainnet) with
{
    apiKey = "<breez api key>"
};
// Build the SDK using the config, seed and default storage
var builder = new SdkBuilder(config: config, seed: seed);
await builder.WithDefaultStorage(storageDir: "./.data");
// You can also pass your custom implementations:
// await builder.WithStorage(<your storage implementation>)
// await builder.WithRealTimeSyncStorage(<your real-time sync storage implementation>)
// await builder.WithChainService(<your chain service implementation>)
// await builder.WithRestClient(<your rest client implementation>)
// await builder.WithKeySet(<your key set type>, <use address index>, <account number>)
// await builder.WithPaymentObserver(<your payment observer implementation>);
var sdk = await builder.Build();
Javascript
// Call init when using the SDK in a web environment before calling any other SDK
// methods. This is not needed when using the SDK in a Node.js/Deno environment.
await init()

// Construct the seed using mnemonic words or entropy bytes
const mnemonic = '<mnemonic words>'
const seed: Seed = { type: 'mnemonic', mnemonic, passphrase: undefined }

// Create the default config
const config = defaultConfig('mainnet')
config.apiKey = '<breez api key>'

// Build the SDK using the config, seed and default storage
let builder = SdkBuilder.new(config, seed)
builder = await builder.withDefaultStorage('./.data')
// You can also pass your custom implementations:
// builder = builder.withStorage(<your storage implementation>)
// builder = builder.withRealTimeSyncStorage(<your real-time sync storage implementation>)
// builder = builder.withChainService(<your chain service implementation>)
// builder = builder.withRestClient(<your rest client implementation>)
// builder = builder.withKeySet(<your key set type>, <use address index>, <account number>)
// builder = builder.withPaymentObserver(<your payment observer implementation>)
const sdk = await builder.build()
React Native
// Construct the seed using mnemonic words or entropy bytes
const mnemonic = '<mnemonics words>'
const seed = new Seed.Mnemonic({ mnemonic, passphrase: undefined })

// Create the default config
const config = defaultConfig(Network.Mainnet)
config.apiKey = '<breez api key>'

// Build the SDK using the config, seed and default storage
const builder = new SdkBuilder(config, seed)
await builder.withDefaultStorage(`${RNFS.DocumentDirectoryPath}/data`)
// You can also pass your custom implementations:
// await builder.withStorage(<your storage implementation>)
// await builder.withRealTimeSyncStorage(<your real-time sync storage implementation>)
// await builder.withChainService(<your chain service implementation>)
// await builder.withRestClient(<your rest client implementation>)
// await builder.withKeySet(<your key set type>, <use address index>, <account number>)
// await builder.withPaymentObserver(<your payment observer implementation>)
const sdk = await builder.build()
Flutter
// Construct the seed using mnemonic words or entropy bytes
String mnemonic = "<mnemonic words>";
final seed = Seed.mnemonic(mnemonic: mnemonic, passphrase: null);

// Create the default config
final config = defaultConfig(network: Network.mainnet)
    .copyWith(apiKey: "<breez api key>");

// Build the SDK using the config, seed and default storage
final builder = SdkBuilder(config: config, seed: seed);
builder.withDefaultStorage(storageDir: "./.data");
// You can also pass your custom implementations:
// builder.withRestChainService(
//     url: "https://custom.chain.service",
//     credentials: Credentials(
//         username: "service-username", password: "service-password"));
// builder.withKeySet(keySetType: <your key set type>, useAddressIndex: <use address index>, accountNumber: <account number>);
final sdk = await builder.build();
Python
# Construct the seed using mnemonic words or entropy bytes
mnemonic = "<mnemonic words>"
seed = Seed.MNEMONIC(mnemonic=mnemonic, passphrase=None)
# Create the default config
config = default_config(network=Network.MAINNET)
config.api_key = "<breez api key>"
try:
    # Build the SDK using the config, seed and default storage
    builder = SdkBuilder(config=config, seed=seed)
    await builder.with_default_storage(storage_dir="./.data")
    # You can also pass your custom implementations:
    # await builder.with_storage(<your storage implementation>)
    # await builder.with_real_time_sync_storage(<your real-time sync storage implementation>)
    # await builder.with_chain_service(<your chain service implementation>)
    # await builder.with_rest_client(<your rest client implementation>)
    # await builder.with_key_set(<your key set type>, <use address index>, <account number>)
    # await builder.with_payment_observer(<your payment observer implementation>)
    sdk = await builder.build()
    return sdk
except Exception as error:
    logging.error(error)
    raise
Go
// Construct the seed using mnemonic words or entropy bytes
mnemonic := "<mnemonic words>"
var seed breez_sdk_spark.Seed = breez_sdk_spark.SeedMnemonic{
	Mnemonic:   mnemonic,
	Passphrase: nil,
}

// Create the default config
apiKey := "<breez api key>"
config := breez_sdk_spark.DefaultConfig(breez_sdk_spark.NetworkMainnet)
config.ApiKey = &apiKey

// Build the SDK using the config, seed and default storage
builder := breez_sdk_spark.NewSdkBuilder(config, seed)
builder.WithDefaultStorage("./.data")
// You can also pass your custom implementations:
// builder.WithStorage(<your storage implementation>)
// builder.WithRealTimeSyncStorage(<your real-time sync storage implementation>)
// builder.WithChainService(<your chain service implementation>)
// builder.WithRestClient(<your rest client implementation>)
// builder.WithKeySet(<your key set type>, <use address index>, <account number>)
// builder.WithPaymentObserver(<your payment observer implementation>)
sdk, err := builder.Build()

return sdk, err

With Storage API docs

When using the SDK Builder, you either have to provide a Storage implementation or use the default storage from the SDK.

Note: Flutter currently only supports using the default storage.

With Real-Time Sync Storage API docs

If you are providing your own Storage implementation, you also need to provide a Real-Time Sync Storage implementation when real-time sync is enabled. When using the default storage from the SDK, this is already provided.

Note: Flutter currently only supports using the default storage.

With Chain Service API docs

The SDK provides a default Bitcoin Chain Service implementation. If you want to use your own, you can provide it either by using With REST Chain Service or by implementing the Bitcoin Chain Service interface.

With REST Chain Service API docs

The SDK provides a default Bitcoin Chain Service implementation. If you want to use your own, you can provide it either by using With Chain Service or by providing a URL and optional credentials.

Rust
let url = "<your REST chain service URL>".to_string();
let chain_api_type = ChainApiType::MempoolSpace;
let optional_credentials = Credentials {
    username: "<username>".to_string(),
    password: "<password>".to_string(),
};
builder.with_rest_chain_service(
    url,
    chain_api_type,
    Some(optional_credentials),
)
Swift
let url = "<your REST chain service URL>"
let chainApiType = ChainApiType.mempoolSpace
let optionalCredentials = Credentials(
    username: "<username>",
    password: "<password>"
)
await builder.withRestChainService(
    url: url,
    apiType: chainApiType,
    credentials: optionalCredentials
)
Kotlin
val url = "<your REST chain service URL>"
val chainApiType = ChainApiType.MEMPOOL_SPACE
val optionalCredentials = Credentials(
    username = "<username>",
    password = "<password>"
)
builder.withRestChainService(
    url = url,
    apiType = chainApiType,
    credentials = optionalCredentials
)
C#
var url = "<your REST chain service URL>";
var chainApiType = ChainApiType.MempoolSpace;
var optionalCredentials = new Credentials(
    username: "<username>",
    password: "<password>"
);
await builder.WithRestChainService(
    url: url,
    apiType: chainApiType,
    credentials: optionalCredentials
);
Javascript
const url = '<your REST chain service URL>'
const chainApiType = 'mempoolSpace'
const optionalCredentials: Credentials = {
  username: '<username>',
  password: '<password>'
}
builder = builder.withRestChainService(url, chainApiType, optionalCredentials)
React Native
const url = '<your REST chain service URL>'
const chainApiType = ChainApiType.MempoolSpace
const optionalCredentials: Credentials = {
  username: '<username>',
  password: '<password>'
}
await builder.withRestChainService(url, chainApiType, optionalCredentials)
Flutter
String url = "<your REST chain service URL>";
var chainApiType = ChainApiType.mempoolSpace;
var optionalCredentials = Credentials(
  username: "<username>",
  password: "<password>",
);
builder.withRestChainService(
  url: url,
  apiType: chainApiType,
  credentials: optionalCredentials,
);
Python
url = "<your REST chain service URL>"
chain_api_type = ChainApiType.MEMPOOL_SPACE
optional_credentials = Credentials(
    username="<username>",
    password="<password>",
)
await builder.with_rest_chain_service(
    url=url,
    api_type=chain_api_type,
    credentials=optional_credentials,
)
Go
url := "<your REST chain service URL>"
chainApiType := breez_sdk_spark.ChainApiTypeMempoolSpace
optionalCredentials := &breez_sdk_spark.Credentials{
	Username: "<username>",
	Password: "<password>",
}
builder.WithRestChainService(url, chainApiType, optionalCredentials)

With Fiat Service API docs

The SDK by default provides a list of available Fiat currencies and current exchange rates. If you want to use your own, you can provide it by implementing the Fiat Service interface.

With LNURL Client API docs

The LNURL Client is used to make REST requests specifically when interacting with LNURL. If you want to use your own, you can it provide by implementing the REST Service interface.

With Key Set API docs

The SDK uses by default the Default key set with the account number 1 on Mainnet (0 on Regtest). You can change this to alter the derivation path used with the provided seed:

  • Default - Uses derivation path m/8797555'/<account number> (use address index is ignored)
  • Taproot - Uses derivation path m/86'/0'/<account number>'/0/0
    (or m/86'/0'/0'/0/<account number> when use address index is enabled)
  • Native Segwit - Uses derivation path m/84'/0'/<account number>'/0/0
    (or m/84'/0'/0'/0/<account number> when use address index is enabled)
  • Wrapped Segwit - Uses derivation path m/49'/0'/<account number>'/0/0
    (or m/49'/0'/0'/0/<account number> when use address index is enabled)
  • Legacy - Uses derivation path m/44'/0'/<account number>'/0/0
    (or m/44'/0'/0'/0/<account number> when use address index is enabled)
Rust
let key_set_type = KeySetType::Default;
let use_address_index = false;
let optional_account_number = 21;
builder.with_key_set(
    key_set_type,
    use_address_index,
    Some(optional_account_number),
)
Swift
let keySetType = KeySetType.default
let useAddressIndex = false
let optionalAccountNumber = UInt32(21)
await builder.withKeySet(
    keySetType: keySetType,
    useAddressIndex: useAddressIndex,
    accountNumber: optionalAccountNumber
)
Kotlin
val keySetType = KeySetType.DEFAULT
val useAddressIndex = false
val optionalAccountNumber = 21u
builder.withKeySet(
    keySetType = keySetType,
    useAddressIndex = useAddressIndex,
    accountNumber = optionalAccountNumber
)
C#
var keySetType = KeySetType.Default;
var useAddressIndex = false;
var optionalAccountNumber = 21u;
await builder.WithKeySet(
    keySetType: keySetType,
    useAddressIndex: useAddressIndex,
    accountNumber: optionalAccountNumber
);
Javascript
const keySetType = 'default'
const useAddressIndex = false
const optionalAccountNumber = 21
builder = builder.withKeySet(keySetType, useAddressIndex, optionalAccountNumber)
React Native
const keySetType = KeySetType.Default
const useAddressIndex = false
const optionalAccountNumber = 21
await builder.withKeySet(keySetType, useAddressIndex, optionalAccountNumber)
Flutter
var keySetType = KeySetType.default_;
var useAddressIndex = false;
var optionalAccountNumber = 21;
builder.withKeySet(
  keySetType: keySetType,
  useAddressIndex: useAddressIndex,
  accountNumber: optionalAccountNumber,
);
Python
key_set_type = KeySetType.DEFAULT
use_address_index = False
optional_account_number = 21
await builder.with_key_set(
    key_set_type=key_set_type,
    use_address_index=use_address_index,
    account_number=optional_account_number,
)
Go
keySetType := breez_sdk_spark.KeySetTypeDefault
useAccountIndex := true
optionalAccountNumber := uint32(21)
builder.WithKeySet(keySetType, useAccountIndex, &optionalAccountNumber)

With Payment Observer API docs

By implementing the Payment Observer interface you can be notified before a payment is sent. It includes information about the provisional payment including the payment ID, amount to be sent (in satoshis or token base units) and payment details based on the payment method.

Note: Flutter currently does not support this.

Rust
pub(crate) struct ExamplePaymentObserver {}

#[async_trait]
impl PaymentObserver for ExamplePaymentObserver {
    async fn before_send(
        &self,
        payments: Vec<ProvisionalPayment>,
    ) -> Result<(), PaymentObserverError> {
        for payment in payments {
            info!(
                "About to send payment: {:?} of amount {:?}",
                payment.payment_id, payment.amount
            );
        }
        Ok(())
    }
}

pub(crate) fn with_payment_observer(builder: SdkBuilder) -> SdkBuilder {
    let observer = ExamplePaymentObserver {};
    builder.with_payment_observer(Arc::new(observer))
}
Swift
class ExamplePaymentObserver: PaymentObserver {
    func beforeSend(payments: [ProvisionalPayment]) async {
        for payment in payments {
            print("About to send payment: \(payment.paymentId) of amount \(payment.amount)")
        }
    }
}

func withPaymentObserver(builder: SdkBuilder) async {
    let paymentObserver = ExamplePaymentObserver()
    await builder.withPaymentObserver(paymentObserver: paymentObserver)
}
Kotlin
class ExamplePaymentObserver : PaymentObserver {
    override suspend fun beforeSend(payments: List<ProvisionalPayment>) {
        for (payment in payments) {
            // Log.v("PaymentObserver", "About to send payment: ${payment.paymentId} of amount ${payment.amount}")
        }
    }
}

suspend fun withPaymentObserver(builder: SdkBuilder) {
    val paymentObserver = ExamplePaymentObserver()
    builder.withPaymentObserver(paymentObserver)
}
C#
class ExamplePaymentObserver : PaymentObserver
{
    public async Task BeforeSend(List<ProvisionalPayment> payments)
    {
        foreach (var payment in payments)
        {
            Console.WriteLine($"About to send payment {payment.paymentId} of amount {payment.amount}");
        }
    }
}

async Task WithPaymentObserver(SdkBuilder builder)
{
    var paymentObserver = new ExamplePaymentObserver();
    await builder.WithPaymentObserver(paymentObserver);
}
Javascript
class ExamplePaymentObserver {
  beforeSend = async (payments: ProvisionalPayment[]) => {
    for (const payment of payments) {
      console.log(`About to send payment: ${payment.paymentId} of amount ${payment.amount}`)
    }
  }
}

const exampleWithPaymentObserver = (builder: SdkBuilder): SdkBuilder => {
  const paymentObserver = new ExamplePaymentObserver()
  return builder.withPaymentObserver(paymentObserver)
}
React Native
class ExamplePaymentObserver {
  beforeSend = async (payments: ProvisionalPayment[]) => {
    for (const payment of payments) {
      console.log(`About to send payment: ${payment.paymentId} of amount ${payment.amount}`)
    }
  }
}

const exampleWithPaymentObserver = async (builder: SdkBuilder) => {
  const paymentObserver = new ExamplePaymentObserver()
  await builder.withPaymentObserver(paymentObserver)
}
Flutter

Python
class ExamplePaymentObserver(PaymentObserver):
    def before_send(self, payments: typing.List[ProvisionalPayment]):
        for payment in payments:
            logging.debug(f"About to send payment {payment.payment_id} of amount {payment.amount}")


async def with_payment_observer(builder: SdkBuilder):
    payment_observer = ExamplePaymentObserver()
    await builder.with_payment_observer(payment_observer=payment_observer)
Go
type ExamplePaymentObserver struct{}

func (ExamplePaymentObserver) BeforeSend(payments []breez_sdk_spark.ProvisionalPayment) error {
	for _, payment := range payments {
		log.Printf("About to send payment: %v of amount %v", payment.PaymentId, payment.Amount)
	}
	return nil
}

func WithPaymentObserver(builder *breez_sdk_spark.SdkBuilder) {
	observer := ExamplePaymentObserver{}
	builder.WithPaymentObserver(observer)
}