Skip to content

feat(kamino): kit-bridge + read-only main market loader (roadmap #5 PR1) - #151

Merged
szhygulin merged 2 commits into
mainfrom
feat/kamino-pr1-kit-bridge
Apr 25, 2026
Merged

feat(kamino): kit-bridge + read-only main market loader (roadmap #5 PR1)#151
szhygulin merged 2 commits into
mainfrom
feat/kamino-pr1-kit-bridge

Conversation

@szhygulin

Copy link
Copy Markdown
Collaborator

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 via actionToIxs(). The roadmap's "multi-tx prerequisite" framing 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 @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 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 Rpc (via createSolanaRpc against our Helius URL) and calls KaminoMarket.load on the canonical main-market address 7u3HeHxYDLhnCoErrtycNokbQYbWGzLs6JSDqGAv5PfF. Hardcodes RECENT_SLOT_DURATION_MS=410 (matches SDK example code).
  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.

Test plan

  • 8 new unit tests cover: all four AccountRole variants of the bridge; missing-accounts / missing-data edge cases; AccountLookupMeta rejection; mocked-SDK loader call-shape; canonical market address pinned
  • npm run build clean
  • npx vitest run — 869 tests, 71 files, all green

Deps added

  • @kamino-finance/klend-sdk@^7.3.22 (10.6 MB, 20 transitive deps)
  • @solana/kit@^2.3.0

npm install needs --legacy-peer-deps because of our existing @solana/web3.js override.

Roadmap status

🤖 Generated with Claude Code

szhygulin and others added 2 commits April 25, 2026 04:55
…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>
@szhygulin
szhygulin merged commit 92d0dc6 into main Apr 25, 2026
3 checks passed
@szhygulin
szhygulin deleted the feat/kamino-pr1-kit-bridge branch April 25, 2026 02:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant