BorrowSDK
The main class for interacting with SatsTerminal Borrow.
Constructor
new BorrowSDK(config: BorrowSDKConfig)
Creates a new SDK instance.
Parameters
| Parameter | Type | Description |
|---|
config | BorrowSDKConfig | SDK 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
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
| Property | Type | Description |
|---|
platformWallet | object | Platform wallet address and signature |
userStatus | UserStatus | Current user status |
activeSession | ActiveSession | Active session details |
transactions | UserTransaction[] | 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
| Parameter | Type | Required | Description |
|---|
collateralAmount | string | Yes | Collateral in BTC |
loanAmount | string | Yes | Loan 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
| Parameter | Type | Required | Description |
|---|
originalBorrowId | string | Yes | Loan ID to repay |
repayAmount | string | Yes | Amount to repay |
chain | ChainType | No | Optional override. Inferred from the original loan when omitted. |
useCollateral | boolean | No | Use collateral for repayment |
collateralToWithdraw | string | No | BTC to withdraw |
userBtcWithdrawAddress | string | No | BTC destination |
trackWorkflow | boolean | No | Track the workflow |
callbacks | WorkflowCallbacks | No | Tracking 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 }
);
borrowMore()
Increase the debt on an existing loan without adding collateral. The original loan’s collateral, market context, bridge and destination are reused server-side, so only the additional borrow amount is required. The borrowed funds are disbursed to the loan’s configured destination. The SDK prepares the wallet session automatically; the loan chain is inferred from the original loan (pass options.chain only to override).
async borrowMore(
originalBorrowId: string,
borrowAmount: string,
options?: {
chain?: ChainType;
disbursementFeeBps?: number;
trackWorkflow?: boolean;
callbacks?: WorkflowCallbacks;
}
): Promise<BorrowMoreResult>
Parameters
| Parameter | Type | Required | Description |
|---|
originalBorrowId | string | Yes | ID of the original borrow transaction |
borrowAmount | string | Yes | Additional amount to borrow, in the loan asset |
disbursementFeeBps | number | No | Payout fee override in basis points (0–10000) |
trackWorkflow | boolean | No | Track the workflow via callbacks |
callbacks | WorkflowCallbacks | No | Workflow tracking callbacks |
Returns
BorrowMoreResult — includes transactionId, workflowId, status, borrowAmount, borrowerPayoutAmount, borrowAsset, and destination details.
Borrow More is rejected when the loan is fully repaid, liquidated, or has no remaining borrow room. The requested amount must not exceed the position’s available borrow capacity.
Example
const result = await sdk.borrowMore(loanId, '500', {
trackWorkflow: true,
callbacks: {
onStatusUpdate: (status) => console.log(status.label),
onComplete: () => console.log('Additional funds disbursed!')
}
});
console.log(result.transactionId);
depositMore()
Add collateral to an existing loan without borrowing. The new collateral is bridged from Bitcoin and deposited into the same position, improving the loan’s health factor. No new debt is taken. The SDK prepares the wallet session automatically; the loan chain is inferred from the original loan.
async depositMore(
originalBorrowId: string,
collateralAmount: string,
options?: {
chain?: ChainType;
trackWorkflow?: boolean;
callbacks?: WorkflowCallbacks;
}
): Promise<DepositMoreResult>
Parameters
| Parameter | Type | Required | Description |
|---|
originalBorrowId | string | Yes | ID of the original borrow transaction |
collateralAmount | string | Yes | Additional collateral to deposit, in BTC |
trackWorkflow | boolean | No | Track the workflow via callbacks |
callbacks | WorkflowCallbacks | No | Workflow tracking callbacks (includes onDepositReady for the BTC deposit) |
Returns
DepositMoreResult — includes transactionId, workflowId, status, depositAmount, collateralAsset, and protocol.
Example
const result = await sdk.depositMore(loanId, '0.01', {
trackWorkflow: true,
callbacks: {
onDepositReady: (info) => console.log(`Send ${info.amountBTC} BTC to ${info.address}`),
onComplete: () => console.log('Collateral added!')
}
});
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
| Parameter | Type | Required | Description |
|---|
collateralAmount | string | Yes | Collateral in BTC, e.g. "0.1" |
loanAmount | string | Yes | Loan amount in the loan asset’s units |
fromChain | ChainType | Yes | Source chain of the collateral being bridged |
fromAssetSymbol | string | Yes | Source asset symbol (e.g. BTC) |
toChain | ChainType | Yes | Bridge destination chain |
toAssetSymbol | string | Yes | Bridge destination asset (e.g. WBTC, cbBTC) |
loanChain | ChainType | Yes | Chain on which the loan is issued |
loanAssetSymbol | string | Yes | Loan 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
| Parameter | Type | Description |
|---|
chain | ChainType | Source chain |
amount | string | Amount to withdraw |
assetSymbol | string | Asset symbol (USDC, USDT) |
btcAddress | string | Destination 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
| Parameter | Type | Required | Description |
|---|
chain | ChainType | Yes | Source chain (ARBITRUM, BASE) |
amount | string | Yes | Amount to withdraw (e.g., ‘100’ for 100 USDC) |
destinationAddress | string | Yes | Destination EVM address |
loanIndex | number | No | Wallet 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.
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
});