@elmntl/jlpd-sdk 0.2.0 → 0.13.5

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 +206 -0
  66. package/dist/jlpd-strategy/hedge-instructions.js +296 -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,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_AUM_HARD_BREAKER_BPS = exports.DEFAULT_SOFT_BREAKER_TOL_BPS = exports.MAX_BREAKER_BPS = void 0;
4
+ exports.softBreakerTolBpsResolved = softBreakerTolBpsResolved;
5
+ exports.aumHardBreakerBpsResolved = aumHardBreakerBpsResolved;
6
+ /** Upper bound for either divergence-breaker band (100%). Only bounds an admin typo. */
7
+ exports.MAX_BREAKER_BPS = 10000;
8
+ /** Default soft-breaker band (1%), applied when the stored field reads `0` or `> MAX_BREAKER_BPS`. */
9
+ exports.DEFAULT_SOFT_BREAKER_TOL_BPS = 100;
10
+ /** Default hard-breaker band (3%), applied when the stored field reads `0` or `> MAX_BREAKER_BPS`. */
11
+ exports.DEFAULT_AUM_HARD_BREAKER_BPS = 300;
12
+ /**
13
+ * Resolved soft-breaker band: the stored value, or `DEFAULT_SOFT_BREAKER_TOL_BPS`
14
+ * when the stored value is `0` or exceeds `MAX_BREAKER_BPS` — mirrors
15
+ * `JlpdConfig::soft_breaker_tol_bps_resolved` exactly.
16
+ */
17
+ function softBreakerTolBpsResolved(config) {
18
+ const v = config.softBreakerTolBps;
19
+ return v === 0 || v > exports.MAX_BREAKER_BPS ? exports.DEFAULT_SOFT_BREAKER_TOL_BPS : v;
20
+ }
21
+ /**
22
+ * Resolved hard-breaker band: the stored value, or `DEFAULT_AUM_HARD_BREAKER_BPS`
23
+ * when the stored value is `0` or exceeds `MAX_BREAKER_BPS` — mirrors
24
+ * `JlpdConfig::aum_hard_breaker_bps_resolved` exactly.
25
+ */
26
+ function aumHardBreakerBpsResolved(config) {
27
+ const v = config.aumHardBreakerBps;
28
+ return v === 0 || v > exports.MAX_BREAKER_BPS ? exports.DEFAULT_AUM_HARD_BREAKER_BPS : v;
29
+ }
@@ -0,0 +1,152 @@
1
+ import { PublicKey } from "@solana/web3.js";
2
+ import BN from "bn.js";
3
+ import type { SolanaConnection } from "../common/connection";
4
+ import { GlobalConfig, Stv, WithdrawRequest, DelayedDepositRequest, ManagerRole } from "./types";
5
+ /**
6
+ * GlobalConfig — singleton protocol registry. Total 56 bytes.
7
+ *
8
+ * Layout (offsets include the 8-byte discriminator):
9
+ * [ 0.. 8] discriminator (sha256("account:GlobalConfig")[..8])
10
+ * [ 8.. 40] admin Pubkey
11
+ * [ 40.. 48] nextVaultId u64
12
+ * [ 48.. 50] flags u16 (CFG_FLAG_*)
13
+ * [ 50.. 51] version u8
14
+ * [ 51.. 52] bump u8
15
+ * [ 52.. 56] _padding [u8; 4]
16
+ */
17
+ export declare function deserializeGlobalConfig(data: Buffer): GlobalConfig;
18
+ /**
19
+ * STV — per-vault state. Total 664 bytes (v2 layout).
20
+ *
21
+ * v2 layout (offsets include the 8-byte Anchor-compatible discriminator).
22
+ * All compile-time asserts in p-stv-core/programs/p-stv-core/src/state/stv.rs
23
+ * are the canonical source of truth; offsets here are copied from those asserts.
24
+ *
25
+ * [ 0.. 8] discriminator (sha256("account:Stv")[..8])
26
+ * [ 8.. 40] baseMint Pubkey (_OFFSET_BASE_MINT == 8)
27
+ * [ 40.. 72] evMint Pubkey (_OFFSET_EV_MINT == 40)
28
+ * [ 72..104] strategy Pubkey (_OFFSET_STRATEGY == 72; immutable)
29
+ * [104..136] feeReceiver Pubkey (_OFFSET_FEE_RECEIVER == 104)
30
+ * [136..168] lendProgram Pubkey (_OFFSET_LEND_PROGRAM == 136; zero = inactive)
31
+ * [168..200] vaultAta Pubkey (_OFFSET_VAULT_ATA == 168; canonical ATA)
32
+ * [200..232] coldAdmin Pubkey (_OFFSET_COLD_ADMIN == 200; per-vault cold admin, never zero on v2)
33
+ * [232..264] pendingAdmin Pubkey (_OFFSET_PENDING_ADMIN == 232; zero = no rotation in progress)
34
+ * [264..296] childVaults[4] [u64; 4] (_OFFSET_CHILD_VAULTS == 264; MAX_CHILD_VAULTS = 4)
35
+ * [296..304] vaultId u64 (_OFFSET_VAULT_ID == 296)
36
+ * [304..312] reservedBase u64
37
+ * [312..320] requestedShares u64 (shares pending in escrow)
38
+ * [320..328] vaultCapacity u64 (0 = uncapped)
39
+ * [328..336] minDeposit u64
40
+ * [336..344] hwm u64 (high-water mark for perf fees)
41
+ * [344..352] lastFeeTs u64
42
+ * [352..360] epochPps u64 (locked PPS for current epoch claims)
43
+ * [360..368] lastNav u64 (snapshot for rate-limit window)
44
+ * [368..376] dailyWithdrawnBase u64 (rate-limit accumulator)
45
+ * [376..380] nextEpochTs u32
46
+ * [380..384] epochSec u32
47
+ * [384..388] currentEpochId u32
48
+ * [388..392] pendingWithdrawals u32
49
+ * [392..396] withdrawWindowStart u32
50
+ * [396..398] mgmtFeeBps u16
51
+ * [398..400] perfFeeBps u16
52
+ * [400..402] flags u16
53
+ * [402..404] dailyWithdrawLimitBps u16
54
+ * [404..405] childVaultCount u8
55
+ * [405..406] version u8 (== 2 for v2 accounts)
56
+ * [406..407] bump u8
57
+ * [407..408] _padding [u8; 1]
58
+ * [408..410] depositFeeBps u16 (_OFFSET_DEPOSIT_FEE_BPS == 408)
59
+ * [410..412] withdrawalFeeBps u16 (_OFFSET_WITHDRAWAL_FEE_BPS == 410)
60
+ * [412..416] pendingDepositCount u32 (_OFFSET_PENDING_DEPOSIT_COUNT == 412)
61
+ * [416..424] pendingDepositBase u64 (_OFFSET_PENDING_DEPOSIT_BASE == 416)
62
+ * [424..456] feeReceiverEvAta Pubkey (_OFFSET_FEE_RECEIVER_EV_ATA == 424)
63
+ * [456..464] lockedSeedShares u64 (_OFFSET_LOCKED_SEED_SHARES == 456)
64
+ * [464..465] withdrawalMode u8 (_OFFSET_WITHDRAWAL_MODE == 464; 0=instant, 1=X, 2=X+1)
65
+ * [465..468] _reservedPad [u8; 3] (_OFFSET_RESERVED_PAD == 465; alignment before last_nav_ts)
66
+ * [468..472] lastNavTs u32 (_OFFSET_LAST_NAV_TS == 468; unix seconds; 0 = no epoch yet)
67
+ * [472..476] strategyStalenessThreshold u32 (_OFFSET_STRATEGY_STALENESS_THRESHOLD == 472; 0 = use default 24 h)
68
+ * [476..508] warmAdmin Pubkey (_OFFSET_WARM_ADMIN == 476; [0u8;32] = "follow cold" sentinel — resolve via warmAdminEffective())
69
+ * [508..664] _reserved [u8; 156] (_OFFSET_RESERVED == 508)
70
+ */
71
+ export declare function deserializeStv(data: Buffer): Stv;
72
+ /**
73
+ * Resolve the effective warm admin for an STV: the stored `warmAdmin`
74
+ * "follow cold" sentinel (`PublicKey.default`, i.e. `[0u8;32]`) resolves to
75
+ * `stv.coldAdmin` (cold). Mirrors the on-chain `Stv::warm_admin_effective()`
76
+ * helper (state/stv.rs) — every warm-gated on-chain auth check
77
+ * (`add_manager`, `remove_manager`, `override_claim_withdraw`,
78
+ * `trip_circuit_breaker`) routes through that same resolution, so this is
79
+ * the correct way to read `warmAdmin` off-chain too; never compare
80
+ * `stv.warmAdmin` directly against a candidate signer.
81
+ *
82
+ * PRE-DEPLOY CAVEAT: every STV on the currently-deployed mainnet program
83
+ * reads the sentinel (the field lives in a zeroed pre-upgrade reserved
84
+ * tail), so this always resolves to `stv.coldAdmin` until the program
85
+ * upgrade ships — which is the correct, safe answer either way (cold's
86
+ * power set is a superset of warm's).
87
+ */
88
+ export declare function warmAdminEffective(stv: Stv): PublicKey;
89
+ /**
90
+ * WithdrawRequest — per-(STV, user, epoch) withdraw escrow. Total 168 bytes.
91
+ *
92
+ * Layout (offsets include the 8-byte discriminator):
93
+ * [ 0.. 8] discriminator (sha256("account:WithdrawRequest")[..8])
94
+ * [ 8.. 40] stv Pubkey
95
+ * [ 40.. 72] user Pubkey
96
+ * [ 72.. 80] shares u64
97
+ * [ 80.. 88] pps u64 (locked at process_epoch time)
98
+ * [ 88.. 92] epochId u32
99
+ * [ 92.. 96] claimAvailableAfter u32 (unix seconds)
100
+ * [ 96.. 97] bump u8
101
+ * [ 97.. 98] version u8
102
+ * [ 98.. 99] requestFlags u8 (bit0 WR_FLAG_MIGRATE: 0=withdraw, 1=migrate)
103
+ * [ 99..104] _padding [u8; 5]
104
+ * [104..112] destVaultId u64 (migrate: dest STV vault_id; withdraw: 0)
105
+ * [112..120] minDestShares u64 (migrate: slippage floor; withdraw: 0)
106
+ * [120..168] _reserved0 [u8; 48]
107
+ */
108
+ export declare function deserializeWithdrawRequest(data: Buffer): WithdrawRequest;
109
+ /**
110
+ * WithdrawRequest kind from `requestFlags` bit 0.
111
+ * Returns `"migrate"` when WR_FLAG_MIGRATE (0x01) is set, else `"withdraw"`.
112
+ */
113
+ export declare function withdrawRequestKind(wr: WithdrawRequest): "withdraw" | "migrate";
114
+ /**
115
+ * DelayedDepositRequest — per-(STV, user, epoch) pending deposit. Total 152 bytes.
116
+ *
117
+ * Layout (offsets include the 8-byte discriminator):
118
+ * [ 0.. 8] discriminator (sha256("account:DelayedDepositRequest")[..8])
119
+ * [ 8.. 40] stv Pubkey
120
+ * [ 40.. 72] user Pubkey
121
+ * [ 72.. 80] amount u64
122
+ * [ 80.. 84] epochId u32 (offset_of == 80, asserted on-chain)
123
+ * [ 84.. 85] bump u8
124
+ * [ 85.. 86] version u8
125
+ * [ 86.. 88] _padding [u8; 2]
126
+ * [ 88..152] _reserved [u8; 64]
127
+ */
128
+ export declare function deserializeDelayedDepositRequest(data: Buffer): DelayedDepositRequest;
129
+ /**
130
+ * ManagerRole — per-(STV, manager) authorization record. Total 80 bytes.
131
+ *
132
+ * Layout (offsets include the 8-byte discriminator):
133
+ * [ 0.. 8] discriminator (sha256("account:ManagerRole")[..8] —
134
+ * shared with elemental-lend + jlpd-strategy)
135
+ * [ 8.. 40] stv Pubkey
136
+ * [ 40.. 72] manager Pubkey
137
+ * [ 72.. 73] bump u8
138
+ * [ 73.. 80] _padding [u8; 7]
139
+ */
140
+ export declare function deserializeManagerRole(data: Buffer): ManagerRole;
141
+ export declare function fetchGlobalConfig(connection: SolanaConnection, programId?: PublicKey): Promise<GlobalConfig>;
142
+ export declare function fetchStv(connection: SolanaConnection, vaultId: number | BN, programId?: PublicKey): Promise<Stv>;
143
+ export declare function fetchStvByAddress(connection: SolanaConnection, address: PublicKey): Promise<Stv>;
144
+ export declare function fetchWithdrawRequest(connection: SolanaConnection, stv: PublicKey, user: PublicKey, epochId: number, programId?: PublicKey): Promise<WithdrawRequest>;
145
+ export declare function fetchWithdrawRequestByAddress(connection: SolanaConnection, address: PublicKey): Promise<WithdrawRequest>;
146
+ export declare function fetchDelayedDepositRequest(connection: SolanaConnection, stv: PublicKey, user: PublicKey, epochId: number, programId?: PublicKey): Promise<DelayedDepositRequest>;
147
+ export declare function fetchDelayedDepositRequestByAddress(connection: SolanaConnection, address: PublicKey): Promise<DelayedDepositRequest>;
148
+ export declare function fetchAllStvs(connection: SolanaConnection, programId?: PublicKey): Promise<[PublicKey, Stv][]>;
149
+ export declare function fetchPendingWithdrawRequests(connection: SolanaConnection, stv: PublicKey, epochId: number, programId?: PublicKey): Promise<[PublicKey, WithdrawRequest][]>;
150
+ export declare function fetchPendingDelayedDepositRequests(connection: SolanaConnection, stv: PublicKey, epochId: number, programId?: PublicKey): Promise<[PublicKey, DelayedDepositRequest][]>;
151
+ export declare function fetchManagerRole(connection: SolanaConnection, stv: PublicKey, manager: PublicKey, programId?: PublicKey): Promise<ManagerRole | null>;
152
+ export declare function fetchManagersForStv(connection: SolanaConnection, stv: PublicKey, programId?: PublicKey): Promise<[PublicKey, ManagerRole][]>;
@@ -0,0 +1,407 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deserializeGlobalConfig = deserializeGlobalConfig;
4
+ exports.deserializeStv = deserializeStv;
5
+ exports.warmAdminEffective = warmAdminEffective;
6
+ exports.deserializeWithdrawRequest = deserializeWithdrawRequest;
7
+ exports.withdrawRequestKind = withdrawRequestKind;
8
+ exports.deserializeDelayedDepositRequest = deserializeDelayedDepositRequest;
9
+ exports.deserializeManagerRole = deserializeManagerRole;
10
+ exports.fetchGlobalConfig = fetchGlobalConfig;
11
+ exports.fetchStv = fetchStv;
12
+ exports.fetchStvByAddress = fetchStvByAddress;
13
+ exports.fetchWithdrawRequest = fetchWithdrawRequest;
14
+ exports.fetchWithdrawRequestByAddress = fetchWithdrawRequestByAddress;
15
+ exports.fetchDelayedDepositRequest = fetchDelayedDepositRequest;
16
+ exports.fetchDelayedDepositRequestByAddress = fetchDelayedDepositRequestByAddress;
17
+ exports.fetchAllStvs = fetchAllStvs;
18
+ exports.fetchPendingWithdrawRequests = fetchPendingWithdrawRequests;
19
+ exports.fetchPendingDelayedDepositRequests = fetchPendingDelayedDepositRequests;
20
+ exports.fetchManagerRole = fetchManagerRole;
21
+ exports.fetchManagersForStv = fetchManagersForStv;
22
+ const web3_js_1 = require("@solana/web3.js");
23
+ const buffer_1 = require("../common/buffer");
24
+ const constants_1 = require("./constants");
25
+ const pda_1 = require("./pda");
26
+ // ---------------------------------------------------------------------------
27
+ // Deserialization
28
+ //
29
+ // All offsets below INCLUDE the 8-byte Anchor account discriminator. Layout
30
+ // blocks above each parser show the field map; the helpers in
31
+ // `common/buffer.ts` validate that `offset + width <= data.length` so a
32
+ // drift between this file and the on-chain layout fails loudly with a
33
+ // `RangeError` rather than returning garbage.
34
+ // ---------------------------------------------------------------------------
35
+ /**
36
+ * GlobalConfig — singleton protocol registry. Total 56 bytes.
37
+ *
38
+ * Layout (offsets include the 8-byte discriminator):
39
+ * [ 0.. 8] discriminator (sha256("account:GlobalConfig")[..8])
40
+ * [ 8.. 40] admin Pubkey
41
+ * [ 40.. 48] nextVaultId u64
42
+ * [ 48.. 50] flags u16 (CFG_FLAG_*)
43
+ * [ 50.. 51] version u8
44
+ * [ 51.. 52] bump u8
45
+ * [ 52.. 56] _padding [u8; 4]
46
+ */
47
+ function deserializeGlobalConfig(data) {
48
+ if (data.length < constants_1.GLOBAL_CONFIG_SIZE) {
49
+ throw new Error(`GlobalConfig data too short: ${data.length} < ${constants_1.GLOBAL_CONFIG_SIZE}`);
50
+ }
51
+ const disc = data.subarray(0, 8);
52
+ if (!disc.equals(constants_1.DISC_GLOBAL_CONFIG)) {
53
+ throw new Error(`Invalid GlobalConfig discriminator`);
54
+ }
55
+ return {
56
+ admin: (0, buffer_1.readPubkey)(data, 8),
57
+ nextVaultId: (0, buffer_1.readU64)(data, 40),
58
+ flags: (0, buffer_1.readU16)(data, 48),
59
+ version: (0, buffer_1.readU8)(data, 50),
60
+ bump: (0, buffer_1.readU8)(data, 51),
61
+ };
62
+ }
63
+ /**
64
+ * STV — per-vault state. Total 664 bytes (v2 layout).
65
+ *
66
+ * v2 layout (offsets include the 8-byte Anchor-compatible discriminator).
67
+ * All compile-time asserts in p-stv-core/programs/p-stv-core/src/state/stv.rs
68
+ * are the canonical source of truth; offsets here are copied from those asserts.
69
+ *
70
+ * [ 0.. 8] discriminator (sha256("account:Stv")[..8])
71
+ * [ 8.. 40] baseMint Pubkey (_OFFSET_BASE_MINT == 8)
72
+ * [ 40.. 72] evMint Pubkey (_OFFSET_EV_MINT == 40)
73
+ * [ 72..104] strategy Pubkey (_OFFSET_STRATEGY == 72; immutable)
74
+ * [104..136] feeReceiver Pubkey (_OFFSET_FEE_RECEIVER == 104)
75
+ * [136..168] lendProgram Pubkey (_OFFSET_LEND_PROGRAM == 136; zero = inactive)
76
+ * [168..200] vaultAta Pubkey (_OFFSET_VAULT_ATA == 168; canonical ATA)
77
+ * [200..232] coldAdmin Pubkey (_OFFSET_COLD_ADMIN == 200; per-vault cold admin, never zero on v2)
78
+ * [232..264] pendingAdmin Pubkey (_OFFSET_PENDING_ADMIN == 232; zero = no rotation in progress)
79
+ * [264..296] childVaults[4] [u64; 4] (_OFFSET_CHILD_VAULTS == 264; MAX_CHILD_VAULTS = 4)
80
+ * [296..304] vaultId u64 (_OFFSET_VAULT_ID == 296)
81
+ * [304..312] reservedBase u64
82
+ * [312..320] requestedShares u64 (shares pending in escrow)
83
+ * [320..328] vaultCapacity u64 (0 = uncapped)
84
+ * [328..336] minDeposit u64
85
+ * [336..344] hwm u64 (high-water mark for perf fees)
86
+ * [344..352] lastFeeTs u64
87
+ * [352..360] epochPps u64 (locked PPS for current epoch claims)
88
+ * [360..368] lastNav u64 (snapshot for rate-limit window)
89
+ * [368..376] dailyWithdrawnBase u64 (rate-limit accumulator)
90
+ * [376..380] nextEpochTs u32
91
+ * [380..384] epochSec u32
92
+ * [384..388] currentEpochId u32
93
+ * [388..392] pendingWithdrawals u32
94
+ * [392..396] withdrawWindowStart u32
95
+ * [396..398] mgmtFeeBps u16
96
+ * [398..400] perfFeeBps u16
97
+ * [400..402] flags u16
98
+ * [402..404] dailyWithdrawLimitBps u16
99
+ * [404..405] childVaultCount u8
100
+ * [405..406] version u8 (== 2 for v2 accounts)
101
+ * [406..407] bump u8
102
+ * [407..408] _padding [u8; 1]
103
+ * [408..410] depositFeeBps u16 (_OFFSET_DEPOSIT_FEE_BPS == 408)
104
+ * [410..412] withdrawalFeeBps u16 (_OFFSET_WITHDRAWAL_FEE_BPS == 410)
105
+ * [412..416] pendingDepositCount u32 (_OFFSET_PENDING_DEPOSIT_COUNT == 412)
106
+ * [416..424] pendingDepositBase u64 (_OFFSET_PENDING_DEPOSIT_BASE == 416)
107
+ * [424..456] feeReceiverEvAta Pubkey (_OFFSET_FEE_RECEIVER_EV_ATA == 424)
108
+ * [456..464] lockedSeedShares u64 (_OFFSET_LOCKED_SEED_SHARES == 456)
109
+ * [464..465] withdrawalMode u8 (_OFFSET_WITHDRAWAL_MODE == 464; 0=instant, 1=X, 2=X+1)
110
+ * [465..468] _reservedPad [u8; 3] (_OFFSET_RESERVED_PAD == 465; alignment before last_nav_ts)
111
+ * [468..472] lastNavTs u32 (_OFFSET_LAST_NAV_TS == 468; unix seconds; 0 = no epoch yet)
112
+ * [472..476] strategyStalenessThreshold u32 (_OFFSET_STRATEGY_STALENESS_THRESHOLD == 472; 0 = use default 24 h)
113
+ * [476..508] warmAdmin Pubkey (_OFFSET_WARM_ADMIN == 476; [0u8;32] = "follow cold" sentinel — resolve via warmAdminEffective())
114
+ * [508..664] _reserved [u8; 156] (_OFFSET_RESERVED == 508)
115
+ */
116
+ function deserializeStv(data) {
117
+ if (data.length < constants_1.STV_SIZE) {
118
+ throw new Error(`Stv data too short: ${data.length} < ${constants_1.STV_SIZE}`);
119
+ }
120
+ const disc = data.subarray(0, 8);
121
+ if (!disc.equals(constants_1.DISC_STV)) {
122
+ throw new Error(`Invalid Stv discriminator`);
123
+ }
124
+ // v2 gate: version must be 2 (stv.rs Stv::from_account — discriminator +
125
+ // version==2 is the complete loader gate; cold_admin!=0 is enforced at write
126
+ // time by init_or_update_stv and is NOT re-checked by the on-chain loader).
127
+ const version = (0, buffer_1.readU8)(data, 405);
128
+ if (version !== 2) {
129
+ throw new Error(`Stv account is not v2: version=${version}`);
130
+ }
131
+ // childVaults: [u64; 4] at offset 264, MAX_CHILD_VAULTS = 4
132
+ const childVaults = [];
133
+ for (let i = 0; i < constants_1.MAX_STRATEGIES; i++) {
134
+ childVaults.push((0, buffer_1.readU64)(data, 264 + i * 8));
135
+ }
136
+ return {
137
+ baseMint: (0, buffer_1.readPubkey)(data, 8),
138
+ evMint: (0, buffer_1.readPubkey)(data, 40),
139
+ strategy: (0, buffer_1.readPubkey)(data, 72),
140
+ feeReceiver: (0, buffer_1.readPubkey)(data, 104),
141
+ lendProgram: (0, buffer_1.readPubkey)(data, 136),
142
+ vaultAta: (0, buffer_1.readPubkey)(data, 168),
143
+ coldAdmin: (0, buffer_1.readPubkey)(data, 200),
144
+ pendingAdmin: (0, buffer_1.readPubkey)(data, 232),
145
+ childVaults,
146
+ vaultId: (0, buffer_1.readU64)(data, 296),
147
+ reservedBase: (0, buffer_1.readU64)(data, 304),
148
+ requestedShares: (0, buffer_1.readU64)(data, 312),
149
+ vaultCapacity: (0, buffer_1.readU64)(data, 320),
150
+ minDeposit: (0, buffer_1.readU64)(data, 328),
151
+ hwm: (0, buffer_1.readU64)(data, 336),
152
+ lastFeeTs: (0, buffer_1.readU64)(data, 344),
153
+ epochPps: (0, buffer_1.readU64)(data, 352),
154
+ lastNav: (0, buffer_1.readU64)(data, 360),
155
+ dailyWithdrawnBase: (0, buffer_1.readU64)(data, 368),
156
+ nextEpochTs: (0, buffer_1.readU32)(data, 376),
157
+ epochSec: (0, buffer_1.readU32)(data, 380),
158
+ currentEpochId: (0, buffer_1.readU32)(data, 384),
159
+ pendingWithdrawals: (0, buffer_1.readU32)(data, 388),
160
+ withdrawWindowStart: (0, buffer_1.readU32)(data, 392),
161
+ mgmtFeeBps: (0, buffer_1.readU16)(data, 396),
162
+ perfFeeBps: (0, buffer_1.readU16)(data, 398),
163
+ flags: (0, buffer_1.readU16)(data, 400),
164
+ dailyWithdrawLimitBps: (0, buffer_1.readU16)(data, 402),
165
+ childVaultCount: (0, buffer_1.readU8)(data, 404),
166
+ version,
167
+ bump: (0, buffer_1.readU8)(data, 406),
168
+ depositFeeBps: (0, buffer_1.readU16)(data, 408),
169
+ withdrawalFeeBps: (0, buffer_1.readU16)(data, 410),
170
+ pendingDepositCount: (0, buffer_1.readU32)(data, 412),
171
+ pendingDepositBase: (0, buffer_1.readU64)(data, 416),
172
+ feeReceiverEvAta: (0, buffer_1.readPubkey)(data, 424),
173
+ lockedSeedShares: (0, buffer_1.readU64)(data, 456),
174
+ withdrawalMode: (0, buffer_1.readU8)(data, 464),
175
+ lastNavTs: (0, buffer_1.readU32)(data, 468),
176
+ strategyStalenessThreshold: (0, buffer_1.readU32)(data, 472),
177
+ warmAdmin: (0, buffer_1.readPubkey)(data, 476),
178
+ };
179
+ }
180
+ /**
181
+ * Resolve the effective warm admin for an STV: the stored `warmAdmin`
182
+ * "follow cold" sentinel (`PublicKey.default`, i.e. `[0u8;32]`) resolves to
183
+ * `stv.coldAdmin` (cold). Mirrors the on-chain `Stv::warm_admin_effective()`
184
+ * helper (state/stv.rs) — every warm-gated on-chain auth check
185
+ * (`add_manager`, `remove_manager`, `override_claim_withdraw`,
186
+ * `trip_circuit_breaker`) routes through that same resolution, so this is
187
+ * the correct way to read `warmAdmin` off-chain too; never compare
188
+ * `stv.warmAdmin` directly against a candidate signer.
189
+ *
190
+ * PRE-DEPLOY CAVEAT: every STV on the currently-deployed mainnet program
191
+ * reads the sentinel (the field lives in a zeroed pre-upgrade reserved
192
+ * tail), so this always resolves to `stv.coldAdmin` until the program
193
+ * upgrade ships — which is the correct, safe answer either way (cold's
194
+ * power set is a superset of warm's).
195
+ */
196
+ function warmAdminEffective(stv) {
197
+ return stv.warmAdmin.equals(web3_js_1.PublicKey.default) ? stv.coldAdmin : stv.warmAdmin;
198
+ }
199
+ /**
200
+ * WithdrawRequest — per-(STV, user, epoch) withdraw escrow. Total 168 bytes.
201
+ *
202
+ * Layout (offsets include the 8-byte discriminator):
203
+ * [ 0.. 8] discriminator (sha256("account:WithdrawRequest")[..8])
204
+ * [ 8.. 40] stv Pubkey
205
+ * [ 40.. 72] user Pubkey
206
+ * [ 72.. 80] shares u64
207
+ * [ 80.. 88] pps u64 (locked at process_epoch time)
208
+ * [ 88.. 92] epochId u32
209
+ * [ 92.. 96] claimAvailableAfter u32 (unix seconds)
210
+ * [ 96.. 97] bump u8
211
+ * [ 97.. 98] version u8
212
+ * [ 98.. 99] requestFlags u8 (bit0 WR_FLAG_MIGRATE: 0=withdraw, 1=migrate)
213
+ * [ 99..104] _padding [u8; 5]
214
+ * [104..112] destVaultId u64 (migrate: dest STV vault_id; withdraw: 0)
215
+ * [112..120] minDestShares u64 (migrate: slippage floor; withdraw: 0)
216
+ * [120..168] _reserved0 [u8; 48]
217
+ */
218
+ function deserializeWithdrawRequest(data) {
219
+ if (data.length < constants_1.WITHDRAW_REQUEST_SIZE) {
220
+ throw new Error(`WithdrawRequest data too short: ${data.length} < ${constants_1.WITHDRAW_REQUEST_SIZE}`);
221
+ }
222
+ const disc = data.subarray(0, 8);
223
+ if (!disc.equals(constants_1.DISC_WITHDRAW_REQUEST)) {
224
+ throw new Error(`Invalid WithdrawRequest discriminator`);
225
+ }
226
+ return {
227
+ stv: (0, buffer_1.readPubkey)(data, 8),
228
+ user: (0, buffer_1.readPubkey)(data, 40),
229
+ shares: (0, buffer_1.readU64)(data, 72),
230
+ pps: (0, buffer_1.readU64)(data, 80),
231
+ epochId: (0, buffer_1.readU32)(data, 88),
232
+ claimAvailableAfter: (0, buffer_1.readU32)(data, 92),
233
+ bump: (0, buffer_1.readU8)(data, 96),
234
+ // version is at offset 97 (_OFFSET_VERSION in withdraw_request.rs:68)
235
+ version: (0, buffer_1.readU8)(data, 97),
236
+ requestFlags: (0, buffer_1.readU8)(data, 98),
237
+ destVaultId: (0, buffer_1.readU64)(data, 104),
238
+ minDestShares: (0, buffer_1.readU64)(data, 112),
239
+ };
240
+ }
241
+ /**
242
+ * WithdrawRequest kind from `requestFlags` bit 0.
243
+ * Returns `"migrate"` when WR_FLAG_MIGRATE (0x01) is set, else `"withdraw"`.
244
+ */
245
+ function withdrawRequestKind(wr) {
246
+ return (wr.requestFlags & 0x01) !== 0 ? "migrate" : "withdraw";
247
+ }
248
+ /**
249
+ * DelayedDepositRequest — per-(STV, user, epoch) pending deposit. Total 152 bytes.
250
+ *
251
+ * Layout (offsets include the 8-byte discriminator):
252
+ * [ 0.. 8] discriminator (sha256("account:DelayedDepositRequest")[..8])
253
+ * [ 8.. 40] stv Pubkey
254
+ * [ 40.. 72] user Pubkey
255
+ * [ 72.. 80] amount u64
256
+ * [ 80.. 84] epochId u32 (offset_of == 80, asserted on-chain)
257
+ * [ 84.. 85] bump u8
258
+ * [ 85.. 86] version u8
259
+ * [ 86.. 88] _padding [u8; 2]
260
+ * [ 88..152] _reserved [u8; 64]
261
+ */
262
+ function deserializeDelayedDepositRequest(data) {
263
+ if (data.length < constants_1.DELAYED_DEPOSIT_REQUEST_SIZE) {
264
+ throw new Error(`DelayedDepositRequest data too short: ${data.length} < ${constants_1.DELAYED_DEPOSIT_REQUEST_SIZE}`);
265
+ }
266
+ const disc = data.subarray(0, 8);
267
+ if (!disc.equals(constants_1.DISC_DELAYED_DEPOSIT_REQUEST)) {
268
+ throw new Error(`Invalid DelayedDepositRequest discriminator`);
269
+ }
270
+ return {
271
+ stv: (0, buffer_1.readPubkey)(data, 8),
272
+ user: (0, buffer_1.readPubkey)(data, 40),
273
+ amount: (0, buffer_1.readU64)(data, 72),
274
+ epochId: (0, buffer_1.readU32)(data, 80),
275
+ bump: (0, buffer_1.readU8)(data, 84),
276
+ version: (0, buffer_1.readU8)(data, 85),
277
+ };
278
+ }
279
+ /**
280
+ * ManagerRole — per-(STV, manager) authorization record. Total 80 bytes.
281
+ *
282
+ * Layout (offsets include the 8-byte discriminator):
283
+ * [ 0.. 8] discriminator (sha256("account:ManagerRole")[..8] —
284
+ * shared with elemental-lend + jlpd-strategy)
285
+ * [ 8.. 40] stv Pubkey
286
+ * [ 40.. 72] manager Pubkey
287
+ * [ 72.. 73] bump u8
288
+ * [ 73.. 80] _padding [u8; 7]
289
+ */
290
+ function deserializeManagerRole(data) {
291
+ if (data.length < constants_1.MANAGER_ROLE_SIZE) {
292
+ throw new Error(`ManagerRole data too short: ${data.length} < ${constants_1.MANAGER_ROLE_SIZE}`);
293
+ }
294
+ const disc = data.subarray(0, 8);
295
+ if (!disc.equals(constants_1.DISC_MANAGER_ROLE)) {
296
+ throw new Error(`Invalid ManagerRole discriminator`);
297
+ }
298
+ return {
299
+ stv: (0, buffer_1.readPubkey)(data, 8),
300
+ manager: (0, buffer_1.readPubkey)(data, 40),
301
+ bump: (0, buffer_1.readU8)(data, 72),
302
+ };
303
+ }
304
+ // ---------------------------------------------------------------------------
305
+ // Fetch Helpers
306
+ // ---------------------------------------------------------------------------
307
+ async function fetchGlobalConfig(connection, programId = constants_1.PROGRAM_ID) {
308
+ const [configPda] = (0, pda_1.findConfigPda)(programId);
309
+ const info = await connection.getAccountInfo(configPda);
310
+ if (!info)
311
+ throw new Error("GlobalConfig account not found");
312
+ return deserializeGlobalConfig(info.data);
313
+ }
314
+ async function fetchStv(connection, vaultId, programId = constants_1.PROGRAM_ID) {
315
+ const [stvPda] = (0, pda_1.findStvPda)(vaultId, programId);
316
+ const info = await connection.getAccountInfo(stvPda);
317
+ if (!info)
318
+ throw new Error(`Stv account not found for vault_id ${vaultId}`);
319
+ return deserializeStv(info.data);
320
+ }
321
+ async function fetchStvByAddress(connection, address) {
322
+ const info = await connection.getAccountInfo(address);
323
+ if (!info)
324
+ throw new Error(`Stv account not found at ${address.toBase58()}`);
325
+ return deserializeStv(info.data);
326
+ }
327
+ async function fetchWithdrawRequest(connection, stv, user, epochId, programId = constants_1.PROGRAM_ID) {
328
+ const [wrPda] = (0, pda_1.findWithdrawRequestPda)(stv, user, epochId, programId);
329
+ const info = await connection.getAccountInfo(wrPda);
330
+ if (!info)
331
+ throw new Error("WithdrawRequest account not found");
332
+ return deserializeWithdrawRequest(info.data);
333
+ }
334
+ async function fetchWithdrawRequestByAddress(connection, address) {
335
+ const info = await connection.getAccountInfo(address);
336
+ if (!info)
337
+ throw new Error(`WithdrawRequest not found at ${address.toBase58()}`);
338
+ return deserializeWithdrawRequest(info.data);
339
+ }
340
+ async function fetchDelayedDepositRequest(connection, stv, user, epochId, programId = constants_1.PROGRAM_ID) {
341
+ const [pda] = (0, pda_1.findDelayedDepositRequestPda)(stv, user, epochId, programId);
342
+ const info = await connection.getAccountInfo(pda);
343
+ if (!info)
344
+ throw new Error("DelayedDepositRequest account not found");
345
+ return deserializeDelayedDepositRequest(info.data);
346
+ }
347
+ async function fetchDelayedDepositRequestByAddress(connection, address) {
348
+ const info = await connection.getAccountInfo(address);
349
+ if (!info)
350
+ throw new Error(`DelayedDepositRequest not found at ${address.toBase58()}`);
351
+ return deserializeDelayedDepositRequest(info.data);
352
+ }
353
+ // ---------------------------------------------------------------------------
354
+ // GPA Helpers
355
+ // ---------------------------------------------------------------------------
356
+ async function fetchAllStvs(connection, programId = constants_1.PROGRAM_ID) {
357
+ const accounts = await connection.getProgramAccounts(programId, {
358
+ filters: [
359
+ { dataSize: constants_1.STV_SIZE },
360
+ { memcmp: { offset: 0, bytes: constants_1.DISC_STV.toString("base64"), encoding: "base64" } },
361
+ ],
362
+ });
363
+ return accounts.map((a) => [a.pubkey, deserializeStv(a.account.data)]);
364
+ }
365
+ async function fetchPendingWithdrawRequests(connection, stv, epochId, programId = constants_1.PROGRAM_ID) {
366
+ const epochBuf = Buffer.alloc(4);
367
+ epochBuf.writeUInt32LE(epochId, 0);
368
+ const accounts = await connection.getProgramAccounts(programId, {
369
+ filters: [
370
+ { dataSize: constants_1.WITHDRAW_REQUEST_SIZE },
371
+ { memcmp: { offset: 0, bytes: constants_1.DISC_WITHDRAW_REQUEST.toString("base64"), encoding: "base64" } },
372
+ { memcmp: { offset: 8, bytes: stv.toBuffer().toString("base64"), encoding: "base64" } },
373
+ { memcmp: { offset: 88, bytes: epochBuf.toString("base64"), encoding: "base64" } },
374
+ ],
375
+ });
376
+ return accounts.map((a) => [a.pubkey, deserializeWithdrawRequest(a.account.data)]);
377
+ }
378
+ async function fetchPendingDelayedDepositRequests(connection, stv, epochId, programId = constants_1.PROGRAM_ID) {
379
+ const epochBuf = Buffer.alloc(4);
380
+ epochBuf.writeUInt32LE(epochId, 0);
381
+ const accounts = await connection.getProgramAccounts(programId, {
382
+ filters: [
383
+ { dataSize: constants_1.DELAYED_DEPOSIT_REQUEST_SIZE },
384
+ { memcmp: { offset: 0, bytes: constants_1.DISC_DELAYED_DEPOSIT_REQUEST.toString("base64"), encoding: "base64" } },
385
+ { memcmp: { offset: 8, bytes: stv.toBuffer().toString("base64"), encoding: "base64" } },
386
+ { memcmp: { offset: 80, bytes: epochBuf.toString("base64"), encoding: "base64" } },
387
+ ],
388
+ });
389
+ return accounts.map((a) => [a.pubkey, deserializeDelayedDepositRequest(a.account.data)]);
390
+ }
391
+ async function fetchManagerRole(connection, stv, manager, programId = constants_1.PROGRAM_ID) {
392
+ const [pda] = (0, pda_1.findStvManagerRolePda)(stv, manager, programId);
393
+ const info = await connection.getAccountInfo(pda);
394
+ if (!info)
395
+ return null;
396
+ return deserializeManagerRole(info.data);
397
+ }
398
+ async function fetchManagersForStv(connection, stv, programId = constants_1.PROGRAM_ID) {
399
+ const accounts = await connection.getProgramAccounts(programId, {
400
+ filters: [
401
+ { dataSize: constants_1.MANAGER_ROLE_SIZE },
402
+ { memcmp: { offset: 0, bytes: constants_1.DISC_MANAGER_ROLE.toString("base64"), encoding: "base64" } },
403
+ { memcmp: { offset: 8, bytes: stv.toBuffer().toString("base64"), encoding: "base64" } },
404
+ ],
405
+ });
406
+ return accounts.map((a) => [a.pubkey, deserializeManagerRole(a.account.data)]);
407
+ }