feat(kamino): kit-bridge + read-only main market loader (roadmap #5 PR1) - #151
Merged
Conversation
…map #5 PR1) First Kamino lending PR. Foundation only — no user-facing tools yet; PR2 (prepare_kamino_init_user + prepare_kamino_supply) is the first consumer. Scope-probe finding before this PR (memory: scope-probe of klend-sdk v7.3.22): the SDK's user-facing builders (KaminoAction.buildXxxTxns) are clean — no ephemeral signers, single ix list per action via actionToIxs(). The "multi-tx prerequisite" framing in HIGH-solana-roadmap.md was overcautious; basic supply/borrow/withdraw/ repay fits the per-step prepare_* pattern we already use for MarginFi. Roadmap #4 (multi-tx pipeline) is deferred / likely unneeded. The catch: SDK is built on @solana/kit v2 while our entire Solana pipeline is @solana/web3.js v1. Bridging is small but unavoidable. What's in this PR: 1. src/modules/solana/kit-bridge.ts — reverse direction of @solana/compat (which only goes web3.js→kit). Decodes kit's AccountRole enum (READONLY=0 / WRITABLE=1 / READONLY_SIGNER=2 / WRITABLE_SIGNER=3) into the v1 isSigner+isWritable bool pair. AccountLookupMeta (per-account ALT references) is rejected with a clear error — Kamino's actionToIxs returns all-static accounts so this is dead code unless we adopt an SDK that pre-resolves lookups. 2. src/modules/solana/kamino.ts — read-only loader. Constructs a kit-style Rpc (via createSolanaRpc against our usual Helius URL) and calls KaminoMarket.load on the canonical main-market address (7u3HeHxYDLhnCoErrtycNokbQYbWGzLs6JSDqGAv5PfF). Hardcodes RECENT_SLOT_DURATION_MS=410 (matches SDK example code; live mainnet value). 3. src/modules/solana/rpc.ts — exposes getSolanaRpcUrl() so kit's RPC client constructor can target the same Helius URL as our web3.js Connection. Both clients are independent runtimes (no shared cache), but they hit the same upstream so no extra RPC budget. Tests cover all four AccountRole variants of the bridge, missing-data / missing-accounts edge cases, AccountLookupMeta rejection, and a mocked-SDK loader smoke test that pins the call shape. Deps added: @kamino-finance/klend-sdk@^7.3.22 (10.6 MB, 20 transitive deps) @solana/kit@^2.3.0 npm install required --legacy-peer-deps because of our existing @solana/web3.js override; downstream PRs and CI need the same flag. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…peer-deps Three CI fixes from PR #151: 1. Lockfile regen pinned. The first push's lockfile was produced by `npm install --legacy-peer-deps` after a clean rm; that produced incomplete entries (missing utf-8-validate, fastestsmallesttextencoderdecoder transitives) which `npm ci` rejected as out-of-sync. 2. Anchor + bs58 hoist regression. Adding @kamino-finance/klend-sdk (declares @coral-xyz/anchor@^0.28.0) caused npm to hoist 0.28 to top-level instead of MarginFi's preferred 0.30.1, breaking the MarginFi IDL load (Anchor 0.28's Idl type is missing fields the 0.30.1 IDL uses). Same story for bs58 — Kamino transitives demoted it from 6.0.0 to 4.0.1, dropping bundled type declarations. Pinned both via `overrides`: @coral-xyz/anchor: ^0.30.1 (forces Kamino onto 0.30 too — minor-version compat is reliable at the Program/coder level we use) @coral-xyz/borsh: ^0.30.1 (companion package, same alignment) bs58: ^6.0.0 (preserves bundled .d.ts) 3. CI install command. @kamino-finance/kliquidity-sdk (transitive of klend-sdk) declares peer @solana/kit@^3.0 while klend-sdk uses @solana/kit@^2.3 — strict resolution refuses to nest. Added `--legacy-peer-deps` to the `npm ci` invocation in both ci.yml and publish.yml so CI permits the nest the same way local `npm install` does. Local: 869 tests green, build clean, both Anchor + bs58 hoisted at correct versions. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
First Kamino lending PR — foundation only, no user-facing tools yet. PR2 (
prepare_kamino_init_user+prepare_kamino_supply) will be the first consumer.Why this exists
Scope-probe of
@kamino-finance/klend-sdk@7.3.22(last turn) found the SDK's user-facing builders (KaminoAction.buildXxxTxns) are clean — no ephemeral signers, single ix list per action viaactionToIxs(). The roadmap's "multi-tx prerequisite" framing was overcautious; basic supply/borrow/withdraw/repay fits the per-stepprepare_*pattern we already use for MarginFi. Roadmap #4 (multi-tx pipeline) is deferred / likely unneeded.The catch: SDK is
@solana/kitv2 while our entire Solana pipeline is@solana/web3.jsv1. Bridging is small but unavoidable.What's in this PR
src/modules/solana/kit-bridge.ts— reverse direction of@solana/compat(which only goes web3.js → kit). Decodes kit'sAccountRoleenum (READONLY=0 / WRITABLE=1 / READONLY_SIGNER=2 / WRITABLE_SIGNER=3) into the v1isSigner+isWritablebool pair.AccountLookupMetais rejected with a clear error — Kamino'sactionToIxsreturns all-static accounts so this is dead code unless we adopt an SDK that pre-resolves lookups.src/modules/solana/kamino.ts— read-only loader. Constructs a kitRpc(viacreateSolanaRpcagainst our Helius URL) and callsKaminoMarket.loadon the canonical main-market address7u3HeHxYDLhnCoErrtycNokbQYbWGzLs6JSDqGAv5PfF. HardcodesRECENT_SLOT_DURATION_MS=410(matches SDK example code).src/modules/solana/rpc.ts— exposesgetSolanaRpcUrl()so kit's RPC client constructor can target the same Helius URL as our web3.jsConnection.Test plan
npm run buildcleannpx vitest run— 869 tests, 71 files, all greenDeps added
@kamino-finance/klend-sdk@^7.3.22(10.6 MB, 20 transitive deps)@solana/kit@^2.3.0npm installneeds--legacy-peer-depsbecause of our existing@solana/web3.jsoverride.Roadmap status
🤖 Generated with Claude Code