Use this file to discover all available pages before exploring further.
Install the SDK, make your first deposit, and verify the balance. Under 30 minutes from zero to working code.
Before you start, you need a portal account with at least one active account type and credentials set up (SIWE domain for frontend, API key for server).
Frontend
Server
1
Install the SDK
pnpm add @blend-money/fe viem
The frontend SDK depends on viem for wallet interactions and chain management.
2
Initialize the SDK
blend.ts
import { BlendSdk } from "@blend-money/fe";import { getPimlicoPaymasterUrl } from "@blend-money/core";const sdk = new BlendSdk({ publishableKey: "pk_live_a1b2c3d4e5f6...", signMessage: (message) => wallet.signMessage({ message }), paymasterUrl: getPimlicoPaymasterUrl("your-pimlico-key"),});
The signMessage function connects your wallet adapter. If you use wagmi, pass signMessageAsync from the useSignMessage hook.
This starts a SIWE flow. The user’s wallet signs a challenge message, and Blend returns a session with their account ID and Safe address. Sessions last 1 hour and auto-refresh.
The quote shows input/output amounts, fees, and estimated time. It expires after a few minutes. If you need to change the amount, call quoteDeposit again - the SDK reuses the same session.
Use parseAmount from @blend-money/core to convert human-readable amounts to the smallest unit. USDC has 6 decimals, so parseAmount("100", 6) returns "100000000".
6
Execute the deposit
execute.ts
import { BlendSdk } from "@blend-money/fe";import { createWalletClient, createPublicClient, http } from "viem";import { base } from "viem/chains";const result = await sdk.execute(quote, { signerAddress: "0x1234...abcd", deriveSigner: async (chainId) => ({ signer: createWalletClient({ chain: base, transport: http() }), publicClient: createPublicClient({ chain: base, transport: http() }), }),});
The SDK locks the session, builds the transaction, and submits it. deriveSigner is called once for deposits. It returns a viem WalletClient and PublicClient for the target chain. For smart wallets (like Coinbase Wallet), set isContractSigner: true.
The balance reflects the deposit after settlement. This usually takes under a minute for same-chain deposits.
8
Handle errors
errors.ts
import { SdkError } from "@blend-money/core";try { const quote = await sdk.quoteDeposit({ /* ... */ });} catch (error) { if (error instanceof SdkError) { console.error(error.code); // "FLOWPLAN_CONFLICT" console.error(error.getUserMessage()); // user-friendly text if (error.isRetryable()) { /* retry with backoff */ } }}
SdkError gives you a machine-readable code, a getUserMessage() for displaying to users, and isRetryable() for handling transient failures like rate limits and server errors.
1
Install the SDK
pnpm add @blend-money/node
The server SDK has no browser dependencies. It works in Node.js, Deno, and edge runtimes.
2
Initialize the SDK
blend-server.ts
import { BlendServerSdk } from "@blend-money/node";const sdk = new BlendServerSdk({ apiKey: process.env.BLEND_API_KEY, accountTypeId: "savings-usdc",});
The accountTypeId is the slug you chose when creating your account type in the portal.
Pass the user’s EOA address. Blend returns their account ID and Safe address. If the account doesn’t exist yet, use sdk.createAccount(address, chainId) to create one.
4
Scope to the account
scope.ts
import { BlendServerSdk } from "@blend-money/node";const client = sdk.forAccount(account.accountId);
All session and balance operations go through this scoped client. It has client.discover, client.account, and client.sessions.
The server SDK uses inputAssetAddress (not tokenAddress). The session stays open until you lock it, cancel it, or it expires (~15 minutes).
6
Execute on-chain
execute-server.ts
import { depositQuoteToActionPlan } from "@blend-money/core";const actionPlan = depositQuoteToActionPlan( quoted.payload, "0x1234...abcd");// Execute requiredApprovals, then requiredTxns// using your backend signer (e.g. viem, ethers)const txHashes = await yourSigner.executeActionPlan(actionPlan);
The server SDK can’t execute transactions directly. Extract the actionPlan from the quoted session, then use your own signer to submit the approvals and transactions on-chain.
Don’t create a new session for every quote. Call quoteDeposit again on the same session to update the amount or token. Use forceReset: true only when starting a completely new flow.Don’t skip error handling. Quotes expire, flow plans can conflict with deposits, and wallets can reject signatures. Check error.isRetryable() before retrying.Don’t hard-code chain IDs or token addresses. Use discover.depositChains() and discover.depositTokens() to build your UI dynamically.
Confirm the domain in Settings > Credentials matches your production URL. Not your staging URL. Not localhost.
2
Rotate credentials
Create fresh API keys for production. Don’t reuse development keys. Deactivate any test keys.
3
Test end-to-end
Make a real deposit and withdrawal on each supported chain. Verify balances update correctly. Test with amounts under $1 to keep costs low.
4
Confirm allocations
Check that your account type’s vault config is Active (not Pending or Provisioning). Deposits to an account type without active infrastructure will fail.
5
Set flow plan mode
Decide whether to auto-approve flow plans or review them manually. Auto-approve is simpler but gives you less control over rebalancing timing.
6
Verify error handling
Test your app’s behavior for expired quotes, rejected wallet signatures, and FLOWPLAN_CONFLICT errors. Users should see helpful messages, not stack traces.
Once you’ve completed the checklist, your integration is production-ready. Deposits, withdrawals, and rebalancing will work end-to-end.
Frontend SDK reference
Full method reference for quoting, execution, and account data.
Server SDK reference
Full method reference for account management and session lifecycle.
Deposits and withdrawals
Cross-chain routing, re-quoting, and withdrawal coordination.
Best practices
Credential security, session management, and error recovery patterns.