{"_id":"@anemonedefi/sdk","name":"@anemonedefi/sdk","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@anemonedefi/sdk","version":"0.1.0","description":"TypeScript SDK for the Anemone Interest Rate Swap Protocol on Solana","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"build":"tsc","build:watch":"tsc --watch","test":"vitest run","test:watch":"vitest","test:coverage":"vitest run --coverage","test:e2e":"vitest run --config e2e/vitest.e2e.config.ts"},"keywords":["solana","defi","interest-rate-swap","anchor"],"license":"MIT","repository":{"type":"git","url":"git+https://github.com/AnemoneDefi/SDK.git"},"publishConfig":{"access":"public"},"dependencies":{"@coral-xyz/anchor":"^0.32.1","@solana/spl-token":"^0.4.9","@solana/web3.js":"^1.98.0","bn.js":"^5.2.1"},"devDependencies":{"@kamino-finance/klend-sdk":"^7.3.22","@types/bn.js":"^5.1.6","@types/node":"^22.0.0","@vitest/coverage-v8":"^2.0.0","typescript":"^5.7.0","vitest":"^2.0.0"},"_id":"@anemonedefi/sdk@0.1.0","gitHead":"7f386ab2bc7999ee2602fe811de0501e6bbb17b5","bugs":{"url":"https://github.com/AnemoneDefi/SDK/issues"},"homepage":"https://github.com/AnemoneDefi/SDK#readme","_nodeVersion":"22.22.2","_npmVersion":"10.9.7","dist":{"integrity":"sha512-FuX3ksoyGBoCk/T+/COmvEm2BeDYDpTI3li1JQmFvUGy7uccujY6OopDrud6E7PdjQFU2e50TtZrOyhOfUylPg==","shasum":"2bdd66468248a10af4f8876829a90df053761aa3","tarball":"https://registry.npmjs.org/@anemonedefi/sdk/-/sdk-0.1.0.tgz","fileCount":236,"unpackedSize":944948,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@anemonedefi%2fsdk@0.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIAEw59WMjUjyHKIJLDRuCAd3PhUy9/oFTSGZ2TKg/yFHAiEA9t7Prjfzia5pVnt72N+GekjHdhViMAN8MTX0ufQsZ78="}]},"_npmUser":{"name":"anemonedefi-dev","email":"anemonedefi@gmail.com"},"directories":{},"maintainers":[{"name":"anemonedefi-dev","email":"anemonedefi@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sdk_0.1.0_1778478992600_0.42392082727657954"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-11T05:56:32.472Z","0.1.0":"2026-05-11T05:56:32.783Z","modified":"2026-05-11T05:56:33.274Z"},"maintainers":[{"name":"anemonedefi-dev","email":"anemonedefi@gmail.com"}],"description":"TypeScript SDK for the Anemone Interest Rate Swap Protocol on Solana","homepage":"https://github.com/AnemoneDefi/SDK#readme","keywords":["solana","defi","interest-rate-swap","anchor"],"repository":{"type":"git","url":"git+https://github.com/AnemoneDefi/SDK.git"},"bugs":{"url":"https://github.com/AnemoneDefi/SDK/issues"},"license":"MIT","readme":"# Anemone SDK\n\nTypeScript SDK for the [Anemone](https://github.com/AnemoneDefi) Interest Rate Swap protocol on Solana.\n\nAnemone lets traders take fixed vs. variable rate positions on Kamino K-Lend yields, while LPs earn the base lending rate with their capital always deployed.\n\n---\n\n## Installation\n\n```bash\nnpm install @anemone/sdk\n```\n\n---\n\n## Quick start\n\n```typescript\nimport { Connection } from \"@solana/web3.js\";\nimport { Anemone } from \"@anemone/sdk\";\n\nconst connection = new Connection(\"https://api.mainnet-beta.solana.com\");\n\n// Read-only (no wallet needed)\nconst sdk = new Anemone({ connection });\n\n// With a wallet (required to send transactions)\nconst sdk = new Anemone({ connection, wallet });\n```\n\n`wallet` is an `AnchorWallet` (Phantom, Wallet Adapter, or anything that implements `signTransaction` + `signAllTransactions`).\n\nThe SDK groups instructions by role:\n\n| Namespace | Instructions |\n|---|---|\n| `sdk.query` | `protocol`, `markets`, `positions` (read-only) |\n| `sdk.admin` | `initializeProtocol`, `createMarket`, `setKeeper`, `pauseProtocol`, `unpauseProtocol`, `setRateIndexOracle` |\n| `sdk.lp` | `depositLiquidity`, `requestWithdrawal` |\n| `sdk.keeper` | `updateRateIndex`, `syncKaminoYield`, `depositToKamino`, `withdrawFromKamino` |\n| `sdk.trader` | `openSwap`, `addCollateral`, `settlePeriod`, `closePositionEarly`, `claimMatured`, `liquidatePosition` |\n\n---\n\n## Reading on-chain state\n\n```typescript\nconst protocol = await sdk.query.protocol.fetch();\nconst markets = await sdk.query.markets.fetchAll();\n\nconst market = await sdk.query.markets.fetchByReserveAndTenor(\n  KAMINO_USDC_RESERVE,\n  BigInt(TENOR_30_DAYS)\n);\n\n// LP position\nconst lpPosition = await sdk.query.positions.fetchLpPosition(\n  wallet.publicKey.toBase58(),\n  market.publicKey\n);\n\n// Swap position (trader+market+nonce)\nconst swap = await sdk.query.positions.fetchSwapPosition(swapPositionAddress);\n```\n\n---\n\n## `preInstructions` — bundling Kamino refresh\n\nMost Kamino-touching instructions accept an optional `preInstructions: TransactionInstruction[]`. The typical pattern is to bundle a Kamino `refresh_reserve` so the program reads post-accrual values:\n\n```typescript\nimport { TransactionInstruction } from \"@solana/web3.js\";\n\n// Build a Kamino refresh_reserve instruction (Anchor discriminator)\nconst refresh = refreshReserveIx({ /* reserve, lendingMarket, scopePrices, kaminoProgram */ });\n\nawait sdk.keeper.updateRateIndex.execute({\n  keeper: wallet.publicKey,\n  underlyingReserve: new PublicKey(KAMINO_USDC_RESERVE),\n  tenorSeconds: BigInt(TENOR_30_DAYS),\n  kaminoReserve: new PublicKey(KAMINO_USDC_RESERVE),\n  preInstructions: [refresh], // atomic: refresh then read\n});\n```\n\nUse cases that accept `preInstructions`: `updateRateIndex`, `syncKaminoYield`, `depositToKamino`, `withdrawFromKamino`, `requestWithdrawal`, `closePositionEarly`, `claimMatured`, `liquidatePosition`.\n\nWithout a fresh refresh, the program may reject with `StaleOracle` or `InvalidRateIndex`.\n\n---\n\n## LP operations\n\n### Deposit liquidity\n\n```typescript\nconst { signature, lpPositionAddress } = await sdk.lp.depositLiquidity.execute({\n  depositor:      wallet.publicKey,\n  market:         new PublicKey(market.publicKey),\n  underlyingMint: new PublicKey(USDC_MINT),\n  lpMint:         new PublicKey(market.lpMint),\n  lpVault:        new PublicKey(market.lpVault),\n  amount:         100_000_000n, // 100 USDC\n});\n```\n\n### Request withdrawal\n\nSingle-shot: burns shares, redeems Kamino shortfall if needed, sends USDC back. All Kamino accounts are required even when no shortfall fires.\n\n```typescript\nconst { signature } = await sdk.lp.requestWithdrawal.execute({\n  withdrawer:    wallet.publicKey,\n  market:        new PublicKey(market.publicKey),\n  underlyingMint: new PublicKey(USDC_MINT),\n  lpMint:        new PublicKey(market.lpMint),\n  lpVault:       new PublicKey(market.lpVault),\n  treasury:      new PublicKey(protocol.treasury),\n  sharesToBurn:  lpPosition.shares,\n  // Kamino redeem-on-shortfall accounts:\n  kaminoReserve, kaminoLendingMarket, kaminoLendingMarketAuthority,\n  reserveLiquidityMint, reserveLiquiditySupply, reserveCollateralMint,\n  collateralTokenProgram, liquidityTokenProgram,\n  preInstructions: [refresh],\n});\n```\n\n---\n\n## Trader operations\n\n### Open a swap\n\n```typescript\nimport { SwapDirection } from \"@anemone/sdk\";\n\nconst { signature, swapPositionAddress } = await sdk.trader.openSwap.execute({\n  trader:          wallet.publicKey,\n  market:          new PublicKey(market.publicKey),\n  underlyingMint:  new PublicKey(USDC_MINT),\n  treasury:        new PublicKey(protocol.treasury),\n  collateralVault: new PublicKey(market.collateralVault),\n  direction:       SwapDirection.PayFixed, // or ReceiveFixed\n  notional:        100_000_000n,            // 100 USDC\n  nonce:           1,                        // unique per (trader, market)\n  maxRateBps:      1500n,                    // PayFixed slippage cap\n  minRateBps:      0n,                       // ReceiveFixed slippage floor\n});\n```\n\n### Add collateral\n\n```typescript\nawait sdk.trader.addCollateral.execute({\n  owner:           wallet.publicKey,\n  market:          new PublicKey(market.publicKey),\n  underlyingMint:  new PublicKey(USDC_MINT),\n  collateralVault: new PublicKey(market.collateralVault),\n  nonce:           1,\n  amount:          50_000_000n, // 50 USDC\n});\n```\n\n### Settle period\n\nPermissionless — anyone can call once `next_settlement_ts` has passed. Pays the period's PnL between `lp_vault` and `collateral_vault`.\n\n```typescript\nawait sdk.trader.settlePeriod.execute({\n  caller:          wallet.publicKey,\n  market:          new PublicKey(market.publicKey),\n  swapPosition:    swapPositionAddress,\n  underlyingMint:  new PublicKey(USDC_MINT),\n  lpVault:         new PublicKey(market.lpVault),\n  collateralVault: new PublicKey(market.collateralVault),\n});\n```\n\n### Close early\n\nPays the early-close fee + final MtM, releases remaining collateral.\n\n```typescript\nawait sdk.trader.closePositionEarly.execute({\n  owner:           wallet.publicKey,\n  market:          new PublicKey(market.publicKey),\n  swapPosition:    swapPositionAddress,\n  underlyingMint:  new PublicKey(USDC_MINT),\n  lpVault:         new PublicKey(market.lpVault),\n  collateralVault: new PublicKey(market.collateralVault),\n  treasury:        new PublicKey(protocol.treasury),\n  // Kamino redeem-on-shortfall accounts:\n  kaminoReserve, kaminoLendingMarket, kaminoLendingMarketAuthority,\n  reserveLiquidityMint, reserveLiquiditySupply, reserveCollateralMint,\n  collateralTokenProgram, liquidityTokenProgram,\n  preInstructions: [refresh],\n});\n```\n\n### Claim matured\n\nOnly valid after `maturity_timestamp`.\n\n```typescript\nawait sdk.trader.claimMatured.execute({\n  owner:           wallet.publicKey,\n  market:          new PublicKey(market.publicKey),\n  swapPosition:    swapPositionAddress,\n  underlyingMint:  new PublicKey(USDC_MINT),\n  lpVault:         new PublicKey(market.lpVault),\n  collateralVault: new PublicKey(market.collateralVault),\n  // ...Kamino accounts as in closePositionEarly\n});\n```\n\n### Liquidate\n\nPermissionless — any underwater position (collateral < maintenance margin) can be liquidated. Liquidation fee splits 1/3 to treasury, 2/3 to liquidator.\n\n```typescript\nawait sdk.trader.liquidatePosition.execute({\n  liquidator:      wallet.publicKey,\n  owner:           positionOwner,\n  market:          new PublicKey(market.publicKey),\n  swapPosition:    swapPositionAddress,\n  underlyingMint:  new PublicKey(USDC_MINT),\n  lpVault:         new PublicKey(market.lpVault),\n  collateralVault: new PublicKey(market.collateralVault),\n  treasury:        new PublicKey(protocol.treasury),\n  // ...Kamino accounts\n});\n```\n\n---\n\n## Admin operations\n\n### Initialize protocol\n\n```typescript\nconst { signature, protocolStateAddress } = await sdk.admin.initializeProtocol.execute({\n  authority: wallet.publicKey,\n  treasury:  treasuryAta,\n  // fees are optional — defaults match the protocol spec\n});\n```\n\n### Create market\n\n```typescript\nconst { signature, marketAddress } = await sdk.admin.createMarket.execute({\n  authority:           wallet.publicKey,\n  underlyingReserve:   new PublicKey(KAMINO_USDC_RESERVE),\n  underlyingProtocol:  new PublicKey(KAMINO_PROGRAM_ID),\n  underlyingMint:      new PublicKey(USDC_MINT),\n  kaminoCollateralMint: kaminoKUsdcMint, // = reserve.collateral.mint_pubkey\n  tenorSeconds:        BigInt(TENOR_30_DAYS),\n  settlementPeriodSeconds: BigInt(SECONDS_PER_DAY),\n});\n```\n\n### Pause / unpause\n\n`paused` blocks new `open_swap` and `deposit_liquidity`. Settlements and closes still work.\n\n```typescript\nawait sdk.admin.pauseProtocol.execute({ authority: wallet.publicKey });\nawait sdk.admin.unpauseProtocol.execute({ authority: wallet.publicKey });\n```\n\n### Set keeper\n\nRotate the address allowed to call `update_rate_index`, `deposit_to_kamino`, `withdraw_from_kamino`.\n\n```typescript\nawait sdk.admin.setKeeper.execute({\n  authority: wallet.publicKey,\n  newKeeper: keeperBotPubkey,\n});\n```\n\n### Set rate index oracle (dev-tools only)\n\nForces `market.current_rate_index` to a specific value. Only available in builds with the `dev-tools` feature flag (devnet/localnet/surfpool); excluded from mainnet builds. Used by tests to drive specific rate states; production uses `update_rate_index` reading from Kamino.\n\n```typescript\nawait sdk.admin.setRateIndexOracle.execute({\n  authority:  wallet.publicKey,\n  market:     new PublicKey(market.publicKey),\n  rateIndex:  newIndexValue,\n});\n```\n\n---\n\n## Keeper operations\n\nThe keeper bot keeps market state fresh and manages Kamino capital deployment.\n\n```typescript\n// Pull Kamino's bsf into market.current_rate_index (cron every ~3 min)\nawait sdk.keeper.updateRateIndex.execute({\n  keeper:            wallet.publicKey,\n  underlyingReserve: new PublicKey(KAMINO_USDC_RESERVE),\n  tenorSeconds:      BigInt(TENOR_30_DAYS),\n  kaminoReserve:     new PublicKey(KAMINO_USDC_RESERVE),\n  preInstructions:   [refresh],\n});\n\n// Sync NAV — credits Kamino yield delta into lp_nav\nawait sdk.keeper.syncKaminoYield.execute({\n  underlyingReserve: new PublicKey(KAMINO_USDC_RESERVE),\n  tenorSeconds:      BigInt(TENOR_30_DAYS),\n  kaminoReserve, kaminoLendingMarket,\n  pythOracle, switchboardPriceOracle, switchboardTwapOracle, scopePrices,\n  preInstructions:   [refresh],\n});\n\n// Move idle lp_vault USDC into Kamino to earn yield\nawait sdk.keeper.depositToKamino.execute({\n  keeper:            wallet.publicKey,\n  underlyingReserve: new PublicKey(KAMINO_USDC_RESERVE),\n  tenorSeconds:      BigInt(TENOR_30_DAYS),\n  amount:            500_000_000n,\n  // ...Kamino accounts\n  preInstructions:   [refresh],\n});\n\n// Redeem k-tokens back to USDC (refill lp_vault before settlements)\nawait sdk.keeper.withdrawFromKamino.execute({\n  keeper:            wallet.publicKey,\n  underlyingReserve: new PublicKey(KAMINO_USDC_RESERVE),\n  tenorSeconds:      BigInt(TENOR_30_DAYS),\n  collateralAmount:  kTokenAmount,\n  // ...Kamino accounts\n  preInstructions:   [refresh],\n});\n```\n\n---\n\n## Constants\n\n```typescript\nimport {\n  ANEMONE_PROGRAM_ID,\n  KAMINO_PROGRAM_ID,\n  KAMINO_USDC_RESERVE,\n  USDC_MINT,\n  USDC_DECIMALS,\n  LP_MINT_DECIMALS,\n  TENOR_30_DAYS,\n  TENOR_90_DAYS,\n  SECONDS_PER_DAY,\n  DEFAULT_PROTOCOL_FEE_BPS,\n  DEFAULT_OPENING_FEE_BPS,\n  DEFAULT_LIQUIDATION_FEE_BPS,\n  DEFAULT_WITHDRAWAL_FEE_BPS,\n  DEFAULT_EARLY_CLOSE_FEE_BPS,\n  DEFAULT_MAX_UTILIZATION_BPS,\n  DEFAULT_BASE_SPREAD_BPS,\n  BPS_DENOMINATOR,\n  KAMINO_MAX_STALE_SLOTS,\n  SEEDS,\n} from \"@anemone/sdk\";\n```\n\n---\n\n## PDA derivation\n\n```typescript\nimport { PdaDeriver } from \"@anemone/sdk\";\nimport { PublicKey } from \"@solana/web3.js\";\n\nconst { address: protocolState } = await PdaDeriver.protocol();\n\nconst { address: market } = await PdaDeriver.market(\n  new PublicKey(KAMINO_USDC_RESERVE),\n  BigInt(TENOR_30_DAYS)\n);\n\nconst { address: lpPosition } = await PdaDeriver.lpPosition(\n  ownerPublicKey,\n  marketPublicKey\n);\n\n// Swap position: seeds are [b\"swap\", trader, market, nonce]\nconst { address: swapPosition } = await PdaDeriver.swapPosition(\n  traderPublicKey,\n  marketPublicKey,\n  /* nonce */ 1\n);\n\nconst { address: lpVault }         = await PdaDeriver.lpVault(marketPublicKey);\nconst { address: collateralVault } = await PdaDeriver.collateralVault(marketPublicKey);\nconst { address: lpMint }          = await PdaDeriver.lpMint(marketPublicKey);\nconst { address: kaminoDeposit }   = await PdaDeriver.kaminoDepositAccount(marketPublicKey);\n```\n\n---\n\n## Development\n\n```bash\nnpm install\nnpm test                # 99 unit tests (mocked program, IDL conformance)\nnpm run test:e2e        # 37 E2E tests against surfpool — see e2e/README.md\nnpm run build           # compile to dist/\nnpx tsc --noEmit        # type-check only\n```\n\n### E2E suite (surfpool)\n\nThe E2E suite runs against [surfpool](https://github.com/txtx/surfpool), a mainnet-fork validator that lazily forks Kamino's USDC reserve, lending market, and Scope prices. See [e2e/README.md](e2e/README.md) for setup; the short version:\n\n```bash\n# In anemone/\nyarn surfpool          # start mainnet fork on 127.0.0.1:8899\nyarn ts-node scripts/setup-surfpool.ts  # deploy program + init protocol/market\n\n# In SDK/\nnpm run test:e2e\n```\n\n15 files, 37 tests, ~15 minutes total runtime. Coverage:\n\n| Category | Files |\n|---|---|\n| Read-only queries | `protocol-read` |\n| LP lifecycle | `lp-lifecycle`, `kamino-deposit` |\n| Trader lifecycle | `swap-lifecycle`, `trader-collateral`, `settle-period`, `claim-matured`, `multi-settlement` |\n| Liquidation | `liquidation` (plumbing), `liquidation-positive` (1/3 vs 2/3 split), `liquidation-organic` (no forged state) |\n| Admin / keeper | `admin-lifecycle`, `keeper-ops` |\n| Negative paths | `negative-paths` (6 reverts) |\n| Pre-mainnet hardening | `pre-mainnet` (pause guards, keeper rotation, Token-2022, slippage) |\n\nThe organic liquidation, multi-settlement, and pre-mainnet tests need the on-chain program built with the `dev-tools` feature so `set_rate_index_oracle` is exposed. Mainnet builds (`--no-default-features`) omit it.\n\n---\n\n## Program\n\n| Network | Program ID |\n|---------|-----------|\n| Mainnet | `KQs6ci5FtedFKPVJThAZSMMXyosK4TvnF7kcDSx5Jwd` |\n","readmeFilename":"README.md","_rev":"1-1eea39cbb8d64a18f0795389babfa508"}