Skip to main content

Overview

The BOB Gateway SDK makes it easy to bring Bitcoin onramp functionality directly into your app. This guide walks through the complete integration process. We recommend using the API directly, but you may use our SDK for convenience.

Installation

npm install @gobob/bob-sdk viem

Initialize the SDK

Import the GatewayApiClient (exported as GatewaySDK) and create an instance:
import { GatewaySDK } from '@gobob/bob-sdk';
import { bob, bobSepolia } from 'viem/chains';

// Mainnet
const gatewaySDK = new GatewaySDK(bob.id);

// Testnet
const gatewaySDKTestnet = new GatewaySDK(bobSepolia.id);

Get Available Routes

Fetch all supported routes to show users their options:
const routes = await gatewaySDK.getRoutes();

// Routes include information about:
// - Source and destination chains
// - Supported tokens
// - Available bridges
// - Fee structures

Get a Quote

Request a quote for the user’s desired transaction:
import { parseBtc } from '@gobob/bob-sdk';
import { parseEther } from 'viem';

const quote = await gatewaySDK.getQuote({
  fromChain: 'bitcoin',
  fromToken: 'BTC',
  fromUserAddress: 'bc1qafk4yhqvj4wep57m62dgrmutldusqde8adh20d',
  toChain: 'bob',
  toToken: 'wBTC',
  toUserAddress: '0x2D2E86236a5bC1c8a5e5499C517E17Fb88Dbc18c',
  amount: parseBtc("0.1"), // 0.1 BTC
  gasRefill: parseEther("0.00001"), // Optional ETH gas refill
});
Display quote.fee, quote.estimatedTime, and other quote fields to give users transparency about the transaction.

Execute the Quote

Execute the quote by having the user sign the Bitcoin transaction:
import { createPublicClient, createWalletClient, http, zeroAddress } from 'viem';
import { useAppKitProvider, useAppKitAccount } from '@reown/appkit/react';
import type { BitcoinConnector } from "@reown/appkit-adapter-bitcoin";
import { ReownWalletAdapter } from '@gobob/bob-sdk';
import { bob } from 'viem/chains';

// Setup viem clients
const publicClient = createPublicClient({
  chain: bob,
  transport: http(),
});

const walletClient = createWalletClient({
  chain: bob,
  transport: http(),
  account: zeroAddress, // Replace with connected account
});

// Get Bitcoin wallet provider
const { walletProvider } = useAppKitProvider<BitcoinConnector>('bip122');
const { address: btcAddress } = useAppKitAccount();

// Execute the quote
const txId = await gatewaySDK.executeQuote({
  quote,
  walletClient,
  publicClient,
  btcSigner: new ReownWalletAdapter(walletProvider, btcAddress),
});

console.log('Transaction ID:', txId);
For detailed wallet integration options including sats-wagmi, Dynamic.xyz, and more, see the Bitcoin Wallets guide.

Monitor Orders

Get the user’s pending and completed orders:
const orders = await gatewaySDK.getOrders(userEvmAddress);

// Display orders in a table or list
orders.forEach(order => {
  console.log(`Order ${order.orderId}: ${order.status}`);
  console.log(`Amount: ${order.amount}, Token: ${order.token}`);
  
  // Check for pending offramp actions
  if (order.refundTx) {
    console.log('Refund transaction available');
  }
  if (order.bumpFeeTx) {
    console.log('Fee bump transaction available');
  }
});

Offramp Features

For offramp (BOB → Bitcoin) transactions, the get-orders API now returns EVM transactions that need to be submitted when actions are required:
If Bitcoin network fees increase after order placement, the order will include a bumpFeeTx that can be submitted to speed up confirmation:
const orders = await gatewaySDK.getOrders(userEvmAddress);

// Find order with bump fee transaction
const orderNeedingBump = orders.find(order => order.bumpFeeTx);

if (orderNeedingBump) {
  // Submit the bump fee transaction
  const hash = await walletClient.sendTransaction({
    to: orderNeedingBump.bumpFeeTx.to,
    data: orderNeedingBump.bumpFeeTx.data,
    value: orderNeedingBump.bumpFeeTx.value,
  });
  
  await publicClient.waitForTransactionReceipt({ hash });
}
Only works if the original transaction hasn’t been confirmed yet.
If an order gets stuck or needs to be cancelled, the order will include a refundTx to unlock the locked assets:
const orders = await gatewaySDK.getOrders(userEvmAddress);

// Find order with refund transaction available
const orderNeedingRefund = orders.find(order => order.refundTx);

if (orderNeedingRefund) {
  // Submit the refund transaction
  const hash = await walletClient.sendTransaction({
    to: orderNeedingRefund.refundTx.to,
    data: orderNeedingRefund.refundTx.data,
    value: orderNeedingRefund.refundTx.value,
  });
  
  await publicClient.waitForTransactionReceipt({ hash });
}
This action is irreversible. Once refunded, the order cannot be resumed.

Monetization

Gateway supports affiliate fees out of the box. You earn a fee on every transaction through your integration: by providing your unique affiliate ID:
const quote = await gatewaySDK.getQuote({
  // ... other params
  affiliateId: '550e8400-e29b-41d4-a716-446655440000', // Your unique UUID
});
Your affiliate ID:
  • Must be a valid UUID (universally unique identifier)
  • Tracks all transactions through your integration
  • Automatically associates earned fees with your account
  • Contact the BOB team to register your affiliate ID and set up fee structure

Next Steps