@elmntl/jlpd-sdk 0.1.11 → 0.13.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +185 -404
  3. package/dist/common/ata.d.ts +26 -0
  4. package/dist/common/ata.js +48 -0
  5. package/dist/common/buffer.d.ts +15 -0
  6. package/dist/common/buffer.js +118 -0
  7. package/dist/common/connection.d.ts +13 -0
  8. package/dist/common/connection.js +2 -0
  9. package/dist/common/constants.d.ts +14 -0
  10. package/dist/common/constants.js +31 -0
  11. package/dist/common/index.d.ts +6 -0
  12. package/dist/common/index.js +28 -0
  13. package/dist/common/strategy-interface.d.ts +59 -0
  14. package/dist/common/strategy-interface.js +42 -0
  15. package/dist/elemental-lend/accounts.d.ts +103 -0
  16. package/dist/elemental-lend/accounts.js +354 -0
  17. package/dist/elemental-lend/constants.d.ts +25 -0
  18. package/dist/elemental-lend/constants.js +48 -0
  19. package/dist/elemental-lend/index.d.ts +8 -0
  20. package/dist/elemental-lend/index.js +24 -0
  21. package/dist/elemental-lend/instructions.d.ts +104 -0
  22. package/dist/elemental-lend/instructions.js +266 -0
  23. package/dist/elemental-lend/jupiter-lend.d.ts +91 -0
  24. package/dist/elemental-lend/jupiter-lend.js +189 -0
  25. package/dist/elemental-lend/kamino-vault.d.ts +173 -0
  26. package/dist/elemental-lend/kamino-vault.js +483 -0
  27. package/dist/elemental-lend/pda.d.ts +12 -0
  28. package/dist/elemental-lend/pda.js +24 -0
  29. package/dist/elemental-lend/protocol-actions.d.ts +56 -0
  30. package/dist/elemental-lend/protocol-actions.js +244 -0
  31. package/dist/elemental-lend/types.d.ts +113 -0
  32. package/dist/elemental-lend/types.js +2 -0
  33. package/dist/elemental-lend-v2/accounts.d.ts +14 -0
  34. package/dist/elemental-lend-v2/accounts.js +136 -0
  35. package/dist/elemental-lend-v2/adapters.d.ts +22 -0
  36. package/dist/elemental-lend-v2/adapters.js +50 -0
  37. package/dist/elemental-lend-v2/constants.d.ts +48 -0
  38. package/dist/elemental-lend-v2/constants.js +104 -0
  39. package/dist/elemental-lend-v2/index.d.ts +8 -0
  40. package/dist/elemental-lend-v2/index.js +24 -0
  41. package/dist/elemental-lend-v2/instructions.d.ts +96 -0
  42. package/dist/elemental-lend-v2/instructions.js +190 -0
  43. package/dist/elemental-lend-v2/lut.d.ts +20 -0
  44. package/dist/elemental-lend-v2/lut.js +65 -0
  45. package/dist/elemental-lend-v2/pda.d.ts +9 -0
  46. package/dist/elemental-lend-v2/pda.js +27 -0
  47. package/dist/elemental-lend-v2/types.d.ts +105 -0
  48. package/dist/elemental-lend-v2/types.js +2 -0
  49. package/dist/elemental-lend-v2/update-aum.d.ts +29 -0
  50. package/dist/elemental-lend-v2/update-aum.js +82 -0
  51. package/dist/index.d.ts +5 -3552
  52. package/dist/index.js +37 -4454
  53. package/dist/jlpd-strategy/accounts.d.ts +83 -0
  54. package/dist/jlpd-strategy/accounts.js +216 -0
  55. package/dist/jlpd-strategy/adapter.d.ts +81 -0
  56. package/dist/jlpd-strategy/adapter.js +118 -0
  57. package/dist/jlpd-strategy/base-to-base-swap.d.ts +74 -0
  58. package/dist/jlpd-strategy/base-to-base-swap.js +205 -0
  59. package/dist/jlpd-strategy/constants.d.ts +127 -0
  60. package/dist/jlpd-strategy/constants.js +174 -0
  61. package/dist/jlpd-strategy/fluid-view.d.ts +199 -0
  62. package/dist/jlpd-strategy/fluid-view.js +799 -0
  63. package/dist/jlpd-strategy/hedge-derived.d.ts +135 -0
  64. package/dist/jlpd-strategy/hedge-derived.js +231 -0
  65. package/dist/jlpd-strategy/hedge-instructions.d.ts +210 -0
  66. package/dist/jlpd-strategy/hedge-instructions.js +300 -0
  67. package/dist/jlpd-strategy/hedge-state.d.ts +88 -0
  68. package/dist/jlpd-strategy/hedge-state.js +110 -0
  69. package/dist/jlpd-strategy/index.d.ts +17 -0
  70. package/dist/jlpd-strategy/index.js +33 -0
  71. package/dist/jlpd-strategy/instructions.d.ts +159 -0
  72. package/dist/jlpd-strategy/instructions.js +234 -0
  73. package/dist/jlpd-strategy/jlp-borrow.d.ts +63 -0
  74. package/dist/jlpd-strategy/jlp-borrow.js +87 -0
  75. package/dist/jlpd-strategy/jlp-data.d.ts +166 -0
  76. package/dist/jlpd-strategy/jlp-data.js +611 -0
  77. package/dist/jlpd-strategy/jupusd-earn.d.ts +90 -0
  78. package/dist/jlpd-strategy/jupusd-earn.js +166 -0
  79. package/dist/jlpd-strategy/live-jlp-price.d.ts +46 -0
  80. package/dist/jlpd-strategy/live-jlp-price.js +267 -0
  81. package/dist/jlpd-strategy/pda.d.ts +13 -0
  82. package/dist/jlpd-strategy/pda.js +28 -0
  83. package/dist/jlpd-strategy/settle-yield.d.ts +45 -0
  84. package/dist/jlpd-strategy/settle-yield.js +113 -0
  85. package/dist/jlpd-strategy/swap-jlp.d.ts +198 -0
  86. package/dist/jlpd-strategy/swap-jlp.js +586 -0
  87. package/dist/jlpd-strategy/types.d.ts +101 -0
  88. package/dist/jlpd-strategy/types.js +29 -0
  89. package/dist/p-stv-core/accounts.d.ts +152 -0
  90. package/dist/p-stv-core/accounts.js +407 -0
  91. package/dist/p-stv-core/constants.d.ts +138 -0
  92. package/dist/p-stv-core/constants.js +181 -0
  93. package/dist/p-stv-core/events.d.ts +7 -0
  94. package/dist/p-stv-core/events.js +246 -0
  95. package/dist/p-stv-core/index.d.ts +11 -0
  96. package/dist/p-stv-core/index.js +27 -0
  97. package/dist/p-stv-core/instructions.d.ts +637 -0
  98. package/dist/p-stv-core/instructions.js +670 -0
  99. package/dist/p-stv-core/lut.d.ts +41 -0
  100. package/dist/p-stv-core/lut.js +81 -0
  101. package/dist/p-stv-core/pda.d.ts +30 -0
  102. package/dist/p-stv-core/pda.js +65 -0
  103. package/dist/p-stv-core/prices.d.ts +20 -0
  104. package/dist/p-stv-core/prices.js +77 -0
  105. package/dist/p-stv-core/remaining-accounts.d.ts +107 -0
  106. package/dist/p-stv-core/remaining-accounts.js +326 -0
  107. package/dist/p-stv-core/send-tx.d.ts +72 -0
  108. package/dist/p-stv-core/send-tx.js +290 -0
  109. package/dist/p-stv-core/sol-wrap.d.ts +34 -0
  110. package/dist/p-stv-core/sol-wrap.js +74 -0
  111. package/dist/p-stv-core/types.d.ts +361 -0
  112. package/dist/p-stv-core/types.js +2 -0
  113. package/package.json +56 -15
  114. package/dist/index.d.mts +0 -3552
  115. package/dist/index.mjs +0 -4363
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.findStrategyStatePda = findStrategyStatePda;
4
+ exports.findStvPositionPda = findStvPositionPda;
5
+ exports.findLendManagerRolePda = findLendManagerRolePda;
6
+ const web3_js_1 = require("@solana/web3.js");
7
+ const constants_1 = require("./constants");
8
+ function findStrategyStatePda(baseMint, programId = constants_1.PROGRAM_ID) {
9
+ return web3_js_1.PublicKey.findProgramAddressSync([constants_1.STRATEGY_STATE_SEED, baseMint.toBuffer()], programId);
10
+ }
11
+ function findStvPositionPda(stv, programId = constants_1.PROGRAM_ID) {
12
+ return web3_js_1.PublicKey.findProgramAddressSync([constants_1.POSITION_SEED, stv.toBuffer()], programId);
13
+ }
14
+ /**
15
+ * Derive the per-strategy_state `ManagerRole` PDA for Elemental Lend.
16
+ * Seeds: `["manager", strategy_state, manager]`.
17
+ *
18
+ * Note the per-program prefix on the name: each Elemental program has its
19
+ * own `ManagerRole` PDA scoped to a different anchor account (`p-stv-core`
20
+ * → STV, `jlpd-strategy` → JlpdConfig).
21
+ */
22
+ function findLendManagerRolePda(strategyState, manager, programId = constants_1.PROGRAM_ID) {
23
+ return web3_js_1.PublicKey.findProgramAddressSync([constants_1.MANAGER_SEED, strategyState.toBuffer(), manager.toBuffer()], programId);
24
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Protocol action transaction builders for Elemental Lend.
3
+ *
4
+ * Builds complete instruction arrays for deposit/withdraw to/from
5
+ * Kamino kVault and Jupiter Lend protocols. Ready to pass to sendSmartTx.
6
+ */
7
+ import { PublicKey, TransactionInstruction } from "@solana/web3.js";
8
+ /**
9
+ * Connection interface required by the protocol-action builders. This is a
10
+ * narrower subset of the canonical `SolanaConnection` defined in
11
+ * `common/connection.ts` — protocol actions only ever need to read accounts.
12
+ */
13
+ import type { SolanaConnection } from "../common/connection";
14
+ export type ProtocolActionConnection = Pick<SolanaConnection, "getAccountInfo" | "getMultipleAccountsInfo">;
15
+ import type { JupiterLendPool } from "./jupiter-lend";
16
+ export type ProtocolType = "Kamino kVault" | "Jupiter Lend";
17
+ export type ProtocolAction = "deposit" | "withdraw";
18
+ export interface ProtocolActionArgs {
19
+ connection: ProtocolActionConnection;
20
+ /** Manager wallet (signer) */
21
+ manager: PublicKey;
22
+ /** Lend strategy state PDA (derived from baseMint if not provided) */
23
+ strategyState?: PublicKey;
24
+ /** Protocol address (Kamino vault_state or Jupiter Lend lending account) */
25
+ protocol: PublicKey;
26
+ protocolType: ProtocolType;
27
+ action: ProtocolAction;
28
+ /** Amount in base token units (e.g. USDC lamports) */
29
+ amount: bigint;
30
+ /**
31
+ * Minimum protocol-receipt out (deposit: min shares/fTokens; withdraw: min base).
32
+ * On-chain the handler reverts if the CPI yields less (and always requires > 0).
33
+ * Defaults to 0n (non-zero still enforced; 0 opts out of slippage protection).
34
+ */
35
+ minOut?: bigint;
36
+ baseMint: PublicKey;
37
+ /** Token program for the base mint (defaults to SPL Token) */
38
+ tokenProgram?: PublicKey;
39
+ /** Jupiter Lend pool config (defaults to USDC_POOL) */
40
+ jupLendPool?: JupiterLendPool;
41
+ /** Elemental Lend program ID (defaults to PROGRAM_ID) */
42
+ programId?: PublicKey;
43
+ }
44
+ /**
45
+ * Build complete instruction array for a protocol deposit or withdraw.
46
+ *
47
+ * Returns instructions including a compute budget instruction (400k CU)
48
+ * and the protocol-specific instruction with all accounts resolved.
49
+ *
50
+ * For Kamino kVault withdraw: reads vault_state on-chain to convert
51
+ * base amount to kvToken shares, and reads KLend reserves for the
52
+ * withdraw accounts.
53
+ *
54
+ * @returns TransactionInstruction[] ready for sendSmartTx
55
+ */
56
+ export declare function buildProtocolActionIxs(args: ProtocolActionArgs): Promise<TransactionInstruction[]>;
@@ -0,0 +1,244 @@
1
+ "use strict";
2
+ /**
3
+ * Protocol action transaction builders for Elemental Lend.
4
+ *
5
+ * Builds complete instruction arrays for deposit/withdraw to/from
6
+ * Kamino kVault and Jupiter Lend protocols. Ready to pass to sendSmartTx.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.buildProtocolActionIxs = buildProtocolActionIxs;
10
+ const web3_js_1 = require("@solana/web3.js");
11
+ const spl_token_1 = require("@solana/spl-token");
12
+ const ata_1 = require("../common/ata");
13
+ const constants_1 = require("./constants");
14
+ const pda_1 = require("./pda");
15
+ const kamino_vault_1 = require("./kamino-vault");
16
+ const jupiter_lend_1 = require("./jupiter-lend");
17
+ // ---------------------------------------------------------------------------
18
+ // Main Builder
19
+ // ---------------------------------------------------------------------------
20
+ /**
21
+ * Build complete instruction array for a protocol deposit or withdraw.
22
+ *
23
+ * Returns instructions including a compute budget instruction (400k CU)
24
+ * and the protocol-specific instruction with all accounts resolved.
25
+ *
26
+ * For Kamino kVault withdraw: reads vault_state on-chain to convert
27
+ * base amount to kvToken shares, and reads KLend reserves for the
28
+ * withdraw accounts.
29
+ *
30
+ * @returns TransactionInstruction[] ready for sendSmartTx
31
+ */
32
+ async function buildProtocolActionIxs(args) {
33
+ const { connection, manager, protocol, protocolType, action, amount, minOut = 0n, baseMint, tokenProgram = spl_token_1.TOKEN_PROGRAM_ID, jupLendPool, programId = constants_1.PROGRAM_ID, } = args;
34
+ const [strategyStatePda] = args.strategyState
35
+ ? [args.strategyState]
36
+ : (0, pda_1.findStrategyStatePda)(baseMint, programId);
37
+ const strategyBaseAta = (0, ata_1.findAta)(baseMint, strategyStatePda, tokenProgram);
38
+ const [managerRolePda] = (0, pda_1.findLendManagerRolePda)(strategyStatePda, manager, programId);
39
+ if (protocolType === "Jupiter Lend") {
40
+ return buildJupLendActionIxs({
41
+ connection,
42
+ manager,
43
+ strategyStatePda,
44
+ strategyBaseAta,
45
+ managerRolePda,
46
+ protocol,
47
+ action,
48
+ amount,
49
+ minOut,
50
+ baseMint,
51
+ tokenProgram,
52
+ pool: jupLendPool ?? jupiter_lend_1.JUP_LEND_POOLS[baseMint.toBase58()] ?? jupiter_lend_1.USDC_POOL,
53
+ programId,
54
+ });
55
+ }
56
+ else {
57
+ return buildKvaultActionIxs({
58
+ connection,
59
+ manager,
60
+ strategyStatePda,
61
+ strategyBaseAta,
62
+ managerRolePda,
63
+ vaultState: protocol,
64
+ action,
65
+ amount,
66
+ minOut,
67
+ baseMint,
68
+ tokenProgram,
69
+ programId,
70
+ });
71
+ }
72
+ }
73
+ function buildJupLendActionIxs(params) {
74
+ const { manager, strategyStatePda, strategyBaseAta, managerRolePda, action, amount, minOut, tokenProgram, pool, programId, } = params;
75
+ const strategyFtokenAta = (0, ata_1.findAta)(pool.fTokenMint, strategyStatePda, tokenProgram);
76
+ const JUP_LEND_PROG = new web3_js_1.PublicKey("jup3YeL8QhtSx1e253b2FDvsMNC87fDrgQZivbrndc9");
77
+ // Fixed accounts for the Anchor instruction
78
+ const fixedAccounts = [
79
+ { pubkey: manager, isSigner: true, isWritable: true },
80
+ { pubkey: strategyStatePda, isSigner: false, isWritable: false },
81
+ { pubkey: managerRolePda, isSigner: false, isWritable: false },
82
+ { pubkey: strategyBaseAta, isSigner: false, isWritable: true },
83
+ { pubkey: strategyFtokenAta, isSigner: false, isWritable: true },
84
+ ];
85
+ let disc;
86
+ let remainingAccounts;
87
+ if (action === "deposit") {
88
+ disc = Buffer.from(constants_1.IX_JUP_LEND_DEPOSIT);
89
+ remainingAccounts = [
90
+ ...(0, jupiter_lend_1.buildJupLendDepositAccounts)(pool, strategyStatePda, strategyBaseAta, strategyFtokenAta).map((a) => ({ ...a, isSigner: false })),
91
+ { pubkey: JUP_LEND_PROG, isSigner: false, isWritable: false },
92
+ ];
93
+ }
94
+ else {
95
+ disc = Buffer.from(constants_1.IX_JUP_LEND_WITHDRAW);
96
+ remainingAccounts = [
97
+ ...(0, jupiter_lend_1.buildJupLendWithdrawAccounts)(pool, strategyStatePda, strategyFtokenAta, strategyBaseAta).map((a) => ({ ...a, isSigner: false })),
98
+ { pubkey: JUP_LEND_PROG, isSigner: false, isWritable: false },
99
+ ];
100
+ }
101
+ // Data: disc(8) + amount(8) + min_out(8) [deposit: min_ftokens_out, withdraw: min_base_out].
102
+ const amountBuf = Buffer.alloc(8);
103
+ amountBuf.writeBigUInt64LE(amount, 0);
104
+ const minOutBuf = Buffer.alloc(8);
105
+ minOutBuf.writeBigUInt64LE(minOut, 0);
106
+ const ixData = Buffer.concat([disc, amountBuf, minOutBuf]);
107
+ const ix = new web3_js_1.TransactionInstruction({
108
+ keys: [...fixedAccounts, ...remainingAccounts],
109
+ programId,
110
+ data: ixData,
111
+ });
112
+ return Promise.resolve([ix]);
113
+ }
114
+ async function buildKvaultActionIxs(params) {
115
+ const { connection, manager, strategyStatePda, strategyBaseAta, managerRolePda, vaultState, action, amount, minOut, baseMint, tokenProgram, programId, } = params;
116
+ // Read vault state for reserve data (needed for both deposit and withdraw)
117
+ const vaultStateInfo = await connection.getAccountInfo(vaultState);
118
+ if (!vaultStateInfo)
119
+ throw new Error("Kamino vault state not found");
120
+ const vaultData = vaultStateInfo.data;
121
+ // Read ALL KLend reserves from vault state for batch refresh
122
+ const reserveKeys = [];
123
+ for (let i = 0; i < 10; i++) {
124
+ try {
125
+ const { reserve } = (0, kamino_vault_1.readVaultAllocation)(vaultData, i);
126
+ if (!reserve.equals(web3_js_1.PublicKey.default)) {
127
+ reserveKeys.push(reserve);
128
+ }
129
+ }
130
+ catch {
131
+ break;
132
+ }
133
+ }
134
+ // Fetch all reserves to read their lending_market field. `readReserveAccounts`
135
+ // (from kamino-vault.ts) is the canonical parser — keeps the KLend Reserve
136
+ // layout constants in one place.
137
+ const reserveInfos = await connection.getMultipleAccountsInfo(reserveKeys);
138
+ const klendReserves = [];
139
+ for (let i = 0; i < reserveKeys.length; i++) {
140
+ const rInfo = reserveInfos[i];
141
+ if (!rInfo)
142
+ continue;
143
+ try {
144
+ const { lendingMarket } = (0, kamino_vault_1.readReserveAccounts)(rInfo.data);
145
+ klendReserves.push({ reserve: reserveKeys[i], lendingMarket });
146
+ }
147
+ catch {
148
+ // Skip reserves whose data isn't long enough for a full parse
149
+ }
150
+ }
151
+ const [sharesMint] = (0, kamino_vault_1.findKvaultSharesMint)(vaultState);
152
+ const strategySharesAta = (0, ata_1.findAta)(sharesMint, strategyStatePda, tokenProgram);
153
+ // Fixed accounts for the Anchor instruction
154
+ const fixedAccounts = [
155
+ { pubkey: manager, isSigner: true, isWritable: true },
156
+ { pubkey: strategyStatePda, isSigner: false, isWritable: false },
157
+ { pubkey: managerRolePda, isSigner: false, isWritable: false },
158
+ { pubkey: strategyBaseAta, isSigner: false, isWritable: true },
159
+ { pubkey: strategySharesAta, isSigner: false, isWritable: true },
160
+ ];
161
+ if (action === "deposit") {
162
+ return buildKvaultDepositIxs(fixedAccounts, vaultState, strategyStatePda, strategyBaseAta, strategySharesAta, baseMint, klendReserves, amount, minOut, programId);
163
+ }
164
+ else {
165
+ return buildKvaultWithdrawIxs(connection, fixedAccounts, vaultState, vaultData, strategyStatePda, strategyBaseAta, strategySharesAta, baseMint, klendReserves, amount, minOut, programId);
166
+ }
167
+ }
168
+ function buildKvaultDepositIxs(fixedAccounts, vaultState, strategyStatePda, strategyBaseAta, strategySharesAta, baseMint, klendReserves, amount, minOut, programId) {
169
+ const disc = Buffer.from(constants_1.IX_KVAULT_DEPOSIT);
170
+ const remainingAccounts = (0, kamino_vault_1.buildKvaultDepositAccounts)(vaultState, strategyStatePda, strategyBaseAta, strategySharesAta, baseMint, klendReserves).map((a) => ({ ...a, isSigner: false }));
171
+ // Data: disc(8) + amount(8) + min_shares_out(8).
172
+ const amountBuf = Buffer.alloc(8);
173
+ amountBuf.writeBigUInt64LE(amount, 0);
174
+ const minOutBuf = Buffer.alloc(8);
175
+ minOutBuf.writeBigUInt64LE(minOut, 0);
176
+ const ixData = Buffer.concat([disc, amountBuf, minOutBuf]);
177
+ const ix = new web3_js_1.TransactionInstruction({
178
+ keys: [...fixedAccounts, ...remainingAccounts],
179
+ programId,
180
+ data: ixData,
181
+ });
182
+ return Promise.resolve([ix]);
183
+ }
184
+ async function buildKvaultWithdrawIxs(connection, fixedAccounts, vaultState, vaultData, strategyStatePda, strategyBaseAta, strategySharesAta, baseMint, klendReserves, amount, minOut, programId) {
185
+ const disc = Buffer.from(constants_1.IX_KVAULT_WITHDRAW);
186
+ // Convert base amount to kvToken shares
187
+ const sharesIssued = vaultData.readBigUInt64LE(232);
188
+ const prevAumSfLo = vaultData.readBigUInt64LE(280);
189
+ const prevAumSfHi = vaultData.readBigUInt64LE(288);
190
+ const prevAumSf = prevAumSfLo + (prevAumSfHi << BigInt(64));
191
+ const FRACTION_ONE = BigInt(1) << BigInt(60);
192
+ let withdrawShares;
193
+ if (prevAumSf > BigInt(0) && sharesIssued > BigInt(0)) {
194
+ // Round up to ensure enough shares are redeemed
195
+ withdrawShares = (amount * sharesIssued * FRACTION_ONE + prevAumSf - BigInt(1)) / prevAumSf;
196
+ }
197
+ else {
198
+ withdrawShares = amount; // fallback: 1:1
199
+ }
200
+ // Cap to actual kvToken balance.
201
+ // SPL Token Account layout: [mint(0..32)][owner(32..64)][amount(64..72)]…
202
+ const sharesAtaInfo = await connection.getAccountInfo(strategySharesAta);
203
+ if (sharesAtaInfo) {
204
+ const actualBalance = sharesAtaInfo.data.readBigUInt64LE(64);
205
+ if (withdrawShares > actualBalance) {
206
+ withdrawShares = actualBalance;
207
+ }
208
+ }
209
+ // Read reserve data for withdraw accounts.
210
+ // Kamino VaultState — first allocation slot starts at offset 312:
211
+ // [312..344] reserve Pubkey
212
+ // [344..376] ctokenVault Pubkey
213
+ // (See `kamino-vault.ts:VAULT_ALLOCATION_OFFSET` for the full table.)
214
+ const reserveKey = new web3_js_1.PublicKey(vaultData.subarray(312, 344));
215
+ const reserveInfo = await connection.getAccountInfo(reserveKey);
216
+ if (!reserveInfo)
217
+ throw new Error("KLend reserve not found");
218
+ const reserveConfig = (0, kamino_vault_1.buildKvaultWithdrawReserveConfig)(vaultData, reserveInfo.data, 0);
219
+ const remainingAccounts = (0, kamino_vault_1.buildKvaultWithdrawAccounts)(vaultState, strategyStatePda, strategyBaseAta, strategySharesAta, baseMint, reserveConfig).map((a) => ({ ...a, isSigner: false }));
220
+ // Append ALL reserves first, then unique lending markets
221
+ for (const r of klendReserves) {
222
+ remainingAccounts.push({ pubkey: r.reserve, isSigner: false, isWritable: true });
223
+ }
224
+ const seenMarkets = new Set();
225
+ for (const r of klendReserves) {
226
+ const key = r.lendingMarket.toBase58();
227
+ if (!seenMarkets.has(key)) {
228
+ seenMarkets.add(key);
229
+ remainingAccounts.push({ pubkey: r.lendingMarket, isSigner: false, isWritable: false });
230
+ }
231
+ }
232
+ // Data: disc(8) + shares(8) + min_base_out(8). minOut is the base-out floor.
233
+ const sharesBuf = Buffer.alloc(8);
234
+ sharesBuf.writeBigUInt64LE(withdrawShares, 0);
235
+ const minOutBuf = Buffer.alloc(8);
236
+ minOutBuf.writeBigUInt64LE(minOut, 0);
237
+ const ixData = Buffer.concat([disc, sharesBuf, minOutBuf]);
238
+ const ix = new web3_js_1.TransactionInstruction({
239
+ keys: [...fixedAccounts, ...remainingAccounts],
240
+ programId,
241
+ data: ixData,
242
+ });
243
+ return [ix];
244
+ }
@@ -0,0 +1,113 @@
1
+ import { PublicKey } from "@solana/web3.js";
2
+ import BN from "bn.js";
3
+ import type { StrategyStateHeader } from "../common/strategy-interface";
4
+ /** Full StrategyState for Elemental Lend (536 bytes) */
5
+ export interface LendStrategyState extends StrategyStateHeader {
6
+ admin: PublicKey;
7
+ protocols: PublicKey[];
8
+ protocolCount: number;
9
+ managerCount: number;
10
+ }
11
+ /** ManagerRole account — authorizes a manager for protocol instructions */
12
+ export interface ManagerRole {
13
+ strategyState: PublicKey;
14
+ manager: PublicKey;
15
+ bump: number;
16
+ }
17
+ export type { StvPosition } from "../common/strategy-interface";
18
+ export interface StrategyInitializedEvent {
19
+ name: "StrategyInitialized";
20
+ strategyState: PublicKey;
21
+ admin: PublicKey;
22
+ baseMint: PublicKey;
23
+ authority: PublicKey;
24
+ }
25
+ export interface StrategyUpdatedEvent {
26
+ name: "StrategyUpdated";
27
+ strategyState: PublicKey;
28
+ oldAdmin: PublicKey;
29
+ newAdmin: PublicKey;
30
+ oldAuthority: PublicKey;
31
+ newAuthority: PublicKey;
32
+ oldFlags: number;
33
+ newFlags: number;
34
+ }
35
+ export interface PositionInitializedEvent {
36
+ name: "PositionInitialized";
37
+ strategyState: PublicKey;
38
+ stv: PublicKey;
39
+ }
40
+ export interface LendDepositEvent {
41
+ name: "DepositEvent";
42
+ strategyState: PublicKey;
43
+ stv: PublicKey;
44
+ amount: BN;
45
+ shares: BN;
46
+ pps: BN;
47
+ }
48
+ export interface LendWithdrawEvent {
49
+ name: "WithdrawEvent";
50
+ strategyState: PublicKey;
51
+ stv: PublicKey;
52
+ shares: BN;
53
+ amount: BN;
54
+ pps: BN;
55
+ }
56
+ export interface AumUpdatedEvent {
57
+ name: "AumUpdated";
58
+ strategyState: PublicKey;
59
+ totalAum: BN;
60
+ pps: BN;
61
+ lastUpdated: BN;
62
+ }
63
+ export interface KvaultDepositEvent {
64
+ name: "KvaultDepositEvent";
65
+ strategyState: PublicKey;
66
+ amount: BN;
67
+ sharesReceived: BN;
68
+ timestamp: BN;
69
+ }
70
+ export interface KvaultWithdrawEvent {
71
+ name: "KvaultWithdrawEvent";
72
+ strategyState: PublicKey;
73
+ shares: BN;
74
+ baseReceived: BN;
75
+ timestamp: BN;
76
+ }
77
+ export interface JupLendDepositEvent {
78
+ name: "JupLendDepositEvent";
79
+ strategyState: PublicKey;
80
+ amount: BN;
81
+ ftokensReceived: BN;
82
+ timestamp: BN;
83
+ }
84
+ export interface JupLendWithdrawEvent {
85
+ name: "JupLendWithdrawEvent";
86
+ strategyState: PublicKey;
87
+ amount: BN;
88
+ ftokensBurned: BN;
89
+ timestamp: BN;
90
+ }
91
+ export interface ProtocolAddedEvent {
92
+ name: "ProtocolAdded";
93
+ strategyState: PublicKey;
94
+ protocolAccount: PublicKey;
95
+ protocolCount: number;
96
+ }
97
+ export interface ProtocolRemovedEvent {
98
+ name: "ProtocolRemoved";
99
+ strategyState: PublicKey;
100
+ protocolAccount: PublicKey;
101
+ protocolCount: number;
102
+ }
103
+ export interface ManagerAddedEvent {
104
+ name: "ManagerAdded";
105
+ strategyState: PublicKey;
106
+ manager: PublicKey;
107
+ }
108
+ export interface ManagerRemovedEvent {
109
+ name: "ManagerRemoved";
110
+ strategyState: PublicKey;
111
+ manager: PublicKey;
112
+ }
113
+ export type LendEvent = StrategyInitializedEvent | StrategyUpdatedEvent | PositionInitializedEvent | LendDepositEvent | LendWithdrawEvent | AumUpdatedEvent | KvaultDepositEvent | KvaultWithdrawEvent | JupLendDepositEvent | JupLendWithdrawEvent | ProtocolAddedEvent | ProtocolRemovedEvent | ManagerAddedEvent | ManagerRemovedEvent;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,14 @@
1
+ import { PublicKey } from "@solana/web3.js";
2
+ import type { StvPosition } from "../common/strategy-interface";
3
+ import type { SolanaConnection } from "../common/connection";
4
+ import type { LendStrategyState, ProtocolVault, ManagerRole } from "./types";
5
+ export declare function deserializeStrategyState(data: Buffer): LendStrategyState;
6
+ export declare function deserializeProtocolVault(data: Buffer): ProtocolVault;
7
+ export declare function deserializeLendStvPosition(data: Buffer): StvPosition;
8
+ export declare function deserializeManagerRole(data: Buffer): ManagerRole;
9
+ export declare function fetchStrategyState(connection: SolanaConnection, baseMint: PublicKey, programId?: PublicKey): Promise<LendStrategyState>;
10
+ export declare function fetchStrategyStateByAddress(connection: SolanaConnection, address: PublicKey): Promise<LendStrategyState>;
11
+ export declare function fetchProtocolVault(connection: SolanaConnection, strategyState: PublicKey, index: number, programId?: PublicKey): Promise<ProtocolVault>;
12
+ export declare function fetchAllProtocolVaults(connection: SolanaConnection, strategyState: PublicKey, protocolCount: number, programId?: PublicKey): Promise<[PublicKey, ProtocolVault][]>;
13
+ export declare function fetchLendStvPosition(connection: SolanaConnection, stv: PublicKey, programId?: PublicKey): Promise<StvPosition>;
14
+ export declare function fetchManagerRole(connection: SolanaConnection, strategyState: PublicKey, manager: PublicKey, programId?: PublicKey): Promise<ManagerRole | null>;
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deserializeStrategyState = deserializeStrategyState;
4
+ exports.deserializeProtocolVault = deserializeProtocolVault;
5
+ exports.deserializeLendStvPosition = deserializeLendStvPosition;
6
+ exports.deserializeManagerRole = deserializeManagerRole;
7
+ exports.fetchStrategyState = fetchStrategyState;
8
+ exports.fetchStrategyStateByAddress = fetchStrategyStateByAddress;
9
+ exports.fetchProtocolVault = fetchProtocolVault;
10
+ exports.fetchAllProtocolVaults = fetchAllProtocolVaults;
11
+ exports.fetchLendStvPosition = fetchLendStvPosition;
12
+ exports.fetchManagerRole = fetchManagerRole;
13
+ const buffer_1 = require("../common/buffer");
14
+ const strategy_interface_1 = require("../common/strategy-interface");
15
+ const constants_1 = require("./constants");
16
+ const pda_1 = require("./pda");
17
+ // ---------------------------------------------------------------------------
18
+ // Deserializers
19
+ // ---------------------------------------------------------------------------
20
+ function deserializeStrategyState(data) {
21
+ if (data.length < constants_1.STRATEGY_STATE_SIZE) {
22
+ throw new Error(`StrategyState data too short: ${data.length} < ${constants_1.STRATEGY_STATE_SIZE}`);
23
+ }
24
+ if (!data.subarray(0, 8).equals(constants_1.DISC_STRATEGY_STATE)) {
25
+ throw new Error(`Invalid StrategyState discriminator`);
26
+ }
27
+ return {
28
+ baseMint: (0, buffer_1.readPubkey)(data, 8),
29
+ authority: (0, buffer_1.readPubkey)(data, 40),
30
+ pps: (0, buffer_1.readU64)(data, 72),
31
+ totalAum: (0, buffer_1.readU64)(data, 80),
32
+ totalShares: (0, buffer_1.readU64)(data, 88),
33
+ lastUpdated: (0, buffer_1.readU64)(data, 96),
34
+ flags: (0, buffer_1.readU16)(data, 104),
35
+ version: (0, buffer_1.readU8)(data, 106),
36
+ bump: (0, buffer_1.readU8)(data, 107),
37
+ admin: (0, buffer_1.readPubkey)(data, 112),
38
+ protocolCount: (0, buffer_1.readU8)(data, 144),
39
+ };
40
+ }
41
+ function deserializeProtocolVault(data) {
42
+ if (data.length < constants_1.PROTOCOL_VAULT_SIZE) {
43
+ throw new Error(`ProtocolVault data too short: ${data.length} < ${constants_1.PROTOCOL_VAULT_SIZE}`);
44
+ }
45
+ if (!data.subarray(0, 8).equals(constants_1.DISC_PROTOCOL_VAULT)) {
46
+ throw new Error(`Invalid ProtocolVault discriminator`);
47
+ }
48
+ return {
49
+ strategyState: (0, buffer_1.readPubkey)(data, 8),
50
+ adapterProgram: (0, buffer_1.readPubkey)(data, 40),
51
+ protocolState: (0, buffer_1.readPubkey)(data, 72),
52
+ index: (0, buffer_1.readU8)(data, 104),
53
+ bump: (0, buffer_1.readU8)(data, 105),
54
+ readAumAccountCount: (0, buffer_1.readU8)(data, 106),
55
+ };
56
+ }
57
+ function deserializeLendStvPosition(data) {
58
+ if (data.length < constants_1.STV_POSITION_SIZE) {
59
+ throw new Error(`StvPosition data too short: ${data.length} < ${constants_1.STV_POSITION_SIZE}`);
60
+ }
61
+ if (!data.subarray(0, 8).equals(constants_1.DISC_STV_POSITION)) {
62
+ throw new Error(`Invalid StvPosition discriminator`);
63
+ }
64
+ return (0, strategy_interface_1.deserializeStvPosition)(data);
65
+ }
66
+ function deserializeManagerRole(data) {
67
+ if (data.length < constants_1.MANAGER_ROLE_SIZE) {
68
+ throw new Error(`ManagerRole data too short: ${data.length} < ${constants_1.MANAGER_ROLE_SIZE}`);
69
+ }
70
+ if (!data.subarray(0, 8).equals(constants_1.DISC_MANAGER_ROLE)) {
71
+ throw new Error(`Invalid ManagerRole discriminator`);
72
+ }
73
+ return {
74
+ strategyState: (0, buffer_1.readPubkey)(data, 8),
75
+ manager: (0, buffer_1.readPubkey)(data, 40),
76
+ bump: (0, buffer_1.readU8)(data, 72),
77
+ };
78
+ }
79
+ // ---------------------------------------------------------------------------
80
+ // Fetch helpers
81
+ // ---------------------------------------------------------------------------
82
+ async function fetchStrategyState(connection, baseMint, programId = constants_1.PROGRAM_ID) {
83
+ const [pda] = (0, pda_1.deriveStrategyState)(baseMint, programId);
84
+ const info = await connection.getAccountInfo(pda);
85
+ if (!info) {
86
+ throw new Error(`StrategyState not found for mint ${baseMint.toBase58()}`);
87
+ }
88
+ return deserializeStrategyState(info.data);
89
+ }
90
+ async function fetchStrategyStateByAddress(connection, address) {
91
+ const info = await connection.getAccountInfo(address);
92
+ if (!info)
93
+ throw new Error(`StrategyState not found at ${address.toBase58()}`);
94
+ return deserializeStrategyState(info.data);
95
+ }
96
+ async function fetchProtocolVault(connection, strategyState, index, programId = constants_1.PROGRAM_ID) {
97
+ const [pda] = (0, pda_1.deriveProtocolVault)(strategyState, index, programId);
98
+ const info = await connection.getAccountInfo(pda);
99
+ if (!info) {
100
+ throw new Error(`ProtocolVault not found at index ${index} for ${strategyState.toBase58()}`);
101
+ }
102
+ return deserializeProtocolVault(info.data);
103
+ }
104
+ async function fetchAllProtocolVaults(connection, strategyState, protocolCount, programId = constants_1.PROGRAM_ID) {
105
+ if (protocolCount === 0)
106
+ return [];
107
+ const pdas = [];
108
+ for (let i = 0; i < protocolCount; i++) {
109
+ const [pda] = (0, pda_1.deriveProtocolVault)(strategyState, i, programId);
110
+ pdas.push(pda);
111
+ }
112
+ const infos = await connection.getMultipleAccountsInfo(pdas);
113
+ const out = [];
114
+ for (let i = 0; i < pdas.length; i++) {
115
+ const info = infos[i];
116
+ if (!info) {
117
+ throw new Error(`ProtocolVault ${i} missing at ${pdas[i].toBase58()}`);
118
+ }
119
+ out.push([pdas[i], deserializeProtocolVault(info.data)]);
120
+ }
121
+ return out;
122
+ }
123
+ async function fetchLendStvPosition(connection, stv, programId = constants_1.PROGRAM_ID) {
124
+ const [pda] = (0, pda_1.deriveStvPosition)(stv, programId);
125
+ const info = await connection.getAccountInfo(pda);
126
+ if (!info)
127
+ throw new Error(`StvPosition not found for stv ${stv.toBase58()}`);
128
+ return deserializeLendStvPosition(info.data);
129
+ }
130
+ async function fetchManagerRole(connection, strategyState, manager, programId = constants_1.PROGRAM_ID) {
131
+ const [pda] = (0, pda_1.deriveManagerRole)(strategyState, manager, programId);
132
+ const info = await connection.getAccountInfo(pda);
133
+ if (!info)
134
+ return null;
135
+ return deserializeManagerRole(info.data);
136
+ }
@@ -0,0 +1,22 @@
1
+ import { PublicKey } from "@solana/web3.js";
2
+ export type AdapterKind = "kamino" | "jupiter-lend";
3
+ export interface AdapterMeta {
4
+ kind: AdapterKind;
5
+ programId: PublicKey;
6
+ readAumAccountCount: number;
7
+ }
8
+ export declare const KAMINO_ADAPTER: AdapterMeta;
9
+ export declare const JUPITER_LEND_ADAPTER: AdapterMeta;
10
+ export declare const ADAPTERS: Record<AdapterKind, AdapterMeta>;
11
+ export interface RegisterAdapterParams {
12
+ protocolState: PublicKey;
13
+ readAumAccountCount: number;
14
+ }
15
+ /** Kamino: protocol_state = vault_state, count = 2. */
16
+ export declare function buildRegisterKaminoParams(vaultState: PublicKey): RegisterAdapterParams;
17
+ /** Jupiter Lend: protocol_state = lending, count = 4. */
18
+ export declare function buildRegisterJupLendParams(lending: PublicKey): RegisterAdapterParams;
19
+ /** Kamino: [vault_state, kv_token_ata]. */
20
+ export declare function resolveKaminoReadAumAccounts(vaultState: PublicKey, kvTokenAta: PublicKey): PublicKey[];
21
+ /** Jupiter Lend: [lending, rewards_rate_model, fToken_ata, fToken_mint]. */
22
+ export declare function resolveJupLendReadAumAccounts(lending: PublicKey, rewardsRateModel: PublicKey, ftokenAta: PublicKey, ftokenMint: PublicKey): PublicKey[];
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ADAPTERS = exports.JUPITER_LEND_ADAPTER = exports.KAMINO_ADAPTER = void 0;
4
+ exports.buildRegisterKaminoParams = buildRegisterKaminoParams;
5
+ exports.buildRegisterJupLendParams = buildRegisterJupLendParams;
6
+ exports.resolveKaminoReadAumAccounts = resolveKaminoReadAumAccounts;
7
+ exports.resolveJupLendReadAumAccounts = resolveJupLendReadAumAccounts;
8
+ const constants_1 = require("./constants");
9
+ exports.KAMINO_ADAPTER = {
10
+ kind: "kamino",
11
+ programId: constants_1.KAMINO_ADAPTER_PROGRAM_ID,
12
+ readAumAccountCount: constants_1.KAMINO_READ_AUM_ACCOUNT_COUNT,
13
+ };
14
+ exports.JUPITER_LEND_ADAPTER = {
15
+ kind: "jupiter-lend",
16
+ programId: constants_1.JUPITER_LEND_ADAPTER_PROGRAM_ID,
17
+ readAumAccountCount: constants_1.JUPITER_LEND_READ_AUM_ACCOUNT_COUNT,
18
+ };
19
+ exports.ADAPTERS = {
20
+ kamino: exports.KAMINO_ADAPTER,
21
+ "jupiter-lend": exports.JUPITER_LEND_ADAPTER,
22
+ };
23
+ /** Kamino: protocol_state = vault_state, count = 2. */
24
+ function buildRegisterKaminoParams(vaultState) {
25
+ return {
26
+ protocolState: vaultState,
27
+ readAumAccountCount: constants_1.KAMINO_READ_AUM_ACCOUNT_COUNT,
28
+ };
29
+ }
30
+ /** Jupiter Lend: protocol_state = lending, count = 4. */
31
+ function buildRegisterJupLendParams(lending) {
32
+ return {
33
+ protocolState: lending,
34
+ readAumAccountCount: constants_1.JUPITER_LEND_READ_AUM_ACCOUNT_COUNT,
35
+ };
36
+ }
37
+ // ---------------------------------------------------------------------------
38
+ // read_aum account resolvers
39
+ //
40
+ // Order MUST match the adapter's read_aum layout. First slot = protocol_state
41
+ // (core-pinned). Adapter validates remaining slots from on-chain data.
42
+ // ---------------------------------------------------------------------------
43
+ /** Kamino: [vault_state, kv_token_ata]. */
44
+ function resolveKaminoReadAumAccounts(vaultState, kvTokenAta) {
45
+ return [vaultState, kvTokenAta];
46
+ }
47
+ /** Jupiter Lend: [lending, rewards_rate_model, fToken_ata, fToken_mint]. */
48
+ function resolveJupLendReadAumAccounts(lending, rewardsRateModel, ftokenAta, ftokenMint) {
49
+ return [lending, rewardsRateModel, ftokenAta, ftokenMint];
50
+ }