Deposit & borrow in one call
executeDepositBorrow is the SDK’s main entry point: a single call that takes
a wallet from nothing to an open, working position. It’s what the deposit
/ borrow button on app.hobba.io runs.
Use it for onboarding (first deposit + first borrow together). For follow-up
operations on an existing position, use executeAction - see
Deposit, Borrow, Repay,
Withdraw.
What one call does
Section titled “What one call does”- Routes the lender. New positions open on the lender Hobba currently defaults to (Jupiter Lend); existing positions stay on their lender. Integrators never pick a market.
- Initializes first-time users. If the wallet has no position for this collateral, the flow creates the on-chain user state (and, on Jupiter Lend, the lending position) automatically - bundled into the same transaction.
- Wraps SOL when the collateral is SOL (deposits are made as wSOL; the SDK adds the wrap instructions).
- Resolves everything on-chain. Lender accounts, address lookup tables, tick accounts - all resolved internally, with automatic recovery when the lender’s tick state moves between quote and submission.
- Deposits and borrows. On Jupiter Lend the deposit and borrow execute as one atomic operation; on Kamino as a combined transaction.
- Simulates, sends, confirms and reports progress through
onStep.
Signature
Section titled “Signature”function executeDepositBorrow( params: ExecuteDepositBorrowParams): Promise<ExecuteDepositBorrowResult>;
interface ExecuteDepositBorrowParams { connection: Connection; // RPC for reads, simulation, submission signer: HobbaSigner; // { publicKey, signTransaction } collateralMint: PublicKey; // CBBTC_MINT or SOL_MINT depositAmount: BN; // collateral base units (cbBTC 1e8, SOL 1e9) borrowAmount: BN; // USDC base units (1e6) apiBaseUrl?: string; // Hobba backend, e.g. "https://app.hobba.io" onStep?: (step: string) => void; // progress text for your UI origin?: number; // partner origin id (see below); default 0}
interface ExecuteDepositBorrowResult { depositSig: string; borrowSig: string; // same tx as depositSig on Kamino lender: "juplend" | "kamino";}Example
Section titled “Example”import { executeDepositBorrow, parseCollateral, parseUsdc, SOL_MINT, classifyError,} from "@hobba-io/core";
try { const result = await executeDepositBorrow({ connection, signer, collateralMint: SOL_MINT, depositAmount: parseCollateral("2", SOL_MINT), // 2 SOL borrowAmount: parseUsdc("100"), // 100 USDC apiBaseUrl: "https://app.hobba.io", onStep: (s) => setStatus(s), // "Preparing transaction…", "Confirming…", … }); console.log(`open on ${result.lender}: ${result.borrowSig}`);} catch (e) { handle(classifyError(e));}A deposit-only onboarding works too - pass borrowAmount: new BN(0).
Validate inputs first
Section titled “Validate inputs first”Don’t guess bounds - ask the protocol. getLimits returns the
min deposit (first deposit vs top-up), the max borrow at 50% LTV, and the SOL
rent reserve; getQuote projects the resulting LTV,
liquidation price and effective APY for a confirm screen:
const limits = await getLimits({ connection, owner, collateralMint, apiBaseUrl });// enforce: depositAmount ≥ limits.minDeposit, borrowAmount ≤ limits.maxBorrowUsdc
const quote = await getQuote({ connection, collateralMint, owner, apiBaseUrl, depositAmount: depositAmount.toString(), borrowAmount: borrowAmount.toString(),});// show: quote.projected.ltvPct, quote.projected.liquidationPriceUsd,// quote.projected.riskLabel, quote.calculator.selfRepayDateKey protocol rules the limits encode:
- Minimum first deposit: 1 SOL or 0.001 cbBTC (top-ups: 0.1 SOL / 0.0001 cbBTC).
- Max user borrow: 50% of collateral value.
- SOL reserve: a “Max” SOL deposit holds back a small amount of lamports for rent and fees.
The origin parameter
Section titled “The origin parameter”Partners onboarding users through their own product can be issued an origin
id. Pass it on the user’s first position and it’s recorded permanently on
their on-chain state - this is how partner attribution works. It’s per-wallet
and first-touch-wins: later positions ignore the parameter. Leave it unset
(0 = Hobba) unless the Hobba team has issued you an id.
After the call
Section titled “After the call”The position is live: Sonnar picks it up on its next poll, tops it
up to the target LTV, and the yield subsidy starts. Read the position back
with getPosition / getPositionMetrics.