sbtc

Build and manage sBTC deposits and withdrawals on Bitcoin and Stacks.

The sbtc package provides functions for creating sBTC deposits on Bitcoin and interacting with the sBTC protocol across Bitcoin and Stacks networks.

Installation

Terminal
$
npm install sbtc

Deposit functions

buildSbtcDepositAddress

buildSbtcDepositAddress creates a Bitcoin address for sBTC deposits with embedded metadata.

Signature

function buildSbtcDepositAddress(options: DepositAddressOptions): DepositAddress

Parameters

NameTypeRequiredDescription
stacksAddressstringYesStacks address to receive sBTC
signersPublicKeystringYesAggregated public key of signers
maxSignerFeenumberNoMaximum fee for signers (default: 80,000 sats)
reclaimLockTimenumberNoLock time for reclaim script (default: 6,000)
networkBitcoinNetworkNoBitcoin network to use (default: MAINNET)

Example

import { buildSbtcDepositAddress, SbtcApiClientMainnet } from 'sbtc';
const client = new SbtcApiClientMainnet();
// Build deposit address
const deposit = buildSbtcDepositAddress({
stacksAddress: 'SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159',
signersPublicKey: await client.fetchSignersPublicKey(),
maxSignerFee: 80_000, // Fee taken from deposit amount
reclaimLockTime: 6_000
});
// Send BTC to deposit.address using any Bitcoin wallet
const txid = await wallet.sendTransfer({
recipient: deposit.address,
amount: 1_000_000 // 0.01 BTC
});
// Notify signers about the deposit
await client.notifySbtc({ txid, ...deposit });

buildSbtcDepositTx

buildSbtcDepositTx creates a complete Bitcoin transaction for sBTC deposits.

Signature

function buildSbtcDepositTx(options: DepositTxOptions): DepositTransaction

Parameters

NameTypeRequiredDescription
amountSatsnumber | bigintYesAmount to deposit in satoshis
stacksAddressstringYesStacks address to receive sBTC
signersPublicKeystringYesAggregated public key of signers
maxSignerFeenumberNoMaximum fee for signers (default: 80,000 sats)
reclaimLockTimenumberNoLock time for reclaim script (default: 144)
networkBitcoinNetworkNoBitcoin network to use

Example

import { buildSbtcDepositTx, SbtcApiClientMainnet } from 'sbtc';
const client = new SbtcApiClientMainnet();
// Build deposit transaction
const deposit = buildSbtcDepositTx({
amountSats: 100_000,
stacksAddress: 'SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159',
signersPublicKey: await client.fetchSignersPublicKey()
});
// Sign transaction
deposit.transaction.sign(privateKey);
deposit.transaction.finalize();
// Broadcast and notify
const txid = await client.broadcastTx(deposit.transaction);
await client.notifySbtc(deposit);

sbtcDepositHelper

sbtcDepositHelper creates a fully-formed deposit transaction from UTXOs.

Signature

function sbtcDepositHelper(options: DepositHelperOptions): Promise<DepositTransaction>

Parameters

NameTypeRequiredDescription
amountSatsnumber | bigintYesAmount to deposit in satoshis
stacksAddressstringYesStacks address to receive sBTC
signersPublicKeystringYesAggregated public key of signers
feeRatenumberYesFee rate in sat/vbyte
utxosUtxoWithTx[]YesUTXOs to fund the transaction
bitcoinChangeAddressstringYesAddress for change output
reclaimPublicKeystringNoPublic key for reclaiming deposits
reclaimLockTimenumberNoLock time for reclaim (default: 144)
maxSignerFeenumberNoMaximum signer fee (default: 80,000)
networkBitcoinNetworkNoBitcoin network (default: MAINNET)

Example

import { sbtcDepositHelper, SbtcApiClientMainnet } from 'sbtc';
const client = new SbtcApiClientMainnet();
const btcAddress = 'bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4';
// Create complete deposit transaction
const deposit = await sbtcDepositHelper({
amountSats: 1_000_000,
stacksAddress: 'SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159',
signersPublicKey: await client.fetchSignersPublicKey(),
feeRate: await client.fetchFeeRate('medium'),
utxos: await client.fetchUtxos(btcAddress),
bitcoinChangeAddress: btcAddress
});
// Sign and broadcast
deposit.transaction.sign(privateKey);
deposit.transaction.finalize();
const txid = await client.broadcastTx(deposit.transaction);
await client.notifySbtc(deposit);

API clients

SbtcApiClientMainnet

SbtcApiClientMainnet provides mainnet API access for sBTC operations.

import { SbtcApiClientMainnet } from 'sbtc';
const client = new SbtcApiClientMainnet();

SbtcApiClientTestnet

SbtcApiClientTestnet provides testnet API access for sBTC operations.

import { SbtcApiClientTestnet } from 'sbtc';
const client = new SbtcApiClientTestnet();

SbtcApiClientDevenv

SbtcApiClientDevenv provides local development API access.

import { SbtcApiClientDevenv } from 'sbtc';
const client = new SbtcApiClientDevenv();

Client methods

fetchSignersPublicKey

fetchSignersPublicKey retrieves the aggregated public key of sBTC signers.

const publicKey = await client.fetchSignersPublicKey();
// '02abc123...' (32-byte hex string)

fetchSignersAddress

fetchSignersAddress retrieves the Bitcoin address of sBTC signers.

const address = await client.fetchSignersAddress();
// 'bc1p...' (p2tr address)

fetchFeeRate

fetchFeeRate retrieves current Bitcoin network fee rates.

const feeRate = await client.fetchFeeRate('medium');
// 15 (sat/vbyte)
// Also supports 'low' and 'high'
const lowFee = await client.fetchFeeRate('low');
const highFee = await client.fetchFeeRate('high');

fetchUtxos

fetchUtxos retrieves unspent transaction outputs for a Bitcoin address.

const utxos = await client.fetchUtxos('bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4');
// Array of UTXOs with transaction data

broadcastTx

broadcastTx broadcasts a Bitcoin transaction to the network.

const txid = await client.broadcastTx(transaction);
// '0x1234abcd...'

notifySbtc

notifySbtc notifies the sBTC API about a deposit transaction.

const response = await client.notifySbtc({
txid,
stacksAddress,
reclaimScript,
depositScript
});
// { status: 200, statusMessage: 'OK' }

fetchSbtcBalance

fetchSbtcBalance retrieves the sBTC balance for a Stacks address.

const balance = await client.fetchSbtcBalance('SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159');
// 1000000n (in micro-sBTC)

Configuration

Client configuration options

NameTypeDescription
sbtcContractstringsBTC contract address
sbtcApiUrlstringsBTC API (Emily) base URL
btcApiUrlstringBitcoin API base URL
stxApiUrlstringStacks API base URL

Custom client configuration

import { SbtcApiClient } from 'sbtc';
const client = new SbtcApiClient({
sbtcContract: 'SP000000000000000000002Q6VF78.sbtc',
sbtcApiUrl: 'https://api.sbtc.tech',
btcApiUrl: 'https://mempool.space/api',
stxApiUrl: 'https://api.mainnet.hiro.so'
});

Complete deposit example

import { sbtcDepositHelper, SbtcApiClientMainnet } from 'sbtc';
async function depositBtcForSbtc() {
const client = new SbtcApiClientMainnet();
const btcAddress = 'bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4';
const stxAddress = 'SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159';
// 1. Create deposit transaction
const deposit = await sbtcDepositHelper({
amountSats: 100_000,
stacksAddress: stxAddress,
signersPublicKey: await client.fetchSignersPublicKey(),
feeRate: await client.fetchFeeRate('medium'),
utxos: await client.fetchUtxos(btcAddress),
bitcoinChangeAddress: btcAddress
});
// 2. Sign transaction
deposit.transaction.sign(privateKey);
deposit.transaction.finalize();
// 3. Broadcast to Bitcoin network
const txid = await client.broadcastTx(deposit.transaction);
console.log('Bitcoin transaction:', txid);
// 4. Notify sBTC signers
await client.notifySbtc(deposit);
console.log('Deposit submitted successfully');
// 5. Check sBTC balance (after confirmation)
const balance = await client.fetchSbtcBalance(stxAddress);
console.log('sBTC balance:', balance);
}