Quickstart
Install the TypeScript SDK, read yield data, and send a deposit with Solana Kit
Install
For typed API access:
npm install @solana/breeze-sdkFor the recommended trusted-backend Solana Kit transaction integration:
npm install @solana/breeze-sdk @solana/kit \
@solana/kit-plugin-rpc @solana/kit-plugin-signerThe dependency-free root import supports Node.js 18 or newer. The optional
@solana/breeze-sdk/kit entry follows Solana Kit 7's Node.js 20.18 or newer
requirement.
Configure
Create an API key, then store it in your server environment.
Keep API keys in trusted server-side configuration. Never expose them in client-side code, browser bundles, mobile applications, logs, or public repositories.
import { BreezeSDK } from '@solana/breeze-sdk';
const apiKey = process.env.BREEZE_API_KEY;
if (!apiKey) throw new Error('BREEZE_API_KEY is required');
const sdk = new BreezeSDK({ apiKey });The production API URL and a 30-second request timeout are the defaults.
Read yield data
const userYield = await sdk.getUserYield({
userId: 'USER_WALLET_ADDRESS',
});
for (const position of userYield.data) {
console.log(position.fund_name, position.yield_earned, position.apy);
}The response includes a data array and pagination meta. Response fields
preserve the API's snake_case names; position values and earned yield use the
token's smallest units, while APY is expressed in percentage points.
Send from a trusted backend with Solana Kit
Configure a Kit client with a server-managed signer and mainnet RPC before
installing the Breeze plugin. serverSigner can come from a custody provider,
key-management service, or another signer that runs in your trusted
environment. For the direct-send flow below, it must implement Kit's
TransactionPartialSigner (signTransactions) or
TransactionModifyingSigner (modifyAndSignTransactions) capability. A signer
that can only send transactions is not sufficient.
import { createClient } from '@solana/kit';
import { solanaMainnetRpc } from '@solana/kit-plugin-rpc';
import { signer } from '@solana/kit-plugin-signer';
import { breeze } from '@solana/breeze-sdk/kit';
import { getBackendSigner } from './custody-signer';
const apiKey = process.env.BREEZE_API_KEY;
const rpcUrl = process.env.SOLANA_RPC_URL;
if (!apiKey || !rpcUrl) {
throw new Error('BREEZE_API_KEY and SOLANA_RPC_URL are required');
}
const backendSigner = await getBackendSigner();
const client = createClient()
.use(signer(backendSigner))
.use(solanaMainnetRpc({ rpcUrl }))
.use(breeze({ apiKey }));
const result = await client.breeze.instructions
.deposit({
strategyId: 'YOUR_STRATEGY_ID',
baseAsset: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
amount: 1_000_000,
})
.sendTransaction();
console.log('Confirmed transaction signature:', result.context.signature);The plugin derives userKey and payerKey from the installed identity and fee
payer, fetches and validates Breeze instructions, retrieves the required address
lookup table, and converts eligible accounts to lookup-table references. The
installed planner then sizes and builds a v0 transaction before the executor
signs, submits, and confirms it. amount uses raw token units; 1_000_000 is
one USDC.
Mainnet transaction
Breeze is mainnet-only. instructions.deposit(...).sendTransaction(),
instructions.withdraw(...), and instructions.closeUserAccount(...) sign and
submit real transactions that can move funds. Validate the strategy, mint,
amount, signer addresses, and RPC configuration before calling them.
instructions.withdraw(...) uses the same lookup-table-backed version-0 flow.
instructions.closeUserAccount(...) uses the same fluent terminals but skips
lookup-table resolution and keeps the installed planner's transaction version.
Finish any builder with .planTransaction() instead of .sendTransaction() when
you need to inspect the transaction message before sending it.
When identity and fee payer use different signers, install both roles
explicitly. Each signer required by the transaction must implement
TransactionPartialSigner or TransactionModifyingSigner for direct sending:
import { identity, payer } from '@solana/kit-plugin-signer';
const client = createClient()
.use(payer(feePayerSigner))
.use(identity(identitySigner))
.use(solanaMainnetRpc({ rpcUrl }))
.use(breeze({ apiKey }));Hand off to a browser wallet
Do not install the Breeze plugin or place a Breeze API key in browser code. When the user signs with a browser wallet, keep the root SDK on your backend and return only the base64-encoded unsigned transaction:
// Trusted backend
const depositTransaction = await sdk.createDepositTransaction({
strategyId: 'YOUR_STRATEGY_ID',
baseAsset: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
amount: 1_000_000,
userKey: 'USER_WALLET_ADDRESS',
payerKey: 'USER_WALLET_ADDRESS',
});
if (typeof depositTransaction !== 'string') {
throw new Error(depositTransaction.message);
}Before creating it, validate the requested strategy, mint, amount, user address, and payer address against values your application permits. Return the serialized transaction—not the API key—to the browser. The connected wallet can then deserialize it, show it to the user for review, sign it, submit it through the application's Solana RPC, and wait for confirmation.
The direct REST POST /deposit/tx
and POST /withdraw/tx
endpoints support the same backend-to-browser handoff. Never send a seed phrase
or private key to Breeze or place one in application code.
Kit plugin reference
Setup
Install identity, payer, RPC, transaction-planning, and transaction-sending
capabilities before breeze(). Every required direct-send signer must implement
TransactionPartialSigner or TransactionModifyingSigner; a sending-only
signer is insufficient. For deposits and withdrawals, Breeze first fetches the
required lookup table and converts eligible instruction accounts to lookup-table
references; the transaction planner must then build a version-0 message.
Close-account planning skips lookup-table resolution.
breeze(config) accepts:
| Field | Type | Required | Default |
|---|---|---|---|
apiKey | string | Yes | — |
baseUrl | string | No | https://api.breeze.baby/ |
timeout | number in milliseconds | No | 30000 |
The installed client.breeze namespace provides these read methods:
| Method | Result |
|---|---|
getUserYield(options) | Paginated yield records |
getUserBalances(options) | Paginated wallet balances |
getBreezeBalances(options) | Strategy-scoped Breeze balances |
getStrategyInfo(strategyId) | Supported assets and current APY |
getHealth() | API health response |
updateApiKey(apiKey) | Replaces the key used by later Breeze requests |
Transaction methods
Each client.breeze.instructions.<op>(options) builder is finished with a
terminal call: .planTransaction(config?) builds the message without submitting,
while .sendTransaction(config?) plans, signs, submits, and confirms. Both
terminals accept an optional { abortSignal }.
| Builder | Terminal calls |
|---|---|
instructions.deposit(options) | .planTransaction(config?) / .sendTransaction(config?) |
instructions.withdraw(options) | .planTransaction(config?) / .sendTransaction(config?) |
instructions.closeUserAccount(options) | .planTransaction(config?) / .sendTransaction(config?) |
Deposit and withdrawal options require strategyId, the baseAsset mint, and
exactly one amount selection: amount in the asset's smallest unit or
all: true. Both accept an optional userTokenAccount. Withdrawal also accepts
createWsolAta, unwrapWsolAta, detectWsolAta, and excludeFees.
Close-account options require either a resolved userAccount or the
strategyId + mint pair used with the installed identity. They also accept
optional fundsRecipient and userTokenAccount overrides.
Each terminal accepts an optional { abortSignal } argument. API requests
continue to use the timeout configured in breeze(config); transaction planning,
lookup-table fetching, and sending use the installed Kit capabilities and their
configuration. Deposit and withdrawal require the planner to produce version 0
because their lookup-table compression cannot be represented by legacy or
version-1 messages. Close-account uses the planner's selected transaction version.
Errors
API failures remain BreezeApiError. Only Breeze-specific instruction and
precondition failures throw BreezeKitError from
@solana/breeze-sdk/kit:
| Code | Meaning |
|---|---|
INVALID_SERIALIZED_INSTRUCTION | The API instruction payload cannot be safely converted to Kit. |
MISSING_ADDRESS_LOOKUP_TABLE | Deposit or withdrawal instructions omitted the required lookup table. |
MISSING_TRANSACTION_SIGNER | No installed identity or payer signer matches a required signing account. |
UNSUPPORTED_TRANSACTION_VERSION | The planner produced a non-version-0 deposit or withdrawal, which requires version 0 for lookup-table compression. |
Invalid addresses, lookup-table RPC failures, and failures from transaction
planning, signing, sending, or confirmation remain native Kit or RPC errors.
Inspect and handle those errors using the installed Kit capabilities rather
than matching them as BreezeKitError.
Low-level exports
The @solana/breeze-sdk/kit entry also exports these primitives for custom Kit
composition:
| Export | Purpose |
|---|---|
breeze(config) | Installs the typed client.breeze namespace. |
getKitInstruction(serializedInstruction, signers) | Validates a Breeze byte-array instruction, converts it to Kit, and attaches matching TransactionSigner objects. |
BreezeKitError | Exposes Breeze-specific conversion and planning precondition failures through its typed code. |
getKitInstruction does not fetch lookup tables, plan, sign, or submit a
transaction. It throws BreezeKitError when the instruction is malformed or a
required signer is absent. Prefer the fluent builders unless you are assembling a
custom Kit instruction plan.
The subpath also exports its plugin, client, builder, terminal, configuration, error-code, and operation-option types as named TypeScript exports.