@elmntl/jlpd-sdk 0.2.0 → 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 -4199
  52. package/dist/index.js +37 -5187
  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 -4199
  115. package/dist/index.mjs +0 -5090
@@ -0,0 +1,326 @@
1
+ "use strict";
2
+ /**
3
+ * Remaining accounts builders for p-STV Core instructions.
4
+ *
5
+ * These functions build the complete `remainingAccounts` arrays needed for
6
+ * deposit, claim_withdraw, and process_epoch instructions, pulling all the
7
+ * lend + protocol AUM + strategy pair + auto-route/unroute account building
8
+ * logic out of the frontend and into the SDK.
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.buildDepositContext = buildDepositContext;
12
+ exports.buildClaimWithdrawContext = buildClaimWithdrawContext;
13
+ exports.buildDepositToStrategyContext = buildDepositToStrategyContext;
14
+ exports.buildProcessEpochContext = buildProcessEpochContext;
15
+ const web3_js_1 = require("@solana/web3.js");
16
+ const pda_1 = require("../elemental-lend/pda");
17
+ const accounts_1 = require("../elemental-lend/accounts");
18
+ const jupiter_lend_1 = require("../elemental-lend/jupiter-lend");
19
+ const kamino_vault_1 = require("../elemental-lend/kamino-vault");
20
+ const ata_1 = require("../common/ata");
21
+ // ---------------------------------------------------------------------------
22
+ // Helpers
23
+ // ---------------------------------------------------------------------------
24
+ const DEFAULT_PUBKEY = web3_js_1.PublicKey.default;
25
+ const SPL_TOKEN_PROGRAM = new web3_js_1.PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
26
+ /** Resolve the effective token program from a VaultInfo. Falls back to SPL Token. */
27
+ function resolveTokenProgram(vault) {
28
+ return vault.tokenProgram ?? SPL_TOKEN_PROGRAM;
29
+ }
30
+ const STRATEGY_STATE_SEED = Buffer.from("strategy_state");
31
+ const POSITION_SEED = Buffer.from("position");
32
+ function isDefault(pubkey) {
33
+ return pubkey.equals(DEFAULT_PUBKEY);
34
+ }
35
+ /**
36
+ * Build the 4 fixed lend accounts for value-movement paths (deposit, claim_withdraw,
37
+ * deposit_to_strategy, withdraw_from_strategy):
38
+ * [lendProgram(ro), lendStrategyState(w), lendPosition(w), lendBaseAta(w)]
39
+ *
40
+ * All three data accounts are writable on these paths because sweep/unsweep CPIs
41
+ * (lend.rs:341-344) write all three.
42
+ *
43
+ * `tokenProgram` MUST match the base-mint's token program. The on-chain
44
+ * check_lend_base_ata (lend.rs:61) derives the expected ATA using
45
+ * [strategy_state, token_program, base_mint] and rejects a mismatch.
46
+ */
47
+ function buildFixedLendAccounts(lendProgram, baseMint, stvAddress, tokenProgram) {
48
+ const [lendStrategyState] = (0, pda_1.findStrategyStatePda)(baseMint, lendProgram);
49
+ const [lendPosition] = (0, pda_1.findStvPositionPda)(stvAddress, lendProgram);
50
+ const lendBaseAta = (0, ata_1.findAta)(baseMint, lendStrategyState, tokenProgram);
51
+ return {
52
+ lendStrategyState,
53
+ accounts: [
54
+ { pubkey: lendProgram, isSigner: false, isWritable: false },
55
+ { pubkey: lendStrategyState, isSigner: false, isWritable: true },
56
+ { pubkey: lendPosition, isSigner: false, isWritable: true },
57
+ { pubkey: lendBaseAta, isSigner: false, isWritable: true },
58
+ ],
59
+ };
60
+ }
61
+ /**
62
+ * Build the 4 fixed lend accounts for the process_epoch (NAV-refresh) path:
63
+ * [lendProgram(ro), lendStrategyState(w), lendPosition(ro), lendBaseAta(ro)]
64
+ *
65
+ * `update_lend_aum` (lend.rs:264-311) only writes `lend_strategy_state`; it passes
66
+ * `lend_base_ata` and protocol accounts as readonly, and never touches `lend_stv_position`
67
+ * in the CPI at all. Marking `lend_stv_position` and `lend_base_ata` writable here would
68
+ * consume extra write-lock slots and can cause AccountNotWritable failures on read-only
69
+ * accounts. Do NOT use for deposit/claim/sweep paths — use `buildFixedLendAccounts`.
70
+ */
71
+ function buildFixedLendAccountsForEpoch(lendProgram, baseMint, stvAddress, tokenProgram) {
72
+ const [lendStrategyState] = (0, pda_1.findStrategyStatePda)(baseMint, lendProgram);
73
+ const [lendPosition] = (0, pda_1.findStvPositionPda)(stvAddress, lendProgram);
74
+ const lendBaseAta = (0, ata_1.findAta)(baseMint, lendStrategyState, tokenProgram);
75
+ return {
76
+ lendStrategyState,
77
+ accounts: [
78
+ { pubkey: lendProgram, isSigner: false, isWritable: false },
79
+ { pubkey: lendStrategyState, isSigner: false, isWritable: true },
80
+ { pubkey: lendPosition, isSigner: false, isWritable: false },
81
+ { pubkey: lendBaseAta, isSigner: false, isWritable: false },
82
+ ],
83
+ };
84
+ }
85
+ /**
86
+ * Build strategy pair accounts for deposit/claim paths: [strategy_state(w), stv_position(w)].
87
+ *
88
+ * Both writable: deposit and claim_withdraw CPIs mutate strategy_state (update_aum)
89
+ * and stv_position (deposit/withdraw shares). Do NOT use for process_epoch's lockPps
90
+ * call — that path only reads positions, never mutates them.
91
+ */
92
+ function buildStrategyPairAccounts(vault) {
93
+ if (isDefault(vault.strategy))
94
+ return [];
95
+ const [stratState] = web3_js_1.PublicKey.findProgramAddressSync([STRATEGY_STATE_SEED, vault.baseMint.toBuffer()], vault.strategy);
96
+ const [stratPos] = web3_js_1.PublicKey.findProgramAddressSync([POSITION_SEED, vault.address.toBuffer()], vault.strategy);
97
+ return [
98
+ { pubkey: stratState, isSigner: false, isWritable: true },
99
+ { pubkey: stratPos, isSigner: false, isWritable: true },
100
+ ];
101
+ }
102
+ /**
103
+ * Build strategy pair accounts for process_epoch lockPps (NAV-only read):
104
+ * [strategy_state(w), stv_position(ro)].
105
+ *
106
+ * process_epoch calls `update_strategy_and_read_position` (strategy.rs:190) which
107
+ * issues a CPI `update_aum` with `strategy_state_info` as WRITABLE
108
+ * (`InstructionAccount::writable`, strategy.rs:230). The CPI passes only
109
+ * [strategy_state, stv_account] — `stv_position` is read locally after the CPI but
110
+ * is NOT passed to the CPI, so it can stay readonly.
111
+ *
112
+ * Marking `strategy_state` writable is required: a CPI cannot upgrade a readonly
113
+ * account to writable, so a readonly `strategy_state` here will cause the transaction
114
+ * to fail with AccountNotWritable.
115
+ *
116
+ * Do NOT use for deposit, claim_withdraw, or deposit_to_strategy paths — use
117
+ * `buildStrategyPairAccounts` for those (both writable).
118
+ */
119
+ function buildStrategyPairAccountsForEpoch(vault) {
120
+ if (isDefault(vault.strategy))
121
+ return [];
122
+ const [stratState] = web3_js_1.PublicKey.findProgramAddressSync([STRATEGY_STATE_SEED, vault.baseMint.toBuffer()], vault.strategy);
123
+ const [stratPos] = web3_js_1.PublicKey.findProgramAddressSync([POSITION_SEED, vault.address.toBuffer()], vault.strategy);
124
+ return [
125
+ { pubkey: stratState, isSigner: false, isWritable: true },
126
+ { pubkey: stratPos, isSigner: false, isWritable: false },
127
+ ];
128
+ }
129
+ // ---------------------------------------------------------------------------
130
+ // Context Builders
131
+ // ---------------------------------------------------------------------------
132
+ /**
133
+ * Build the complete remaining_accounts for a deposit instruction.
134
+ *
135
+ * Layout: [4 lend, N protocol_aum, M*2+P strategy_pairs, K auto_route]
136
+ *
137
+ * - If lend is active, derives lend PDAs and fetches protocol AUM accounts
138
+ * - Builds strategy pair accounts for each active strategy
139
+ * - If USDC + Jupiter Lend registered, appends auto-route accounts
140
+ * - Checks for stale kVaults (returned in preInstructions once invest ix is available)
141
+ */
142
+ async function buildDepositContext(connection, vault, payer) {
143
+ const remainingAccounts = [];
144
+ const preInstructions = [];
145
+ let protocolAumCount = 0;
146
+ const tokenProgram = resolveTokenProgram(vault);
147
+ // 1. Lend accounts (if active)
148
+ if (!isDefault(vault.lendProgram)) {
149
+ const { accounts: lendAccounts, lendStrategyState } = buildFixedLendAccounts(vault.lendProgram, vault.baseMint, vault.address, tokenProgram);
150
+ remainingAccounts.push(...lendAccounts);
151
+ // Single fetch of LendStrategyState — used for both protocol AUM
152
+ // accounts and kVault staleness check.
153
+ const lendState = await (0, accounts_1.fetchLendStrategyState)(connection, vault.baseMint, vault.lendProgram).catch(() => null);
154
+ if (lendState) {
155
+ // Protocol AUM accounts — ALL registered protocols must be present.
156
+ // buildProtocolAccountsForAum derives canonical ATAs even for uninitialized
157
+ // positions; the on-chain handler values those as zero (update_aum.rs:291).
158
+ const protocolAccounts = await (0, accounts_1.buildProtocolAccountsForAum)(connection, lendState, lendStrategyState, tokenProgram);
159
+ protocolAumCount = protocolAccounts.length;
160
+ remainingAccounts.push(...protocolAccounts);
161
+ // Check kVault staleness — prepend invest ix if stale
162
+ try {
163
+ const protocolKeys = lendState.protocols
164
+ .filter((p) => !isDefault(p));
165
+ // Need a payer for the invest ix — will be set by the caller
166
+ const investIxs = payer ? await (0, kamino_vault_1.buildKaminoInvestIxsIfStale)(connection, payer, vault.baseMint, protocolKeys) : [];
167
+ preInstructions.push(...investIxs);
168
+ }
169
+ catch {
170
+ // Skip if staleness check fails
171
+ }
172
+ }
173
+ }
174
+ // 2. Strategy pair accounts (2 per strategy: state + position)
175
+ const strategyAccounts = buildStrategyPairAccounts(vault);
176
+ remainingAccounts.push(...strategyAccounts);
177
+ // 3. Auto-route to Jupiter Lend (for any asset with a configured pool)
178
+ let autoRouteCount = 0;
179
+ const jupPool = jupiter_lend_1.JUP_LEND_POOLS[vault.baseMint.toBase58()];
180
+ if (!isDefault(vault.lendProgram) && jupPool) {
181
+ try {
182
+ const [lendSS] = (0, pda_1.findStrategyStatePda)(vault.baseMint, vault.lendProgram);
183
+ const strategyBaseAta = (0, ata_1.findAta)(vault.baseMint, lendSS, tokenProgram);
184
+ const strategyFtokenAta = (0, ata_1.findAta)(jupPool.fTokenMint, lendSS, tokenProgram);
185
+ const autoRouteAccounts = (0, jupiter_lend_1.buildJupLendAutoRouteAccounts)(jupPool, lendSS, strategyBaseAta, strategyFtokenAta);
186
+ autoRouteCount = autoRouteAccounts.length;
187
+ for (const acc of autoRouteAccounts) {
188
+ remainingAccounts.push({ ...acc, isSigner: false });
189
+ }
190
+ }
191
+ catch {
192
+ // Skip auto-route if account resolution fails
193
+ }
194
+ }
195
+ // 4. Strategy program (after auto-route, for CPI resolution)
196
+ // Must be in the transaction but NOT counted as auto-route or strategy pairs.
197
+ if (!isDefault(vault.strategy)) {
198
+ remainingAccounts.push({ pubkey: vault.strategy, isSigner: false, isWritable: false });
199
+ }
200
+ return { remainingAccounts, protocolAumCount, autoRouteCount, preInstructions };
201
+ }
202
+ /**
203
+ * Build the complete remaining_accounts for a claim_withdraw instruction.
204
+ *
205
+ * Layout: [4 lend, K auto_unroute]
206
+ *
207
+ * - If lend is active, derives lend PDAs
208
+ * - If USDC + Jupiter Lend, appends auto-unroute accounts
209
+ */
210
+ async function buildClaimWithdrawContext(connection, vault) {
211
+ const remainingAccounts = [];
212
+ const preInstructions = [];
213
+ let autoUnrouteCount = 0;
214
+ let protocolAumCount = 0;
215
+ const tokenProgram = resolveTokenProgram(vault);
216
+ if (!isDefault(vault.lendProgram)) {
217
+ const { accounts: lendAccounts, lendStrategyState } = buildFixedLendAccounts(vault.lendProgram, vault.baseMint, vault.address, tokenProgram);
218
+ remainingAccounts.push(...lendAccounts);
219
+ // Protocol-AUM accounts (between fixed lend and auto-unroute) — feed the
220
+ // pre-unsweep update_aum refresh. The on-chain lend update_aum rejects an
221
+ // incomplete tail, so these MUST cover the strategy's full protocol set.
222
+ // Canonical ATAs are derived even for uninitialized positions (valued as zero).
223
+ const lendState = await (0, accounts_1.fetchLendStrategyState)(connection, vault.baseMint, vault.lendProgram).catch(() => null);
224
+ if (lendState) {
225
+ const protocolAccounts = await (0, accounts_1.buildProtocolAccountsForAum)(connection, lendState, lendStrategyState, tokenProgram);
226
+ protocolAumCount = protocolAccounts.length;
227
+ remainingAccounts.push(...protocolAccounts);
228
+ }
229
+ // Auto-unroute from Jupiter Lend (for any asset with a configured pool)
230
+ const jupPoolForUnroute = jupiter_lend_1.JUP_LEND_POOLS[vault.baseMint.toBase58()];
231
+ if (jupPoolForUnroute) {
232
+ try {
233
+ const lendBaseAta = (0, ata_1.findAta)(vault.baseMint, lendStrategyState, tokenProgram);
234
+ const strategyFtokenAta = (0, ata_1.findAta)(jupPoolForUnroute.fTokenMint, lendStrategyState, tokenProgram);
235
+ const autoUnrouteAccounts = (0, jupiter_lend_1.buildJupLendAutoUnrouteAccounts)(jupPoolForUnroute, lendStrategyState, strategyFtokenAta, lendBaseAta);
236
+ autoUnrouteCount = autoUnrouteAccounts.length;
237
+ remainingAccounts.push(...autoUnrouteAccounts.map(a => ({ ...a, isSigner: false })));
238
+ }
239
+ catch {
240
+ // Skip auto-unroute if resolution fails
241
+ }
242
+ }
243
+ }
244
+ return { remainingAccounts, autoUnrouteCount, protocolAumCount, preInstructions };
245
+ }
246
+ /**
247
+ * Build the complete remaining_accounts for a deposit_to_strategy instruction.
248
+ *
249
+ * Layout: [4 fixed lend, N protocol_aum, K auto_unroute]
250
+ *
251
+ * - Fixed lend accounts (if lend is active)
252
+ * - Protocol AUM accounts: required by the on-chain handler to refresh lend
253
+ * valuation via update_lend_aum before the reserved_base liquidity lock check
254
+ * - Auto-unroute accounts: forwarded to the lend withdraw CPI for unsweep
255
+ *
256
+ * The `connection` parameter is required to fetch LendStrategyState and
257
+ * resolve protocol AUM accounts.
258
+ */
259
+ async function buildDepositToStrategyContext(connection, vault) {
260
+ const remainingAccounts = [];
261
+ let protocolAumCount = 0;
262
+ let autoUnrouteCount = 0;
263
+ const tokenProgram = resolveTokenProgram(vault);
264
+ if (!isDefault(vault.lendProgram)) {
265
+ const { accounts: lendAccounts, lendStrategyState } = buildFixedLendAccounts(vault.lendProgram, vault.baseMint, vault.address, tokenProgram);
266
+ remainingAccounts.push(...lendAccounts);
267
+ // Fetch LendStrategyState once — used for protocol AUM resolution.
268
+ // ALL registered protocols must be present; derive canonical ATAs even for
269
+ // uninitialized positions (the on-chain handler values them as zero).
270
+ const lendState = await (0, accounts_1.fetchLendStrategyState)(connection, vault.baseMint, vault.lendProgram).catch(() => null);
271
+ if (lendState) {
272
+ const protocolAccounts = await (0, accounts_1.buildProtocolAccountsForAum)(connection, lendState, lendStrategyState, tokenProgram);
273
+ protocolAumCount = protocolAccounts.length;
274
+ remainingAccounts.push(...protocolAccounts);
275
+ }
276
+ // Auto-unroute from Jupiter Lend (for any asset with a configured pool)
277
+ const jupPoolForUnroute = jupiter_lend_1.JUP_LEND_POOLS[vault.baseMint.toBase58()];
278
+ if (jupPoolForUnroute) {
279
+ try {
280
+ const lendBaseAta = (0, ata_1.findAta)(vault.baseMint, lendStrategyState, tokenProgram);
281
+ const strategyFtokenAta = (0, ata_1.findAta)(jupPoolForUnroute.fTokenMint, lendStrategyState, tokenProgram);
282
+ const autoUnrouteAccounts = (0, jupiter_lend_1.buildJupLendAutoUnrouteAccounts)(jupPoolForUnroute, lendStrategyState, strategyFtokenAta, lendBaseAta);
283
+ autoUnrouteCount = autoUnrouteAccounts.length;
284
+ remainingAccounts.push(...autoUnrouteAccounts.map(a => ({ ...a, isSigner: false })));
285
+ }
286
+ catch {
287
+ // Skip auto-unroute if resolution fails
288
+ }
289
+ }
290
+ }
291
+ return { remainingAccounts, protocolAumCount, autoUnrouteCount, preInstructions: [] };
292
+ }
293
+ /**
294
+ * Build the complete remaining_accounts for a process_epoch instruction.
295
+ *
296
+ * @param phase - 'lockPps': needs lend + protocol AUM + strategy pairs for NAV.
297
+ * 'advance': empty remaining_accounts.
298
+ */
299
+ async function buildProcessEpochContext(connection, vault, phase) {
300
+ if (phase === "advance") {
301
+ return { remainingAccounts: [], protocolAumCount: 0, preInstructions: [] };
302
+ }
303
+ // lockPps: lend + protocol AUM (for NAV update_aum refresh) + strategy pairs.
304
+ // No auto-route — process_epoch does not sweep to Jupiter Lend.
305
+ const tokenProgram = resolveTokenProgram(vault);
306
+ const remainingAccounts = [];
307
+ const preInstructions = [];
308
+ let protocolAumCount = 0;
309
+ if (!isDefault(vault.lendProgram)) {
310
+ // Use epoch-specific fixed lend accounts: lend_strategy_state writable,
311
+ // lend_stv_position and lend_base_ata readonly (update_lend_aum does not write them).
312
+ const { accounts: lendAccounts, lendStrategyState } = buildFixedLendAccountsForEpoch(vault.lendProgram, vault.baseMint, vault.address, tokenProgram);
313
+ remainingAccounts.push(...lendAccounts);
314
+ // ALL registered protocols must be present; derive canonical ATAs even for
315
+ // uninitialized positions (the on-chain handler values them as zero).
316
+ const lendState = await (0, accounts_1.fetchLendStrategyState)(connection, vault.baseMint, vault.lendProgram);
317
+ const protocolAccounts = await (0, accounts_1.buildProtocolAccountsForAum)(connection, lendState, lendStrategyState, tokenProgram);
318
+ protocolAumCount = protocolAccounts.length;
319
+ remainingAccounts.push(...protocolAccounts);
320
+ }
321
+ // Strategy pairs for process_epoch: strategy_state WRITABLE (update_aum CPI writes it),
322
+ // stv_position readonly (only read locally after CPI, not passed into the CPI itself).
323
+ const strategyAccounts = buildStrategyPairAccountsForEpoch(vault);
324
+ remainingAccounts.push(...strategyAccounts);
325
+ return { remainingAccounts, protocolAumCount, preInstructions };
326
+ }
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Smart transaction builder and sender.
3
+ *
4
+ * Features:
5
+ * - Simulates to get exact compute units, adds 5% buffer
6
+ * - Fetches priority fee from Helius (medium tier)
7
+ * - Pre-checks size to decide legacy vs versioned tx with LUT (no double-sign)
8
+ * - Uses lastValidBlockHeight for reliable confirmation
9
+ * - Parallel fetches where possible
10
+ */
11
+ import { AddressLookupTableAccount, Connection, PublicKey, Transaction, TransactionInstruction, VersionedTransaction } from "@solana/web3.js";
12
+ /**
13
+ * Default LUTs for Elemental Vaults.
14
+ * These are fetched in parallel and merged for every versioned transaction.
15
+ *
16
+ * After creating new LUTs with `scripts/create-luts.ts --create`,
17
+ * replace these placeholder addresses with the real ones.
18
+ */
19
+ export declare const DEFAULT_LUT_ADDRESSES: {
20
+ /** Elemental Lend (Kamino + Jupiter Lend + protocol infra) */
21
+ lend: PublicKey;
22
+ /** p-STV Core (vaults, evMints, vault ATAs, config) */
23
+ stv: PublicKey;
24
+ /** JLPD Strategy (config, strategy states, positions, JLP, oracles) */
25
+ jlpd: PublicKey;
26
+ };
27
+ /**
28
+ * Wallet signing callback. Accepts either a legacy `Transaction` or a
29
+ * `VersionedTransaction` and returns the same type, fully signed.
30
+ *
31
+ * Generic over `T` so callers don't lose the input type when chaining.
32
+ */
33
+ export type SignTransactionFn = <T extends Transaction | VersionedTransaction>(tx: T) => Promise<T>;
34
+ /**
35
+ * Minimal structural type accepted by `sendSmartTx` / `simulateSmartTx`.
36
+ * Using a structural subset of `Connection` lets callers pass any web3.js
37
+ * version without nominal type mismatches.
38
+ */
39
+ export type SmartTxConnection = Pick<Connection, "getLatestBlockhash" | "getAddressLookupTable" | "simulateTransaction" | "sendRawTransaction" | "confirmTransaction">;
40
+ export interface SmartTxOptions {
41
+ /** Single LUT address (deprecated — use additionalLuts or DEFAULT_LUT_ADDRESSES) */
42
+ lutAddress?: PublicKey;
43
+ /** Additional pre-fetched ALTs to merge (e.g. Jupiter ALTs) */
44
+ additionalLuts?: AddressLookupTableAccount[];
45
+ /** Skip priority fee fetch (use 0) */
46
+ noPriorityFee?: boolean;
47
+ /** Custom compute unit limit (skips simulation) */
48
+ computeUnits?: number;
49
+ /** Force legacy transaction (no ALTs). Use when CPI programs appear as regular accounts. */
50
+ forceLegacy?: boolean;
51
+ /**
52
+ * RPC URL — required to enable the Helius `getPriorityFeeEstimate` shortcut.
53
+ * If omitted, the SDK falls back to a flat `FALLBACK_PRIORITY_FEE` and skips
54
+ * the Helius call entirely. Avoid reaching into `connection._rpcEndpoint`.
55
+ */
56
+ rpcUrl?: string;
57
+ }
58
+ /**
59
+ * Build, simulate, and send a transaction with optimal compute budget.
60
+ *
61
+ * 1. Fetches blockhash + LUT + priority fee in parallel
62
+ * 2. Pre-checks serialized size to choose legacy vs versioned
63
+ * 3. Simulates to get exact CU, adds 10% buffer
64
+ * 4. Prepends ComputeBudget instructions
65
+ * 5. Signs and sends with lastValidBlockHeight confirmation
66
+ */
67
+ export declare function sendSmartTx(connection: SmartTxConnection, instructions: TransactionInstruction[], payer: PublicKey, signTransaction: SignTransactionFn, optionsOrLut?: PublicKey | SmartTxOptions): Promise<string>;
68
+ /**
69
+ * Simulate a transaction without signing. Returns true if simulation succeeds.
70
+ * Use this to gate combined-tx attempts before asking the wallet to sign.
71
+ */
72
+ export declare function simulateSmartTx(connection: SmartTxConnection, instructions: TransactionInstruction[], payer: PublicKey, optionsOrLut?: PublicKey | SmartTxOptions): Promise<boolean>;