Claiming on-chain deposits
Bitcoin sent to the wallet's on-chain address arrives as a deposit, which has to be claimed before it reaches the balance. The SDK detects a deposit as soon as it is in the mempool and claims it on its own once the cost fits the max claim fee.
How deposits are claimed
A deposit can be claimed at three speeds. Every claim is made through the Spark Service Provider, whose fee covers the on-chain cost of the claim and may include a share of the deposit amount. For the two faster ones the provider also fronts the funds, and charges more for doing so.
| Claim | Availability | When funds arrive | Cost |
|---|---|---|---|
| Instant | Provider decides per deposit | At 0 confirmations, while the deposit is still in the mempool | Instant claim fee |
| Expedited | Usually offered | At 1 or 2 confirmations | Instant claim fee |
| Standard | Always | At 3 confirmations on mainnet (1 on regtest) | Standard claim fee, the lowest |
The SDK takes the fastest claim whose fee fits the max claim fee. Whether a deposit is offered an instant or expedited claim, and at which depth, is decided by the provider for each deposit. The SDK retries the early claim as confirmations arrive, so a deposit the provider will not front in the mempool is often claimed a block or two later.
The max claim fee
The max claim fee is the most the SDK pays to claim a deposit on its own. It caps both the standard claim fee and the instant claim fee, so it also decides whether deposits are claimed early at all.
Its on-chain part is set as an absolute amount in sats, a rate in sats/vbyte, or the fastest recommended fee plus a leeway. On top of it, proportional_ppmproportional_ppmproportionalPpmproportionalPpmproportionalPpmproportionalPpmproportionalPpmProportionalPpmProportionalPpm can allow a share of the deposit amount, because the provider's fees grow with the deposit. Without it, a large deposit can exceed the max claim fee even when on-chain fees are low. The share counts toward every claim, so it also raises what an instant or expedited claim may cost.
The default, 1 sat/vbyte plus 0.1% of the deposit amount, is sized for the standard claim, so deposits are usually credited at 3 confirmations. Raise it to have deposits credited early. To make automatic claims more likely, follow the fastest recommended fee:
// Create the default config
let mut config = default_config(Network::Mainnet);
config.api_key = Some("<breez api key>".to_string());
// Set the maximum fee to the fastest network recommended fee at the time of claim
// with a leeway of 1 sats/vbyte, plus 0.1% of the deposit amount
config.max_deposit_claim_fee = Some(MaxFee {
onchain: MaxOnchainFee::NetworkRecommended {
leeway_sat_per_vbyte: 1,
},
proportional_ppm: Some(1_000),
});
// Create the default config
var config = defaultConfig(network: Network.mainnet)
config.apiKey = "<breez api key>"
// Set the maximum fee to the fastest network recommended fee at the time of claim
// with a leeway of 1 sats/vbyte, plus 0.1% of the deposit amount
config.maxDepositClaimFee = MaxFee(
onchain: MaxOnchainFee.networkRecommended(leewaySatPerVbyte: 1),
proportionalPpm: 1000
)
// Create the default config
val config = defaultConfig(Network.MAINNET)
config.apiKey = "<breez api key>"
// Set the maximum fee to the fastest network recommended fee at the time of claim
// with a leeway of 1 sats/vbyte, plus 0.1% of the deposit amount
config.maxDepositClaimFee = MaxFee(
onchain = MaxOnchainFee.NetworkRecommended(leewaySatPerVbyte = 1u),
proportionalPpm = 1000u
)
// Create the default config
var config = BreezSdkSparkMethods.DefaultConfig(Network.Mainnet) with
{
apiKey = "<breez api key>"
};
// Set the maximum fee to the fastest network recommended fee at the time of claim
// with a leeway of 1 sats/vbyte, plus 0.1% of the deposit amount
config = config with
{
maxDepositClaimFee = new MaxFee(
onchain: new MaxOnchainFee.NetworkRecommended(leewaySatPerVbyte: 1),
proportionalPpm: 1000
)
};
// Create the default config
const config = defaultConfig('mainnet')
config.apiKey = '<breez api key>'
// Set the maximum fee to the fastest network recommended fee at the time of claim
// with a leeway of 1 sats/vbyte, plus 0.1% of the deposit amount
config.maxDepositClaimFee = {
onchain: { type: 'networkRecommended', leewaySatPerVbyte: 1 },
proportionalPpm: 1000
}
// Create the default config
const config = defaultConfig(Network.Mainnet)
config.apiKey = '<breez api key>'
// Set the maximum fee to the fastest network recommended fee at the time of claim
// with a leeway of 1 sats/vbyte, plus 0.1% of the deposit amount
config.maxDepositClaimFee = MaxFee.create({
onchain: new MaxOnchainFee.NetworkRecommended({ leewaySatPerVbyte: BigInt(1) }),
proportionalPpm: 1000
})
// Create the default config
var config = defaultConfig(network: Network.mainnet);
config = config.copyWith(apiKey: "<breez api key>");
// Set the maximum fee to the fastest network recommended fee at the time of claim
// with a leeway of 1 sats/vbyte, plus 0.1% of the deposit amount
config = config.copyWith(
maxDepositClaimFee: MaxFee(
onchain:
MaxOnchainFee.networkRecommended(leewaySatPerVbyte: BigInt.from(1)),
proportionalPpm: 1000));
# Create the default config
config = default_config(network=Network.MAINNET)
config.api_key = "<breez api key>"
# Set the maximum fee to the fastest network recommended fee at the time of claim
# with a leeway of 1 sats/vbyte, plus 0.1% of the deposit amount
config.max_deposit_claim_fee = MaxFee(
onchain=MaxOnchainFee.NETWORK_RECOMMENDED(leeway_sat_per_vbyte=1),
proportional_ppm=1000,
)
// Create the default config
config := breez_sdk_spark.DefaultConfig(breez_sdk_spark.NetworkMainnet)
apiKey := "<breez api key>"
config.ApiKey = &apiKey
// Set the maximum fee to the fastest network recommended fee at the time of claim
// with a leeway of 1 sats/vbyte, plus 0.1% of the deposit amount
proportionalPpm := uint32(1000)
networkRecommended := breez_sdk_spark.MaxFee{
Onchain: breez_sdk_spark.MaxOnchainFeeNetworkRecommended{LeewaySatPerVbyte: 1},
ProportionalPpm: &proportionalPpm,
}
config.MaxDepositClaimFee = &networkRecommended
What your app needs to handle
When the SDK cannot claim a deposit, usually because the claim costs more than the max claim fee, it emits SdkEvent::UnclaimedDepositsSdkEvent.UNCLAIMED_DEPOSITSSdkEvent.unclaimedDepositsSdkEvent.UnclaimedDepositsSdkEvent.UnclaimedDepositsSdkEvent.UnclaimedDepositsSdkEvent.UnclaimedDepositsSdkEventUnclaimedDepositsSdkEvent.UnclaimedDeposits. The deposit then waits for your app to claim it manually, typically once the user accepts the fee, or to refund it to an external address.
- Tracking deposits: list deposits, see them before they confirm, and tell their states apart.
- Claiming deposits manually: price a claim, claim it with a higher max fee, and handle the outcome.
- Refunding deposits: send a deposit back to a Bitcoin address and follow the refund.