Skip to main content
This is the flagship flow: deposit USDC, split into PT+YT, sell YT on the AMM, and have the intent-router attest that the achieved APY cleared your target.

The three transactions

1

TX1, Open the session + deposit

  1. intent-router::create_session(target_rate, duration, amount, market, pool)
  2. delta-vault::deposit(amount, open_perp=true, size_amount)
  3. intent-router::record_step1, reads vault share delta, asserts delivery.
2

TX2, Split + attest

  1. split-engine::deposit(vault_shares)
  2. intent-router::record_step2, asserts PT + YT minted 1:1.
3

TX3, Swap + verify rate

  1. yield-amm::swap(YT → underlying) (or equivalently PT → underlying after you hold both)
  2. intent-router::record_step3(pt_sold, underlying_received) re-derives the achieved APY and reverts if below target_rate.

Client pseudocode

const sessionId = BigInt(Date.now());

// TX1
await sendTransaction([
  getCreateSessionInstruction({
    owner: wallet,
    sessionId,
    targetRate: 250_000_000n,   // 25% APY (9-decimal FP)
    duration: 30n * 86400n,     // 30 days
    amount: 1_000_000_000n,     // 1,000 USDC
    market, pool,
  }),
  getDepositInstruction({ /* delta-vault args */ }),
  getRecordStep1Instruction({ session, sharesBefore, sharesAfter }),
]);

// TX2
await sendTransaction([
  getSplitDepositInstruction({ /* split-engine args */ }),
  getRecordStep2Instruction({ session, ptBefore, ptAfter, ytBefore, ytAfter }),
]);

// TX3
await sendTransaction([
  getSwapInstruction({ /* yield-amm args — sell YT for underlying */ }),
  getRecordStep3Instruction({
    session,
    ptSold, underlyingReceived,
  }),
]);

What the router enforces on step 3

discount=pt_soldunderlying_received\text{discount} = \text{pt\_sold} - \text{underlying\_received} achieved_rate=discount×ONE×SECONDS_PER_YEARunderlying_received×duration\text{achieved\_rate} = \frac{\text{discount} \times \text{ONE} \times \text{SECONDS\_PER\_YEAR}}{\text{underlying\_received} \times \text{duration}} The tx reverts unless achieved_ratesession.target_rate\text{achieved\_rate} \geq \text{session.target\_rate}. If the AMM moved against you between TX2 and TX3, record_step3 reverts your PT + YT stay in your wallet, and you can retry or unwind manually.

What you’re left with

  • PT equal to your original share count, redeemable 1:1 at maturity.
  • USDC received from selling YT, the prepaid fixed yield.
  • An on-chain receipt (IntentFulfilled event) any integrator can verify.

Fixed-rate intents concept

Why this is split across three txs.

intent-router reference

Account + instruction layout.