@reflectmoney/tranches
v1.0.0
Published
SDK for orchestrating Reflect Tranches (senior/junior) using Proxy Program and RLP
Maintainers
Readme
@reflectmoney/tranches
TypeScript SDK for orchestrating Reflect Tranches on Solana. Wraps the on-chain Proxy Program (senior tranche) and RLP (junior tranche) into a single high-level surface: deposit, withdraw, simulate, build address lookup tables, and discover existing tranches.
For pure exchange-rate math (designed to be called from another Solana
program), see the Rust companion crate tranche-rate-sdk.
Install
npm install @reflectmoney/tranchesPeer requirements:
@solana/kit ^6.8@reflectmoney/whitelabel ^1.0@reflectmoney/insurance(published as a sibling)
Quick start
Construct a Tranches orchestrator
import { createSolanaRpc, address } from "@solana/kit";
import { Tranches } from "@reflectmoney/tranches";
const rpc = createSolanaRpc("https://api.mainnet-beta.solana.com");
const tranches = new Tranches(rpc, {
stablecoinMint: address("..."), // underlying base asset (e.g. USDC+)
seniorMint: address("..."), // senior tranche token mint
juniorMint: address("..."), // junior tranche LP mint
});
await tranches.load();Deposit and withdraw
// Senior tranche: stablecoin in → senior tokens out
const seniorDepositIxs = await tranches.depositSenior(
user, // TransactionSigner
1_000_000, // raw amount of stablecoin
0, // minimum senior tokens (slippage protection)
);
// Junior tranche: stablecoin in → LP tokens out
const juniorDepositIxs = await tranches.depositJunior(user, 1_000_000);
// Senior tranche: senior tokens in → stablecoin out (immediate)
const seniorWithdrawIxs = await tranches.withdrawSenior(user, 500_000, 0);
// Junior tranche: two-step (cooldown)
const requestIx = await tranches.requestWithdrawJunior(user, 500_000);
// ...wait for cooldown to elapse on chain...
const withdrawIxs = await tranches.withdrawJunior(user, cooldownId);Each call returns one or more Instructions — assemble them into a
v0 transaction yourself.
Simulate before sending
// Senior:
const wrap = await tranches.simulateSeniorDeposit(1_000_000);
// → { outputAmount, newPrincipal, newIntegratorsCommission }
const unwrap = await tranches.simulateSeniorWithdraw(500_000);
// Junior:
const lpMinted = await tranches.simulateJuniorDeposit(1_000_000);
const breakdown = await tranches.simulateJuniorWithdraw(500_000);
// → [{ mint, amount }, ...]The simulation math mirrors the on-chain logic exactly (dynamic virtual offset, oracle dispatch, settlement/crank).
Discovery
import { Tranches } from "@reflectmoney/tranches";
// List every senior + junior tranche on chain:
const all = await Tranches.getAllTranches(rpc);
// Filter to tranches that hold a specific asset:
const usdcPlus = await Tranches.getTranchesByAsset(rpc, address("..."));
// Detailed stats for one tranche pair:
const seniorStats = await tranches.getSeniorTrancheStats();
const juniorStats = await tranches.getJuniorTrancheStats();Address lookup tables
The full deposit/withdraw paths touch ~12–16 accounts (more for multi-asset junior pools). To fit into a v0 transaction, build a LUT once:
const {
lookupTableAddress,
createInstruction,
extendInstructions,
} = await tranches.createLookupTable(payer);
// Send `createInstruction` first, then each `extendInstructions[i]` —
// each extend is sized to fit in one tx.Crank operations
For protocol-side rebalancing:
// Route senior commission to junior pool:
const ixs = await tranches.routeYield(crankAuthority, amount);
// Slash junior pool to top up senior vault:
const ixs = await tranches.slashAndRestore(crankAuthority, amount);
// Burn LP held by authority to boost junior rate:
const ix = await tranches.burnAuthorityLpTokens(authority, amount);Setup operations
initializeSeniorTranche and initializeJuniorTranche create new
tranches end-to-end (transfer mint authority, register the pool, build
the vault ATAs). See JSDoc on those methods.
License
MIT.
