Market-level enablement
| Field | What it does |
|---|---|
borrow_order_creation_enabled | If 1, borrowers can place new orders |
borrow_order_execution_enabled | If 1, lenders can fill placed orders |
min_borrow_order_fill_value | Minimum USD value (scaled fraction) for any single fill. Applies both at order placement and on partial fills |
min_borrow_order_fill_value is large enough to make fills economically meaningful (e.g., 1,000 equivalent). Set it to filter out dust orders that would crowd the orderbook.
- SDK
- API
- Kamino CLI
Enable borrow orders via SDK
Curator-side: flip the market flags viaupdateLendingMarketIxs. End-user-side: place orders via the setBorrowOrder instruction; lenders fill via fillBorrowOrder.Curator: enable on the market
Borrower: place an order
The SDK exposes the rawsetBorrowOrder instruction builder via the codegen module. Build the instruction with the order parameters and submit it from the borrower’s wallet.Lender: fill an order
klend-sdk/src/@codegen/klend/instructions/setBorrowOrder.ts and fillBorrowOrder.ts.The order itself
A borrow order is stored on the borrower’s obligation account. Each order specifies:| Field | What it does |
|---|---|
remaining_debt_amount | The principal still seeking a fill. Decreases as partial fills happen |
max_borrow_rate_bps | The highest interest rate (bps) the borrower will accept. A lender can fill at any rate ≤ this value |
min_debt_term_seconds | The minimum term (seconds) the borrower will accept. Lenders’ fills must use a fixed-term reserve with debt_term_seconds >= min_debt_term_seconds |
fillable_until_timestamp | Order expires after this timestamp |
enable_auto_rollover_on_filled_borrows | If 1, filled borrows from this order auto-roll on maturity (subject to market-level rollover settings) |
The matching flow
The borrower callsset-borrow-order on their obligation, specifying the parameters above. At this stage no target reserve is named: the order is a pure expression of “what I’m willing to take” — max rate, min term, expiry, size.
A lender (or filler bot, or vault) finds the order, picks a fixed-term reserve whose debt_term_seconds and current borrow rate sit inside the order’s min_debt_term_seconds and max_borrow_rate_bps bounds, and calls fill-borrow-order referencing the borrower’s obligation, the chosen reserve, and the amount to fill. The program verifies expiry, term, rate, and fill-size constraints; on success, principal flows from the reserve to the borrower’s debt position with the matched fixed term.
The order’s remaining_debt_amount decreases by the filled size. When it reaches zero, the order closes. The borrower can also cancel the order at any time, and the order is automatically void after fillable_until_timestamp passes.
Three liquidity flows that fill orders
| Flow | Source of liquidity |
|---|---|
| Repaid liquidity matching | Repayments into a fixed-term reserve free up liquidity. Bots monitor and fill outstanding borrow orders against that reserve |
| Vault-driven fills | A Kamino vault sitting on top can route deposits into a fixed-term reserve to fill matching orders, capturing the rate as yield for the vault’s depositors |
| Direct seeding | A privileged lender deposits directly into a fixed-term reserve. The deposit sits as available liquidity until a borrow order fills it |
Cancelling an order
A borrower can cancel their open order at any time (subject to no in-flight partial fill). Cancellation closes the order without affecting the borrows that have already been filled — those positions persist as normal fixed-term debt.Interaction with obligation ownership transfer
When a borrower has an open borrow order, transferring obligation ownership has a constraint: the order’s debt destination is tied to the original owner’s authority. If the new owner accepts the obligation while an order is open, the order becomes unfillable. Recommended flow: cancel any open borrow orders before initiating an obligation transfer. See Obligation ownership transfer.Off-chain infrastructure
Borrow orders are useful in proportion to the off-chain matching infrastructure around them. A typical setup:- Order indexer: an off-chain service watches
set-borrow-orderevents and maintains an orderbook view per reserve - Filler bot: a service that detects fillable orders and submits
fill-borrow-ordertransactions - UI: the borrower’s UI shows the orderbook and lets them place / cancel orders
Common errors
| Error | Cause |
|---|---|
BorrowOrderCreationDisabled | borrow_order_creation_enabled = 0. Enable |
BorrowOrderExecutionDisabled | borrow_order_execution_enabled = 0. Enable |
BorrowOrderAlreadyExists | The obligation already has an open order. Cancel the existing one first |
BorrowOrderFillValueTooSmall | Fill amount is below min_borrow_order_fill_value |
BorrowOrderExpired | now > fillable_until_timestamp. Borrower must place a new order |
BorrowOrderTermNotAcceptable | Lender’s chosen reserve has debt_term_seconds < order.min_debt_term_seconds |
BorrowOrderRateNotAcceptable | Fill rate exceeds max_borrow_rate_bps |
Reference
- Market config reference —
borrow_order_*flags andmin_borrow_order_fill_value - Fixed rate reserves — the underlying lending mechanics
- Obligation ownership transfer — interaction with open orders