Documentation Index Fetch the complete documentation index at: https://docs.blend.money/llms.txt
Use this file to discover all available pages before exploring further.
Authentication, account management, balance queries, error handling, and TypeScript type definitions.
Authentication
SIWE flow (frontend)
The frontend SDK uses Sign-In with Ethereum. The user’s wallet signs a challenge message. Blend returns a JWT that binds the wallet to a Blend account.
The JWT contains the wallet address, account ID, and account type. Every SDK call after sign-in includes it automatically. You never pass an account ID.
API key auth (server)
The server SDK authenticates with an API key (sk_live_) in the X-API-Key header. No challenge/verify step. The API key replaces both the publishable key and the SIWE session.
import { BlendServerSdk } from "@blend-money/node" ;
const sdk = new BlendServerSdk ({
apiKey: process.env. BLEND_API_KEY ! ,
accountTypeId: "savings-usd" ,
});
You pass accountId explicitly to every account-scoped call via sdk.forAccount(accountId).
Rate limits
Endpoint Limit Scoped by SIWE challenge (POST /auth/challenge) 10 / 60 seconds IP address SIWE verify (POST /auth/verify) 5 / 60 seconds IP address Account-scoped routes (frontend) 100 / 60 seconds Wallet address Account-scoped routes (server) 100 / 60 seconds API key
Exceeding limits returns a 429 with error code RATE_LIMITED or RATE_LIMIT.
Session security
Keep JWTs in memory. Use sessionStorage for persistence across reloads. Avoid localStorage.
Clear the session when the wallet disconnects or address changes.
Never share an exported session across users or account types.
Auth error codes
Code Status What to do AUTH_NOT_SIGNED_IN401 Call sdk.signIn(). AUTH_CHALLENGE_FAILED500 Check publishable key and network. Retry. AUTH_VERIFICATION_FAILED401 User may have cancelled signing or wallet address mismatch. AUTH_TOKEN_EXPIRED401 JWT expired. The SDK auto-refreshes, but call signIn() if it persists. AUTH_INVALID_SESSION400 Malformed data in restoreSession(). Clear and sign in again.
Accounts
Resolution
How Blend maps wallet addresses to accounts differs by SDK.
Frontend (automatic): The publishable key identifies your organization and account type. SIWE proves wallet ownership. After sign-in, the account is implicit.
Server (manual): The API key identifies your organization. The accountTypeId in the SDK config selects the product. You call sdk.lookupAccount(address) to find or create the account. You call sdk.forAccount(accountId) to scope operations.
Safe submodule
Check and trigger Safe deployments on specific chains.
// Check if Safe is deployed on a chain
const result = await sdk.account.safe. resolve ( 8453 );
resolve returns a discriminated union:
Status Meaning "validated"Safe exists on this chain. Returns accountId, userAddress, safeAddress, chainId. "not-deployed"Safe hasn’t been deployed on this chain yet. "invalid"Contract at the address is not a valid Safe. "disconnected"Could not reach the chain RPC.
// Request deployment on a new chain
await sdk.account.safe. request ( 8453 );
request is fire-and-forget. Deployment happens in the background.
Balance & positions
balance
Current aggregate balance with per-chain breakdown.
const balance = await sdk.account. balance ();
Field Type Description accountIdstringBlend account ID safeAddressstringOn-chain Safe address perChainBalancePerChain[]Per-chain vault breakdown with fiat values totalFiatAmountAggregate balance across all chains heldAssetsHeldAsset[]Assets currently held in the Safe
balanceHistory
Time-series balance snapshots. Use startDate and endDate to filter.
const history = await sdk.account. balanceHistory ({
startDate: "2025-01-01" ,
endDate: "2025-03-01" ,
});
positions
All position events (deposits, withdrawals, rebalances) sorted newest first.
const positions = await sdk.account. positions ();
Returns deposit, withdrawal, and rebalance events with transaction hashes, amounts, and timestamps.
returns
Profit and loss metrics for the account.
const returns = await sdk.account. returns ();
Field Type Description currentFiatAmountCurrent balance value totalDepositedFiatAmountSum of all deposits totalWithdrawnFiatAmountSum of all withdrawals netDepositedFiatAmounttotalDeposited - totalWithdrawnreturnsFiatAmountcurrent - netDepositedreturnsPctnumberreturns / netDeposited * 100
Yield
Account-type-level yield data. Not per-account.
const yieldData = await sdk.discover. yield ();
Field Type Description accountTypeIdstringThe account type yieldBreakdownChainYieldBreakdown[]Per-chain APY breakdown with base and boosted rates
Error handling
SdkError
All SDK methods throw SdkError on failure.
import { SdkError } from "@blend-money/core" ;
try {
await sdk. quoteDeposit ({ /* ... */ });
} catch (error) {
if (error instanceof SdkError ) {
error.status; // HTTP status code (0 for network)
error.code; // machine-readable code string
error.message; // human-readable description
error.response; // raw API response body
error. isRetryable (); // true for 429, 5xx, network errors
error. getUserMessage (); // user-friendly message
}
}
Error codes
Session errors:
Code Status Meaning FLOWPLAN_CONFLICT409 Rebalance in progress. Retry after it settles. INTENT_NOT_FOUND404 Session UUID not found. INTENT_EXPIRED410 Quote has expired. Re-quote. INTENT_WRONG_STATUS409 Session cannot be modified in current state. INTENT_CONCURRENT_TRANSITION409 Session status changed concurrently. Retry. SESSION_NOT_QUOTED409 Must quote before locking or executing. SESSION_LOCKED_BY_OTHER409 Locked by a different signer address. SETTLEMENT_TIMEOUT408 Polling exceeded timeout (default 5 min).
Auth errors:
Code Status Meaning AUTH_NOT_SIGNED_IN401 Not authenticated. Call signIn(). AUTH_CHALLENGE_FAILED500 SIWE challenge request failed. Check publishable key. AUTH_VERIFICATION_FAILED401 Wallet signature verification failed. AUTH_TOKEN_EXPIRED401 JWT expired. Auto-refresh will attempt re-auth. AUTH_INVALID_SESSION400 Malformed session data in restoreSession().
General errors:
Code Status Meaning NETWORK_ERROR0 No response from server. VALIDATION_ERROR400 Client-side validation failed. RATE_LIMITED / RATE_LIMIT429 Too many requests. NOT_FOUND404 Resource not found. TIMEOUT408 Request timed out. SERVER_ERROR500 Internal server error. NOT_IMPLEMENTED501 Feature not available.
Amount utilities
Convert between human-readable amounts and smallest-unit strings.
import { parseAmount, formatAmount } from "@blend-money/core" ;
parseAmount ( "100.50" , 6 ); // "100500000" (USDC: 6 decimals)
parseAmount ( "1.5" , 18 ); // "1500000000000000000" (18 decimals)
formatAmount ( "100500000" , 6 ); // "100.5"
formatAmount ( "1500000000000000000" , 18 ); // "1.5"
parseAmount rejects fractional digits exceeding the token’s decimal count.
Key types
SessionStatus
type SessionStatus = "OPEN" | "LOCKED" | "SUBMITTED" | "SETTLED" | "FAILED" | "CANCELLED" ;
Terminal states: SETTLED, FAILED, CANCELLED.
DepositQuote
type DepositQuote = {
readonly type : "DEPOSIT" ;
readonly intentId : string ;
readonly originChainId : number ;
readonly destinationChainId : number ;
readonly input : { readonly symbol : string ; readonly amount : string ; readonly amountUsd : string };
readonly output : { readonly symbol : string ; readonly amount : string ; readonly amountUsd : string };
readonly fees : { readonly totalUsd : string };
readonly estimatedSeconds : number ;
readonly expiresAt : string ;
};
WithdrawQuote
type WithdrawQuote = {
readonly type : "WITHDRAW" ;
readonly intentId : string ;
readonly destinationChainId : number ;
readonly totalAmount : string ;
readonly totalFeesUsd : string ;
readonly estimatedSeconds : number ;
readonly sourceChainCount : number ;
readonly sourceChainIds : readonly number [];
readonly expiresAt : string ;
};
ExecuteResult
type ExecuteResult = {
status : "settled" | "failed" | "cancelled" ;
txHashes : Array <{ hash : string ; chainId : number }>;
settledAt : string | null ;
error : string | null ;
};
ActionPlan
type ActionPlan = {
deployType : "direct" | "multisend" ;
requiredApprovals : Txn [];
requiredTxns : Txn [];
chainId : number ;
};
Deposits produce a single ActionPlan with deployType: "direct". Withdrawals produce an ActionPlan[] with deployType: "multisend".
BalanceResponse
type BalanceResponse = {
accountId : string ;
safeAddress : string ;
perChain : BalancePerChain [];
total : FiatAmount ;
heldAssets : HeldAsset [];
};
Frontend SDK Frontend configuration, auth, and execution.
Server SDK Server configuration, account management, and sessions.