Skip to main content
On Solana, credit runs on Kamino Lend (the klend program). A lending market holds one reserve per token: gNTB’s reserve accepts it as collateral, and cNGN’s reserve is what lenders supply and borrowers draw. A borrower’s position is an obligation account that records its deposits and borrows.
Devnet only. No gNTB market exists on Solana mainnet yet.

The gNTB / cNGN market (devnet)

These are read from the reserve accounts; re-read them before relying on them.

Using the Kamino SDK

The simplest client is Kamino’s TypeScript SDK, @kamino-finance/klend-sdk. Load the market by its address and build actions with KaminoAction (buildDepositTxns, buildBorrowTxns, buildRepayTxns, buildWithdrawTxns): the SDK adds the refresh instructions described below for you.
The SDK resolves prices through Kamino’s mainnet Scope program by default. On devnet, our feed lives on Kamino’s devnet Scope program (3Vw8Ngkh1MVJTPHthmUbmU2XKtFEkjYvJzMqrv2rh9yX), so SDK helpers that compute prices client-side may not find it. Building and sending transactions is unaffected: the klend program reads the feed itself.

The instructions

If you build transactions yourself, klend refuses an action on stale state, so every action is preceded in the same transaction by:
  1. refresh_reserve for every reserve the obligation touches, plus the one you act on. Accounts: reserve, lending market, then the Pyth / Switchboard price / Switchboard TWAP slots (pass the klend program id for “none”), then the Scope prices account.
  2. refresh_obligation, with the obligation’s deposit reserves, then its borrow reserves, in the order the obligation lists them, as remaining accounts.
Posting collateral and borrowing can share one transaction: deposit, then refresh again (the obligation now lists the gNTB deposit), then borrow.

Accounts you derive

Reserve vaults (liquidity supply, fee receiver, collateral mint, collateral supply) are stored on the reserve account: read them from it. The gNTB and cNGN reserves have no rewards farm, so the _v2 instructions’ farm accounts are the klend program id, with the farms program FarmsPZpWu9i7Kky8tPN37rs2TpmMrAZrC7S7vJa91Hr.

kTokens

Deposits are tracked in the reserve’s collateral token (kTokens). One kToken is worth total supply ÷ kToken supply of the underlying, where total supply = available liquidity + borrowed − accumulated fees. It starts at 1 and grows as interest is paid, so convert amounts to kTokens before withdrawing (round down).

The price feed

Each reserve reads its price from a Scope feed on Kamino’s oracle program. Ours is a FixedPrice entry that GetEquity updates to gNTB’s accrued price in cNGN (entry 0), with cNGN fixed at 1 (entry 1). Read an entry from the prices account at byte offset 40 + 56 × index: value (u64), exp (u64), then the slot and unix timestamp it was last refreshed. A reserve refuses a price older than its maxAgePriceSeconds. On devnet this is set generously (7 days) for testing; a mainnet market would require a short age and a running updater.

Liquidation

When a position’s borrowed value exceeds the liquidation threshold (77%) of its collateral value, anyone may call liquidate_obligation_and_redeem_reserve_collateral to repay part of the debt and receive gNTB worth the repaid amount plus the 7.4% bonus. Kamino’s liquidation rules (how much can be repaid at once) are in its documentation.