Skip to main content
The @jup-ag/lend-referral-sdk package reads Lend Referral wrappers, builds the instructions for every user and partner operation, and reproduces the program’s math so you can show estimates and set slippage bounds. It is built on @solana/kit (Kit). The SDK never signs and never sends: it takes Kit TransactionSigners and returns Kit Instructions, and your app signs and sends them.

Install

The SDK is built on @solana/kit 8.5. Use Kit 8.5 or later in your app, so that your signers and addresses match the SDK’s types. The package is an ES module and exports everything from its root. Amounts are raw token atoms as bigint, and addresses are Kit Address strings that you compare with ===.

How a call works

Every operation is the same three steps. Only the first and the last touch the network.
  1. Read. resolveWrapper fetches the wrapper, its market, the protocol config and the vault, checks that they belong together, and returns a WrapperContext.
  2. Act. An action such as depositUnderlying turns the context into instructions and a quote. It derives every address and computes every estimate locally.
  3. Sign and send. Build a message with buildTransactionMessage or your own Kit pipeline, then sign and send it the way your app already does.
Read again before each operation. A context is a snapshot, and the quote is only as fresh as the snapshot.

Read a wrapper

A wrapper is identified by three addresses:
The context holds everything an action needs: claimAuthority and protocolFeeShareOverride are Kit Option values, never null. Read them with unwrapOption or isSome from @solana/kit. If you omit xTokenMint, resolveWrapper searches the market for its wrapper. The search throws ReferralSdkError with kind WrapperNotFound when the market has no wrapper, and AmbiguousWrapper when it has more than one. Several partners can each have a wrapper on the same market, so pass xTokenMint in production.

Deposit end to end

This example is a server process with a keypair. It deposits 1 USDC into the wrapper, accepts up to 0.5% less than the estimate, and decodes the program error if the transaction fails.
bound is required on every user action. The other operations, the bound options and the token account options are on Deposit and Withdraw.

Sign from your app

Pick the signer by who signs. A noop signer from createNoopSigner(address) puts the address on the instructions as a signer and produces no signature, so the real signature comes from the wallet or the multisig.
The wallet signs and sends in one call.

Simulate and set compute

buildTransactionMessage sets no compute budget and no priority fee unless you ask. Deposits and withdrawals in the underlying token call into Jupiter Lend and Liquidity, so simulate them before you send. simulateMessage simulates the unsigned message, so you can run it before the wallet signs.
If your instructions already contain a SetComputeUnitLimit or SetComputeUnitPrice, leave the matching option unset. Otherwise the helper throws ReferralSdkError with kind DuplicateComputeBudgetInstruction, because the runtime rejects a transaction with two of the same compute-budget instruction.

Handle errors

Failures come from two places: checks the SDK runs before it builds anything, and errors the program returns on chain. The SDK throws ReferralSdkError, with a kind and a context (account, address, matches): decodeProgramError(err, message) names the Lend Referral error behind a failed send or simulation and returns { code, name, message }, or null when the failure is not a Lend Referral error. Pass the message you sent, so that a code from another program is not named as a Lend Referral error. Errors raised inside Jupiter Lend or Liquidity return null: they use their own codes in the 6000 range. To decode a simulation result, convert value.err with getSolanaErrorFromTransactionError first, as in Simulate and set compute.
Every program error code, from 7000 to 7018, is listed with its cause in the Lend Referral Reference.