Skip to main content

BorrowSDK

The main class for interacting with SatsTerminal Borrow.

Constructor

new BorrowSDK(config: BorrowSDKConfig)
Creates a new SDK instance.

Parameters

ParameterTypeDescription
configBorrowSDKConfigSDK configuration

Example

import { BorrowSDK, ChainType } from '@satsterminal-sdk/borrow';

const sdk = new BorrowSDK({
  apiKey: 'your-api-key',
  wallet: {
    address: 'bc1q...',
    signMessage: async (msg) => wallet.signMessage(msg)
  }
});

Utility Exports

The SDK also exports utility functions for unit conversion and response handling:
import {
  BorrowSDK,
  ChainType,
  Units,                    // Type-safe BTC/satoshi conversions
  ResponseNormalizer,       // API response normalization
  type Satoshis,           // Branded type for satoshis
  type BTC,                // Branded type for BTC
} from '@satsterminal-sdk/borrow';

// Convert units
const btc = Units.satsToBtc(10000000);      // "0.10000000"
const sats = Units.btcToSats("0.1");        // 10000000

// Auto-detect and normalize units
const normalized = Units.normalizeToBtc(value);

// Handle various API response formats
const quotes = ResponseNormalizer.normalizeQuotes(apiResponse);
See Types Reference for full documentation.

Properties

userStatus

Current user status.
readonly userStatus: UserStatus

platformWalletAddress

The platform smart wallet address (index 0).
readonly platformWalletAddress: string | null

Methods

setup()

Optional account preload for dashboards and manual account flows. Without options, the SDK uses the active chain if one is already selected, otherwise Base as the preload chain. Pass options.chain only when you intentionally want to preload a different chain. executeBorrow() derives the chain from the selected quote and can prepare the required borrow wallet/session state automatically.
async setup(options?: { chain?: ChainType }): Promise<{
  platformWallet: { address: string; signature: string };
  userStatus: UserStatus;
  activeSession: ActiveSession;
  transactions: UserTransaction[];
}>

Returns

PropertyTypeDescription
platformWalletobjectPlatform wallet address and signature
userStatusUserStatusCurrent user status
activeSessionActiveSessionActive session details
transactionsUserTransaction[]Recent transactions

Example

const { platformWallet, userStatus, activeSession } = await sdk.setup();
console.log('Smart Account:', platformWallet.address);
Use this when you want to load account status, session details, and transaction history before the user starts a borrow. Borrow-only flows can skip it.

startNewLoan()

Advanced method to create a new isolated loan wallet/session manually. Most borrow flows should use getQuotes() and executeBorrow().
async startNewLoan(options?: { chain?: ChainType }): Promise<{
  userStatus: UserStatus;
  activeSession: ActiveSession;
}>

Example

const { userStatus, activeSession } = await sdk.startNewLoan();
// Now ready to execute borrow

getQuotes()

Get available loan quotes.
async getQuotes(params: QuoteRequest): Promise<Quote[]>

Parameters

ParameterTypeRequiredDescription
collateralAmountstringYesCollateral in BTC
loanAmountstringYesLoan amount in USD

Example

const quotes = await sdk.getQuotes({
  collateralAmount: '0.1',
  loanAmount: '5000'
});

getWebhookConfig()

Get the webhook configuration for the SDK API key.
async getWebhookConfig(): Promise<SdkWebhookConfig | null>

updateWebhookConfig()

Create or update the webhook configuration for the SDK API key.
async updateWebhookConfig(input: SdkWebhookConfigUpdateRequest): Promise<SdkWebhookConfig>

Example

await sdk.updateWebhookConfig({
  enabled: true,
  url: 'https://api.example.com/webhooks/satsterminal',
  events: [SdkWebhookEventType.BTC_DEPOSIT_CONFIRMED],
});

rotateWebhookSecret()

Rotate the HMAC signing secret used for webhook delivery. The new secret is returned once.
async rotateWebhookSecret(): Promise<SdkWebhookSecretResponse>

Example

const { secret } = await sdk.rotateWebhookSecret();

executeBorrow()

Execute a borrow with a selected quote. This method prepares the platform wallet, loan wallet, and session automatically when needed.
async executeBorrow(quote: Quote, options?: {
  destinationAddress?: string;
}): Promise<string>

Returns

string - Workflow ID If setup() was called immediately before, executeBorrow() reuses that prepared unused loan wallet. Otherwise it creates a fresh isolated loan wallet/session for the borrow.

Example

const workflowId = await sdk.executeBorrow(selectedQuote, {
  destinationAddress: '0x...'
});

await sdk.trackWorkflow(workflowId, {
  onStatusUpdate: (status) => console.log(status.label),
  onDepositReady: (info) => console.log(`Deposit ${info.amountBTC} BTC to ${info.address}`),
  onComplete: () => console.log('Borrow complete')
}, 'borrow');

repay()

Repay a loan. The SDK prepares the platform wallet address/signature automatically when needed; callers do not need to call setup() first. The loan chain is inferred from the original borrow transaction; pass options.chain only as an explicit override.
async repay(
  originalBorrowId: string,
  repayAmount: string,
  options?: {
    chain?: ChainType;
    useCollateral?: boolean;
    collateralToWithdraw?: string;
    userBtcWithdrawAddress?: string;
    trackWorkflow?: boolean;
    callbacks?: WorkflowCallbacks;
  }
): Promise<string>

Parameters

ParameterTypeRequiredDescription
originalBorrowIdstringYesLoan ID to repay
repayAmountstringYesAmount to repay
chainChainTypeNoOptional override. Inferred from the original loan when omitted.
useCollateralbooleanNoUse collateral for repayment
collateralToWithdrawstringNoBTC to withdraw
userBtcWithdrawAddressstringNoBTC destination
trackWorkflowbooleanNoTrack the workflow
callbacksWorkflowCallbacksNoTracking callbacks

Example

await sdk.repay(loanId, '1000', {
  collateralToWithdraw: '0.01',
  userBtcWithdrawAddress: 'bc1q...',
  trackWorkflow: true,
  callbacks: {
    onComplete: () => console.log('Repaid!')
  }
});

withdrawCollateral()

Withdraw collateral from a loan. The SDK prepares the platform wallet address/signature automatically when needed; callers do not need to call setup() first. The loan chain is inferred from the original borrow transaction; pass options.chain only as an explicit override.
async withdrawCollateral(
  originalBorrowId: string,
  collateralAmount: string,
  btcWithdrawAddress: string,
  options?: {
    chain?: ChainType;
    trackWorkflow?: boolean;
    callbacks?: WorkflowCallbacks;
  }
): Promise<string>

Example

await sdk.withdrawCollateral(
  loanId,
  '0.01',
  'bc1q...',
  { trackWorkflow: true, callbacks }
);

getLoanCollateralInfo()

Get collateral information for a loan.
async getLoanCollateralInfo(loanId: string): Promise<LoanCollateralInfo | null>

Returns

{
  totalCollateral: string;
  availableCollateral: string;
  maxWithdrawable: string;
  totalDebt: string;
  remainingDebt: string;
}

getLoanHistory()

Get loan transaction history.
async getLoanHistory(options?: {
  page?: number;
  limit?: number;
  status?: 'active' | 'pending' | 'all';
}): Promise<PaginatedResponse<UserTransaction>>

Example

const history = await sdk.getLoanHistory({
  page: 1,
  limit: 20,
  status: 'active'
});

getPendingLoans()

Get loans awaiting deposit.
async getPendingLoans(): Promise<UserTransaction[]>

getRepayTransactions()

Get repay transactions for a loan.
async getRepayTransactions(loanId?: string): Promise<RepayTransaction[]>

getRepayStatus()

Get status of a repay transaction.
async getRepayStatus(transactionId: string): Promise<RepayTransactionStatusResponse>

trackWorkflow()

Manually track a workflow.
async trackWorkflow(
  workflowId: string,
  callbacks: WorkflowCallbacks,
  workflowType?: 'borrow' | 'repay'
): Promise<void>

resumeLoan()

Resume tracking a loan workflow.
async resumeLoan(workflowId: string, callbacks?: WorkflowCallbacks): Promise<void>

getStatus()

Get workflow status.
async getStatus(workflowId: string): Promise<any>

sendBitcoin()

Send Bitcoin (requires wallet provider with sendBitcoin).
async sendBitcoin(toAddress: string, satoshis: number): Promise<string>

getFees()

Get bridge fee information for a given chain and collateral amount. Lightweight; use this for an early-stage estimate when you only know the destination chain and collateral.
async getFees(params: FeesRequest): Promise<FeesResponseData>

Example

const fees = await sdk.getFees({
  chain: ChainType.ARBITRUM,
  collateralAmount: '0.1'
});

getQuoteFees()

Get the full fee breakdown for a specific quote: bridge fees plus borrow-side fees (platform fee, applied disbursement bps, campaign waiver, net loan amount). Call this after getQuotes() to display the final numbers a user will see at checkout. The borrow-side fees are returned separately from the quote because they depend on the borrower’s campaign eligibility and the chosen loan asset/chain.
async getQuoteFees(params: QuoteFeesRequestData): Promise<QuoteFeesResponseData>

Parameters

ParameterTypeRequiredDescription
collateralAmountstringYesCollateral in BTC, e.g. "0.1"
loanAmountstringYesLoan amount in the loan asset’s units
fromChainChainTypeYesSource chain of the collateral being bridged
fromAssetSymbolstringYesSource asset symbol (e.g. BTC)
toChainChainTypeYesBridge destination chain
toAssetSymbolstringYesBridge destination asset (e.g. WBTC, cbBTC)
loanChainChainTypeYesChain on which the loan is issued
loanAssetSymbolstringYesLoan asset (e.g. USDC)

Example

const quotes = await sdk.getQuotes({
  collateralAmount: '0.1',
  loanAmount: '5000'
});
const best = quotes[0];

const fees = await sdk.getQuoteFees({
  collateralAmount: '0.1',
  loanAmount: '5000',
  fromChain: ChainType.BITCOIN,
  fromAssetSymbol: 'BTC',
  toChain: best.chain,
  toAssetSymbol: 'WBTC',
  loanChain: best.chain,
  loanAssetSymbol: 'USDC',
});

console.log('Bridge fee USD:', fees.bridgeFees.totalBridgeFeeUSD);
console.log('Platform fee:', fees.borrowFees.platformFee);
console.log('Net loan to user:', fees.borrowFees.netLoanAmount);
if (fees.borrowFees.feeSource === 'campaign') {
  console.log('Campaign discount applied:', fees.borrowFees.campaignSlug);
}
For best UX, fetch quotes and quote fees in parallel once the user has entered both a collateral amount and a loan amount:
const [quotes, fees] = await Promise.all([
  sdk.getQuotes({ collateralAmount, loanAmount }),
  sdk.getQuoteFees({
    collateralAmount,
    loanAmount,
    fromChain: ChainType.BITCOIN,
    fromAssetSymbol: 'BTC',
    toChain: selectedChain,
    toAssetSymbol: 'WBTC',
    loanChain: selectedChain,
    loanAssetSymbol: 'USDC',
  }),
]);

getWalletPositions()

Get token positions for the platform wallet.
async getWalletPositions(params?: {
  filterPositions?: string;
  filterTrash?: string;
}): Promise<WalletPositionsResponse>

getWalletPortfolio()

Get portfolio summary.
async getWalletPortfolio(filter?: string): Promise<WalletPortfolioResponse>

withdrawToBitcoin()

Withdraw EVM assets to Bitcoin. The SDK prepares the platform wallet address/signature automatically when needed.
async withdrawToBitcoin(params: WithdrawToBitcoinRequest): Promise<string>

Parameters

ParameterTypeDescription
chainChainTypeSource chain
amountstringAmount to withdraw
assetSymbolstringAsset symbol (USDC, USDT)
btcAddressstringDestination BTC address

getWithdrawStatus()

Get withdrawal status.
async getWithdrawStatus(transactionId: string): Promise<WithdrawStatusResponse>

withdrawToEVM()

Withdraw USDC from the platform smart account to an EVM address with sponsored gas (gasless). The SDK prepares the platform wallet address/signature automatically when needed.
async withdrawToEVM(params: WithdrawToEVMRequest): Promise<string>

Parameters

ParameterTypeRequiredDescription
chainChainTypeYesSource chain (ARBITRUM, BASE)
amountstringYesAmount to withdraw (e.g., ‘100’ for 100 USDC)
destinationAddressstringYesDestination EVM address
loanIndexnumberNoWallet index (defaults to 0 for platform wallet)

Returns

string - Transaction hash

Features

  • Gasless: Transaction fees are sponsored via ZeroDev paymaster
  • Instant: Single EVM transaction, no bridging required
  • USDC only: Currently supports USDC transfers

Example

// Withdraw USDC to your personal wallet (gasless)
const txHash = await sdk.withdrawToEVM({
  chain: ChainType.ARBITRUM,
  amount: '100',
  destinationAddress: '0x742d35Cc6634C0532925a3b844Bc9e7595f...'
});

console.log('Transaction hash:', txHash);
// Verify on block explorer: https://arbiscan.io/tx/{txHash}

clearSession()

Clear session and reset state.
clearSession(): void

Helper Function

useBorrow()

Factory function to create SDK instance.
function useBorrow(config: BorrowSDKConfig): BorrowSDK

Example

import { useBorrow } from '@satsterminal-sdk/borrow';

const sdk = useBorrow({
  apiKey: 'your-api-key',
  wallet: walletProvider
});