@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.
- package/LICENSE +201 -0
- package/README.md +185 -404
- package/dist/common/ata.d.ts +26 -0
- package/dist/common/ata.js +48 -0
- package/dist/common/buffer.d.ts +15 -0
- package/dist/common/buffer.js +118 -0
- package/dist/common/connection.d.ts +13 -0
- package/dist/common/connection.js +2 -0
- package/dist/common/constants.d.ts +14 -0
- package/dist/common/constants.js +31 -0
- package/dist/common/index.d.ts +6 -0
- package/dist/common/index.js +28 -0
- package/dist/common/strategy-interface.d.ts +59 -0
- package/dist/common/strategy-interface.js +42 -0
- package/dist/elemental-lend/accounts.d.ts +103 -0
- package/dist/elemental-lend/accounts.js +354 -0
- package/dist/elemental-lend/constants.d.ts +25 -0
- package/dist/elemental-lend/constants.js +48 -0
- package/dist/elemental-lend/index.d.ts +8 -0
- package/dist/elemental-lend/index.js +24 -0
- package/dist/elemental-lend/instructions.d.ts +104 -0
- package/dist/elemental-lend/instructions.js +266 -0
- package/dist/elemental-lend/jupiter-lend.d.ts +91 -0
- package/dist/elemental-lend/jupiter-lend.js +189 -0
- package/dist/elemental-lend/kamino-vault.d.ts +173 -0
- package/dist/elemental-lend/kamino-vault.js +483 -0
- package/dist/elemental-lend/pda.d.ts +12 -0
- package/dist/elemental-lend/pda.js +24 -0
- package/dist/elemental-lend/protocol-actions.d.ts +56 -0
- package/dist/elemental-lend/protocol-actions.js +244 -0
- package/dist/elemental-lend/types.d.ts +113 -0
- package/dist/elemental-lend/types.js +2 -0
- package/dist/elemental-lend-v2/accounts.d.ts +14 -0
- package/dist/elemental-lend-v2/accounts.js +136 -0
- package/dist/elemental-lend-v2/adapters.d.ts +22 -0
- package/dist/elemental-lend-v2/adapters.js +50 -0
- package/dist/elemental-lend-v2/constants.d.ts +48 -0
- package/dist/elemental-lend-v2/constants.js +104 -0
- package/dist/elemental-lend-v2/index.d.ts +8 -0
- package/dist/elemental-lend-v2/index.js +24 -0
- package/dist/elemental-lend-v2/instructions.d.ts +96 -0
- package/dist/elemental-lend-v2/instructions.js +190 -0
- package/dist/elemental-lend-v2/lut.d.ts +20 -0
- package/dist/elemental-lend-v2/lut.js +65 -0
- package/dist/elemental-lend-v2/pda.d.ts +9 -0
- package/dist/elemental-lend-v2/pda.js +27 -0
- package/dist/elemental-lend-v2/types.d.ts +105 -0
- package/dist/elemental-lend-v2/types.js +2 -0
- package/dist/elemental-lend-v2/update-aum.d.ts +29 -0
- package/dist/elemental-lend-v2/update-aum.js +82 -0
- package/dist/index.d.ts +5 -3552
- package/dist/index.js +37 -4454
- package/dist/jlpd-strategy/accounts.d.ts +83 -0
- package/dist/jlpd-strategy/accounts.js +216 -0
- package/dist/jlpd-strategy/adapter.d.ts +81 -0
- package/dist/jlpd-strategy/adapter.js +118 -0
- package/dist/jlpd-strategy/base-to-base-swap.d.ts +74 -0
- package/dist/jlpd-strategy/base-to-base-swap.js +205 -0
- package/dist/jlpd-strategy/constants.d.ts +127 -0
- package/dist/jlpd-strategy/constants.js +174 -0
- package/dist/jlpd-strategy/fluid-view.d.ts +199 -0
- package/dist/jlpd-strategy/fluid-view.js +799 -0
- package/dist/jlpd-strategy/hedge-derived.d.ts +135 -0
- package/dist/jlpd-strategy/hedge-derived.js +231 -0
- package/dist/jlpd-strategy/hedge-instructions.d.ts +210 -0
- package/dist/jlpd-strategy/hedge-instructions.js +300 -0
- package/dist/jlpd-strategy/hedge-state.d.ts +88 -0
- package/dist/jlpd-strategy/hedge-state.js +110 -0
- package/dist/jlpd-strategy/index.d.ts +17 -0
- package/dist/jlpd-strategy/index.js +33 -0
- package/dist/jlpd-strategy/instructions.d.ts +159 -0
- package/dist/jlpd-strategy/instructions.js +234 -0
- package/dist/jlpd-strategy/jlp-borrow.d.ts +63 -0
- package/dist/jlpd-strategy/jlp-borrow.js +87 -0
- package/dist/jlpd-strategy/jlp-data.d.ts +166 -0
- package/dist/jlpd-strategy/jlp-data.js +611 -0
- package/dist/jlpd-strategy/jupusd-earn.d.ts +90 -0
- package/dist/jlpd-strategy/jupusd-earn.js +166 -0
- package/dist/jlpd-strategy/live-jlp-price.d.ts +46 -0
- package/dist/jlpd-strategy/live-jlp-price.js +267 -0
- package/dist/jlpd-strategy/pda.d.ts +13 -0
- package/dist/jlpd-strategy/pda.js +28 -0
- package/dist/jlpd-strategy/settle-yield.d.ts +45 -0
- package/dist/jlpd-strategy/settle-yield.js +113 -0
- package/dist/jlpd-strategy/swap-jlp.d.ts +198 -0
- package/dist/jlpd-strategy/swap-jlp.js +586 -0
- package/dist/jlpd-strategy/types.d.ts +101 -0
- package/dist/jlpd-strategy/types.js +29 -0
- package/dist/p-stv-core/accounts.d.ts +152 -0
- package/dist/p-stv-core/accounts.js +407 -0
- package/dist/p-stv-core/constants.d.ts +138 -0
- package/dist/p-stv-core/constants.js +181 -0
- package/dist/p-stv-core/events.d.ts +7 -0
- package/dist/p-stv-core/events.js +246 -0
- package/dist/p-stv-core/index.d.ts +11 -0
- package/dist/p-stv-core/index.js +27 -0
- package/dist/p-stv-core/instructions.d.ts +637 -0
- package/dist/p-stv-core/instructions.js +670 -0
- package/dist/p-stv-core/lut.d.ts +41 -0
- package/dist/p-stv-core/lut.js +81 -0
- package/dist/p-stv-core/pda.d.ts +30 -0
- package/dist/p-stv-core/pda.js +65 -0
- package/dist/p-stv-core/prices.d.ts +20 -0
- package/dist/p-stv-core/prices.js +77 -0
- package/dist/p-stv-core/remaining-accounts.d.ts +107 -0
- package/dist/p-stv-core/remaining-accounts.js +326 -0
- package/dist/p-stv-core/send-tx.d.ts +72 -0
- package/dist/p-stv-core/send-tx.js +290 -0
- package/dist/p-stv-core/sol-wrap.d.ts +34 -0
- package/dist/p-stv-core/sol-wrap.js +74 -0
- package/dist/p-stv-core/types.d.ts +361 -0
- package/dist/p-stv-core/types.js +2 -0
- package/package.json +56 -15
- package/dist/index.d.mts +0 -3552
- package/dist/index.mjs +0 -4363
|
@@ -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>;
|