Wallet Balance
swapper.Utils exposes fee-aware balance helpers for both smart chain wallets and Bitcoin wallets.
These helpers are meant for swap UIs and "Max" buttons. Unlike a raw RPC balance, they estimate how much can actually be used in a swap without leaving too little for network fees. This is especially important for the exact-input flows described in Creating Quotes and Executing Swaps.
- use
getSpendableBalance()for smart chain wallet balances. - use
getBitcoinSpendableBalance()for Bitcoin on-chain wallet balances.
The returned balances use the TokenAmount object type which makes it easy to show the balance in human-readable format, get the raw token amount or estimate the USD value of the amount.
- Smart chain
- Bitcoin
Use SwapperUtils.getSpendableBalance() to get the spendable balance of a smart chain (i.e. Solana, Starknet, etc.) wallet, as is the case in the Smart Chain → BTC/Lightning flow. For native tokens such as SOL, STRK or the native token of an EVM chain, the SDK automatically deducts the estimated fee required to initiate the swap. The returned amount is therefore safe to use as a "Max" amount for exact-input swaps.
const strkBalance = await swapper.Utils.getSpendableBalance(
starknetSigner,
Tokens.STARKNET.STRK,
{
feeMultiplier: 1.1 // Optionally keep an extra 10% fee buffer
}
);
console.log("Spendable balance:", strkBalance.toString());
For non-native tokens such as WBTC, transaction fees are paid in the native token of the chain, so the token balance itself is usually fully spendable. You can use the hasEnoughForTxFees() function to check if the source wallet has enough native token balance to cover the transaction fees for initiating the swap.
// Check if a ToBTCSwap or ToBTCLNSwap can be initiated
const {enoughBalance, balance, required} = await swap.hasEnoughForTxFees();
if (!enoughBalance) {
console.log(`The source wallet has insufficient balance to execute the swap, required: ${required.toString()}, balance: ${balance.toString()}`);
}
A large non-native token balance does not guarantee that the swap can be initiated. The wallet still needs enough native gas token balance. This matters even more in the legacy Solana flows, where even the destination side requires SOL for deposits or transaction fees. See Bitcoin → Solana and Lightning → Solana.
Use SwapperUtils.getBitcoinSpendableBalance() for Bitcoin on-chain source balances. This helper estimates the maximum sendable BTC amount after miner fees and takes the destination smart chain into account.
Swap destination chain matters for spendable balance estimation because Bitcoin → Smart Chain on Starknet/EVM uses the newer UTXO-controlled vault flow, while Bitcoin → Solana uses the legacy Solana flow with a different Bitcoin transaction footprint.
const {balance, feeRate} = await swapper.Utils.getBitcoinSpendableBalance(
bitcoinWalletAddress,
"STARKNET", // Swap destination chain
{
gasDrop: true, // When swapping with the "gas drop" feature, the Bitcoin transaction gets slightly larger
minFeeRate: 2 // Optionally enforce a minimum sats/vB floor
}
);
console.log("Spendable balance for BTC → STARKNET swaps:", balance.toString());
console.log("Using bitcoin fee rate:", feeRate, "sats/vB");
The wallet argument can be either a plain Bitcoin address string or a wallet object implementing IBitcoinWallet or MinimalBitcoinWalletInterface.
If the user requests a gas drop in the Bitcoin → Smart Chain flow, be sure to pass gasDrop: true to getBitcoinSpendableBalance(), since requesting gas drop slightly increases the size of the Bicoin transaction.
Swaps Using Max Balance
Spendable balance helpers are most useful for estimating maximum amount of a swap source token that can be used for EXACT_IN-mode swaps. To create a swap spending the full balance of a wallet you can use the following:
- Smart chain
- Bitcoin
import {SwapAmountType} from "@atomiqlabs/sdk";
// Get the spendable balance of the signer
const maxSpendable = await swapper.Utils.getSpendableBalance(
starknetSigner,
Tokens.STARKNET.STRK
);
// Create an EXACT_IN swap spending the full wallet balance
const swap = await swapper.swap(
Tokens.STARKNET.STRK,
Tokens.BITCOIN.BTC,
maxSpendable.amount,
SwapAmountType.EXACT_IN,
starknetSigner.getAddress(),
btcAddress
);
import {SwapAmountType} from "@atomiqlabs/sdk";
// Get the spendable balance of the signer
const {balance, feeRate} = await swapper.Utils.getBitcoinSpendableBalance(
bitcoinWalletAddress,
"STARKNET", // Use the proper swap destination chain
{
gasDrop: true // We also want to request a gas drop so set this to true
}
);
// Create an EXACT_IN swap spending the full wallet balance
const swap = await swapper.swap(
Tokens.BITCOIN.BTC,
Tokens.STARKNET.WBTC,
balance.amount,
SwapAmountType.EXACT_IN,
undefined,
starknetSigner.getAddress(),
{
gasAmount: 1_000_000_000_000_000_000n // Also request a gas drop
}
);
In the case of non-legacy Bitcoin → Smart chain swaps (not applicable to legacy Bitcoin → Solana) the LPs require a certain minimum fee rate to be used for the bitcoin transaction, this fee rate can be higher than the fee that was initially used to estimate balance, hence you might need to re-fetch the bitcoin balance using this new minimal fee rate:
if (swap.minimumBtcFeeRate > feeRate) {
// Re-compute the maximum spendable spendable balance with the fee minimum
const {balance, feeRate} = await swapper.Utils.getBitcoinSpendableBalance(
bitcoinWalletAddress,
"STARKNET", // Use the proper swap destination chain
{
gasDrop: true, // We also want to request a gas drop so set this to true
minFeeRate: swap.minimumBtcFeeRate // Pass in the minimum fee rate from the created swap quote
}
);
... // Now get the quote using this adjusted amount
}
In your UI you can hook the getBitcoinSpendableBalance() and getSpendableBalance functions to recompute on state changes, i.e. if the source/destination chain types change or gas drop request is toggled.
API Reference
- SwapperUtils - Utility class exposed as
swapper.Utils - getSpendableBalance - Get spendable smart chain balance
- getBitcoinSpendableBalance - Get spendable Bitcoin balance for a route
- getNativeToken - Get the native token object for a chain
- IBitcoinWallet - Bitcoin wallet interface usable by the balance helper