@elmntl/jlpd-sdk 0.1.11 → 0.2.0

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/dist/index.js CHANGED
@@ -49,6 +49,7 @@ __export(index_exports, {
49
49
  PoolContext: () => PoolContext,
50
50
  SEED_JLP_VAULT: () => SEED_JLP_VAULT,
51
51
  SEED_STV: () => SEED_STV,
52
+ SEED_WITHDRAW_REQUEST: () => SEED_WITHDRAW_REQUEST,
52
53
  STV_ACCOUNT_SIZE: () => STV_ACCOUNT_SIZE,
53
54
  STV_DATA_SIZE: () => STV_DATA_SIZE,
54
55
  STV_DISCRIMINATOR: () => STV_DISCRIMINATOR,
@@ -57,6 +58,9 @@ __export(index_exports, {
57
58
  USDC_POOL: () => USDC_POOL,
58
59
  WBTC_POOL: () => WBTC_POOL,
59
60
  WETH_POOL: () => WETH_POOL,
61
+ WITHDRAW_REQUEST_ACCOUNT_SIZE: () => WITHDRAW_REQUEST_ACCOUNT_SIZE,
62
+ WITHDRAW_REQUEST_DATA_SIZE: () => WITHDRAW_REQUEST_DATA_SIZE,
63
+ WITHDRAW_REQUEST_DISCRIMINATOR: () => WITHDRAW_REQUEST_DISCRIMINATOR,
60
64
  WSOL_POOL: () => WSOL_POOL,
61
65
  baseToJlx: () => baseToJlx,
62
66
  baseToShares: () => baseToShares,
@@ -70,22 +74,25 @@ __export(index_exports, {
70
74
  clearAtaCache: () => clearAtaCache,
71
75
  clearPdaCache: () => clearPdaCache,
72
76
  createClaimFeesInstruction: () => createClaimFeesInstruction,
77
+ createClaimWithdrawInstruction: () => createClaimWithdrawInstruction,
73
78
  createDepositInstruction: () => createDepositInstruction,
74
79
  createInitOrUpdateVaultInstruction: () => createInitOrUpdateVaultInstruction,
75
80
  createInitializeStvInstruction: () => createInitializeStvInstruction,
76
81
  createJupEarnInstruction: () => createJupEarnInstruction,
77
82
  createMoveJlxInstruction: () => createMoveJlxInstruction,
83
+ createProcessEpochInstruction: () => createProcessEpochInstruction,
78
84
  createProgram: () => createProgram,
85
+ createRequestWithdrawInstruction: () => createRequestWithdrawInstruction,
79
86
  createSettleYieldInstruction: () => createSettleYieldInstruction,
80
87
  createSwapJlxJlpInstruction: () => createSwapJlxJlpInstruction,
81
88
  createUpdateStvInstruction: () => createUpdateStvInstruction,
82
- createWithdrawInstruction: () => createWithdrawInstruction,
83
89
  deriveAta: () => deriveAta,
84
90
  deriveStvAtas: () => deriveStvAtas,
85
91
  deriveStvPda: () => deriveStvPda,
86
92
  deriveUserAtas: () => deriveUserAtas,
87
93
  deriveVaultAtas: () => deriveVaultAtas,
88
94
  deriveVaultPda: () => deriveVaultPda,
95
+ deriveWithdrawRequestPda: () => deriveWithdrawRequestPda,
89
96
  fetchAddressLookupTables: () => fetchAddressLookupTables,
90
97
  fetchJlpRate: () => fetchJlpRate,
91
98
  fetchJupiterPriceUsd: () => fetchJupiterPriceUsd,
@@ -99,6 +106,7 @@ __export(index_exports, {
99
106
  parseStv: () => parseStv,
100
107
  parseSwapRemainingAccounts: () => parseSwapRemainingAccounts,
101
108
  parseVault: () => parseVault,
109
+ parseWithdrawRequest: () => parseWithdrawRequest,
102
110
  sharesToBase: () => sharesToBase
103
111
  });
104
112
  module.exports = __toCommonJS(index_exports);
@@ -205,66 +213,71 @@ var jlp_d_program_default = {
205
213
  args: []
206
214
  },
207
215
  {
208
- name: "close_stv",
216
+ name: "claim_withdraw",
209
217
  docs: [
210
- "Close an STV account and return rent to admin",
211
- "Destructive operation - use only for cleanup/migration",
218
+ "Claim processed withdrawal (epoch-based delayed withdrawal)",
212
219
  "",
213
- "# Safety Checks",
214
- "- Validates jvX supply is 0 (no active shares)",
215
- "- Validates base_loaned is 0 (no outstanding loans)",
216
- "- Validates accrued_fees_jlx is 0 (no unclaimed fees)"
220
+ "# Flow",
221
+ "1. Verify request is processed (pps > 0) and claim period reached",
222
+ "2. Transfer base from STV to user",
223
+ "3. Close request's jvX ATA and WithdrawRequest PDA (rent to user)"
217
224
  ],
218
225
  discriminator: [
219
- 173,
220
- 189,
221
- 151,
222
- 131,
223
- 240,
224
- 39,
225
- 199,
226
- 147
226
+ 232,
227
+ 89,
228
+ 154,
229
+ 117,
230
+ 16,
231
+ 204,
232
+ 182,
233
+ 224
227
234
  ],
228
235
  accounts: [
229
236
  {
230
- name: "admin",
237
+ name: "user",
231
238
  docs: [
232
- "Admin must sign - verified via vault.has_one = admin"
239
+ "User claiming their withdrawal"
233
240
  ],
234
241
  writable: true,
235
- signer: true,
236
- relations: [
237
- "jlp_vault"
242
+ signer: true
243
+ },
244
+ {
245
+ name: "stv",
246
+ docs: [
247
+ "The STV PDA account (mut for reserved_base update)"
248
+ ],
249
+ writable: true
250
+ },
251
+ {
252
+ name: "base_mint",
253
+ docs: [
254
+ "Base asset mint (for transfer_checked)"
238
255
  ]
239
256
  },
240
257
  {
241
- name: "jlp_vault",
258
+ name: "jv_mint",
242
259
  docs: [
243
- "JLP Vault for admin validation"
260
+ "jvX mint (for ATA close verification)"
261
+ ]
262
+ },
263
+ {
264
+ name: "user_base_ata",
265
+ docs: [
266
+ "User's base token destination"
244
267
  ],
245
- pda: {
246
- seeds: [
247
- {
248
- kind: "const",
249
- value: [
250
- 106,
251
- 108,
252
- 112,
253
- 95,
254
- 118,
255
- 97,
256
- 117,
257
- 108,
258
- 116
259
- ]
260
- }
261
- ]
262
- }
268
+ writable: true
263
269
  },
264
270
  {
265
- name: "stv",
271
+ name: "stv_base_ata",
266
272
  docs: [
267
- "STV to close"
273
+ "STV's base ATA (source for base transfer)"
274
+ ],
275
+ writable: true
276
+ },
277
+ {
278
+ name: "withdraw_request",
279
+ docs: [
280
+ "WithdrawRequest PDA - closed after claim (rent to user)"
268
281
  ],
269
282
  writable: true,
270
283
  pda: {
@@ -272,33 +285,49 @@ var jlp_d_program_default = {
272
285
  {
273
286
  kind: "const",
274
287
  value: [
275
- 115,
288
+ 119,
289
+ 105,
276
290
  116,
277
- 118
291
+ 104,
292
+ 100,
293
+ 114,
294
+ 97,
295
+ 119,
296
+ 95,
297
+ 114,
298
+ 101,
299
+ 113,
300
+ 117,
301
+ 101,
302
+ 115,
303
+ 116
278
304
  ]
279
305
  },
280
306
  {
281
307
  kind: "account",
282
- path: "base_mint"
308
+ path: "stv"
309
+ },
310
+ {
311
+ kind: "account",
312
+ path: "user"
313
+ },
314
+ {
315
+ kind: "account",
316
+ path: "withdraw_request.epoch_id",
317
+ account: "WithdrawRequest"
283
318
  }
284
319
  ]
285
320
  }
286
321
  },
287
322
  {
288
- name: "jv_mint",
289
- docs: [
290
- "jvX mint for this STV - used to verify no active shares"
291
- ]
292
- },
293
- {
294
- name: "base_mint",
323
+ name: "request_jvx_ata",
295
324
  docs: [
296
- "Base asset mint for this STV"
297
- ]
325
+ "Empty jvX ATA owned by WithdrawRequest PDA (to close, rent to user)"
326
+ ],
327
+ writable: true
298
328
  },
299
329
  {
300
- name: "system_program",
301
- address: "11111111111111111111111111111111"
330
+ name: "token_program"
302
331
  }
303
332
  ],
304
333
  args: []
@@ -560,7 +589,7 @@ var jlp_d_program_default = {
560
589
  name: "jv_mint",
561
590
  docs: [
562
591
  "Vault share token mint (jvX) - STV is the mint authority",
563
- "Client generates keypair and passes it as signer"
592
+ "Uses init_if_needed in case mint exists from a previous STV initialization"
564
593
  ],
565
594
  writable: true,
566
595
  signer: true
@@ -859,36 +888,335 @@ var jlp_d_program_default = {
859
888
  ]
860
889
  },
861
890
  {
862
- name: "stv_jlx_ata",
863
- docs: [
864
- "STV's jlX ATA",
865
- "For base-only pools, this is the base ATA (jl_mint == base_mint)"
866
- ],
867
- writable: true
891
+ name: "stv_jlx_ata",
892
+ docs: [
893
+ "STV's jlX ATA",
894
+ "For base-only pools, this is the base ATA (jl_mint == base_mint)"
895
+ ],
896
+ writable: true
897
+ },
898
+ {
899
+ name: "vault_staging_ata",
900
+ docs: [
901
+ "Vault's staging jlX ATA (for this specific jl_mint)",
902
+ "For base-only pools, this is the staging base ATA"
903
+ ],
904
+ writable: true
905
+ },
906
+ {
907
+ name: "token_program",
908
+ docs: [
909
+ "Token program"
910
+ ]
911
+ }
912
+ ],
913
+ args: [
914
+ {
915
+ name: "params",
916
+ type: {
917
+ defined: {
918
+ name: "MoveJlxParams"
919
+ }
920
+ }
921
+ }
922
+ ]
923
+ },
924
+ {
925
+ name: "process_epoch",
926
+ docs: [
927
+ "Process epoch: burn jvX from withdraw requests, record PPS, earmark base",
928
+ "",
929
+ "Permissionless (anyone can call after epoch ends).",
930
+ "Processes WithdrawRequest pairs from remaining_accounts.",
931
+ "Uses epoch_pps for multi-batch consistency.",
932
+ "",
933
+ "# Remaining Accounts",
934
+ "- [0-1]: Jupiter Lend accounts (if jl_mint != base_mint)",
935
+ "- [N..]: pairs of [WithdrawRequest (mut), request_jvx_ata (mut)]"
936
+ ],
937
+ discriminator: [
938
+ 115,
939
+ 194,
940
+ 215,
941
+ 160,
942
+ 113,
943
+ 154,
944
+ 81,
945
+ 5
946
+ ],
947
+ accounts: [
948
+ {
949
+ name: "payer",
950
+ docs: [
951
+ "Payer/caller - permissionless (anyone can call after epoch ends)"
952
+ ],
953
+ writable: true,
954
+ signer: true
955
+ },
956
+ {
957
+ name: "jlp_vault",
958
+ docs: [
959
+ "The JLP Vault PDA account (for pause checks)"
960
+ ]
961
+ },
962
+ {
963
+ name: "stv",
964
+ docs: [
965
+ "The STV PDA account (mut for epoch state + fee crystallization)"
966
+ ],
967
+ writable: true
968
+ },
969
+ {
970
+ name: "base_mint",
971
+ docs: [
972
+ "Base asset mint (for NAV calc)"
973
+ ]
974
+ },
975
+ {
976
+ name: "jl_mint",
977
+ docs: [
978
+ "jlX mint (for exchange rate)"
979
+ ]
980
+ },
981
+ {
982
+ name: "jv_mint",
983
+ docs: [
984
+ "jvX mint (mut for burn - supply decreases)"
985
+ ],
986
+ writable: true
987
+ },
988
+ {
989
+ name: "stv_base_ata",
990
+ docs: [
991
+ "STV's base ATA (for NAV)"
992
+ ]
993
+ },
994
+ {
995
+ name: "stv_jlx_ata",
996
+ docs: [
997
+ "STV's jlX ATA (for NAV)"
998
+ ]
999
+ },
1000
+ {
1001
+ name: "token_program"
1002
+ }
1003
+ ],
1004
+ args: []
1005
+ },
1006
+ {
1007
+ name: "request_withdraw",
1008
+ docs: [
1009
+ "Request withdrawal of jvX shares (epoch-based delayed withdrawal)",
1010
+ "",
1011
+ "# Flow",
1012
+ "1. Validate epoch is active and not ended",
1013
+ "2. Create or accumulate into WithdrawRequest PDA for this epoch",
1014
+ "3. Transfer jvX from user to request's escrow ATA",
1015
+ "",
1016
+ "User must wait for process_epoch + claim_withdraw to receive base."
1017
+ ],
1018
+ discriminator: [
1019
+ 137,
1020
+ 95,
1021
+ 187,
1022
+ 96,
1023
+ 250,
1024
+ 138,
1025
+ 31,
1026
+ 182
1027
+ ],
1028
+ accounts: [
1029
+ {
1030
+ name: "user",
1031
+ docs: [
1032
+ "User requesting withdrawal"
1033
+ ],
1034
+ writable: true,
1035
+ signer: true
1036
+ },
1037
+ {
1038
+ name: "jlp_vault",
1039
+ docs: [
1040
+ "The JLP Vault PDA account (for pause checks)"
1041
+ ]
1042
+ },
1043
+ {
1044
+ name: "stv",
1045
+ docs: [
1046
+ "The STV PDA account (for epoch validation)"
1047
+ ],
1048
+ writable: true
1049
+ },
1050
+ {
1051
+ name: "jv_mint",
1052
+ docs: [
1053
+ "jvX mint (vault share token)"
1054
+ ]
1055
+ },
1056
+ {
1057
+ name: "user_jvx_ata",
1058
+ docs: [
1059
+ "User's jvX token account (source of shares)"
1060
+ ],
1061
+ writable: true
1062
+ },
1063
+ {
1064
+ name: "withdraw_request",
1065
+ docs: [
1066
+ "WithdrawRequest PDA - created or accumulated into"
1067
+ ],
1068
+ writable: true,
1069
+ pda: {
1070
+ seeds: [
1071
+ {
1072
+ kind: "const",
1073
+ value: [
1074
+ 119,
1075
+ 105,
1076
+ 116,
1077
+ 104,
1078
+ 100,
1079
+ 114,
1080
+ 97,
1081
+ 119,
1082
+ 95,
1083
+ 114,
1084
+ 101,
1085
+ 113,
1086
+ 117,
1087
+ 101,
1088
+ 115,
1089
+ 116
1090
+ ]
1091
+ },
1092
+ {
1093
+ kind: "account",
1094
+ path: "stv"
1095
+ },
1096
+ {
1097
+ kind: "account",
1098
+ path: "user"
1099
+ },
1100
+ {
1101
+ kind: "arg",
1102
+ path: "epoch_id"
1103
+ }
1104
+ ]
1105
+ }
1106
+ },
1107
+ {
1108
+ name: "request_jvx_ata",
1109
+ docs: [
1110
+ "jvX ATA owned by the WithdrawRequest PDA (escrow for shares)"
1111
+ ],
1112
+ writable: true,
1113
+ pda: {
1114
+ seeds: [
1115
+ {
1116
+ kind: "account",
1117
+ path: "withdraw_request"
1118
+ },
1119
+ {
1120
+ kind: "const",
1121
+ value: [
1122
+ 6,
1123
+ 221,
1124
+ 246,
1125
+ 225,
1126
+ 215,
1127
+ 101,
1128
+ 161,
1129
+ 147,
1130
+ 217,
1131
+ 203,
1132
+ 225,
1133
+ 70,
1134
+ 206,
1135
+ 235,
1136
+ 121,
1137
+ 172,
1138
+ 28,
1139
+ 180,
1140
+ 133,
1141
+ 237,
1142
+ 95,
1143
+ 91,
1144
+ 55,
1145
+ 145,
1146
+ 58,
1147
+ 140,
1148
+ 245,
1149
+ 133,
1150
+ 126,
1151
+ 255,
1152
+ 0,
1153
+ 169
1154
+ ]
1155
+ },
1156
+ {
1157
+ kind: "account",
1158
+ path: "jv_mint"
1159
+ }
1160
+ ],
1161
+ program: {
1162
+ kind: "const",
1163
+ value: [
1164
+ 140,
1165
+ 151,
1166
+ 37,
1167
+ 143,
1168
+ 78,
1169
+ 36,
1170
+ 137,
1171
+ 241,
1172
+ 187,
1173
+ 61,
1174
+ 16,
1175
+ 41,
1176
+ 20,
1177
+ 142,
1178
+ 13,
1179
+ 131,
1180
+ 11,
1181
+ 90,
1182
+ 19,
1183
+ 153,
1184
+ 218,
1185
+ 255,
1186
+ 16,
1187
+ 132,
1188
+ 4,
1189
+ 142,
1190
+ 123,
1191
+ 216,
1192
+ 219,
1193
+ 233,
1194
+ 248,
1195
+ 89
1196
+ ]
1197
+ }
1198
+ }
1199
+ },
1200
+ {
1201
+ name: "token_program"
868
1202
  },
869
1203
  {
870
- name: "vault_staging_ata",
871
- docs: [
872
- "Vault's staging jlX ATA (for this specific jl_mint)",
873
- "For base-only pools, this is the staging base ATA"
874
- ],
875
- writable: true
1204
+ name: "associated_token_program",
1205
+ address: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
876
1206
  },
877
1207
  {
878
- name: "token_program",
879
- docs: [
880
- "Token program"
881
- ]
1208
+ name: "system_program",
1209
+ address: "11111111111111111111111111111111"
882
1210
  }
883
1211
  ],
884
1212
  args: [
885
1213
  {
886
- name: "params",
887
- type: {
888
- defined: {
889
- name: "MoveJlxParams"
890
- }
891
- }
1214
+ name: "shares",
1215
+ type: "u64"
1216
+ },
1217
+ {
1218
+ name: "epoch_id",
1219
+ type: "u32"
892
1220
  }
893
1221
  ]
894
1222
  },
@@ -1138,121 +1466,6 @@ var jlp_d_program_default = {
1138
1466
  }
1139
1467
  }
1140
1468
  ]
1141
- },
1142
- {
1143
- name: "withdraw",
1144
- docs: [
1145
- "Withdraw base asset by burning jvX shares",
1146
- "",
1147
- "# Flow",
1148
- "1. Crystallize fees inline (ensures fair PPS)",
1149
- "2. Calculate base amount from shares at post-fee PPS",
1150
- "3. Burn jvX shares from user",
1151
- "4. Transfer base from STV's base ATA to user",
1152
- "",
1153
- "# Note",
1154
- "Requires sufficient base balance in STV's base ATA.",
1155
- "Manager must ensure liquidity by converting jlX to base via",
1156
- "jup_earn_deposit_withdraw instruction before user withdrawals.",
1157
- "",
1158
- "Remaining accounts (optional, for exchange rate):",
1159
- "[0] = Jupiter Lend lending account",
1160
- "[1] = Jupiter Lend rewards rate model"
1161
- ],
1162
- discriminator: [
1163
- 183,
1164
- 18,
1165
- 70,
1166
- 156,
1167
- 148,
1168
- 109,
1169
- 161,
1170
- 34
1171
- ],
1172
- accounts: [
1173
- {
1174
- name: "user",
1175
- docs: [
1176
- "User performing the withdrawal"
1177
- ],
1178
- writable: true,
1179
- signer: true
1180
- },
1181
- {
1182
- name: "jlp_vault",
1183
- docs: [
1184
- "The JLP Vault PDA account",
1185
- "Note: PDA verified in handler via get_pda() to avoid multiple loads"
1186
- ]
1187
- },
1188
- {
1189
- name: "stv",
1190
- docs: [
1191
- "The STV PDA account",
1192
- "Note: PDA verified in handler via get_pda() to avoid multiple loads"
1193
- ],
1194
- writable: true
1195
- },
1196
- {
1197
- name: "base_mint",
1198
- docs: [
1199
- "Base asset mint (underlying token: SOL, BTC, ETH, USDC)"
1200
- ]
1201
- },
1202
- {
1203
- name: "jl_mint",
1204
- docs: [
1205
- "jlX mint (Jupiter Lend token) - used for NAV calculation"
1206
- ]
1207
- },
1208
- {
1209
- name: "jv_mint",
1210
- docs: [
1211
- "jvX mint (vault share token) - STV is mint authority",
1212
- "Verified against STV.jv_mint in handler"
1213
- ],
1214
- writable: true
1215
- },
1216
- {
1217
- name: "user_base_ata",
1218
- docs: [
1219
- "User's base asset token account (destination for withdrawal)"
1220
- ],
1221
- writable: true
1222
- },
1223
- {
1224
- name: "user_jvx_ata",
1225
- docs: [
1226
- "User's jvX token account (source - shares to burn)"
1227
- ],
1228
- writable: true
1229
- },
1230
- {
1231
- name: "stv_base_ata",
1232
- docs: [
1233
- "STV's base ATA (source for base tokens to user)"
1234
- ],
1235
- writable: true
1236
- },
1237
- {
1238
- name: "stv_jlx_ata",
1239
- docs: [
1240
- "STV's jlX ATA (used for NAV calculation)"
1241
- ]
1242
- },
1243
- {
1244
- name: "token_program",
1245
- docs: [
1246
- "Token program"
1247
- ]
1248
- }
1249
- ],
1250
- args: [
1251
- {
1252
- name: "shares_to_burn",
1253
- type: "u64"
1254
- }
1255
- ]
1256
1469
  }
1257
1470
  ],
1258
1471
  accounts: [
@@ -1281,6 +1494,19 @@ var jlp_d_program_default = {
1281
1494
  17,
1282
1495
  230
1283
1496
  ]
1497
+ },
1498
+ {
1499
+ name: "WithdrawRequest",
1500
+ discriminator: [
1501
+ 186,
1502
+ 239,
1503
+ 174,
1504
+ 191,
1505
+ 189,
1506
+ 13,
1507
+ 47,
1508
+ 196
1509
+ ]
1284
1510
  }
1285
1511
  ],
1286
1512
  events: [
@@ -1297,6 +1523,32 @@ var jlp_d_program_default = {
1297
1523
  57
1298
1524
  ]
1299
1525
  },
1526
+ {
1527
+ name: "EpochAdvanced",
1528
+ discriminator: [
1529
+ 41,
1530
+ 220,
1531
+ 14,
1532
+ 123,
1533
+ 117,
1534
+ 70,
1535
+ 117,
1536
+ 157
1537
+ ]
1538
+ },
1539
+ {
1540
+ name: "EpochProcessed",
1541
+ discriminator: [
1542
+ 18,
1543
+ 238,
1544
+ 2,
1545
+ 247,
1546
+ 238,
1547
+ 178,
1548
+ 94,
1549
+ 138
1550
+ ]
1551
+ },
1300
1552
  {
1301
1553
  name: "FeesClaimSkipped",
1302
1554
  discriminator: [
@@ -1467,16 +1719,29 @@ var jlp_d_program_default = {
1467
1719
  ]
1468
1720
  },
1469
1721
  {
1470
- name: "Withdrawn",
1722
+ name: "WithdrawClaimed",
1471
1723
  discriminator: [
1472
- 20,
1724
+ 77,
1725
+ 130,
1473
1726
  89,
1474
- 223,
1475
- 198,
1476
- 194,
1477
- 124,
1478
- 219,
1479
- 13
1727
+ 38,
1728
+ 239,
1729
+ 172,
1730
+ 174,
1731
+ 85
1732
+ ]
1733
+ },
1734
+ {
1735
+ name: "WithdrawRequested",
1736
+ discriminator: [
1737
+ 114,
1738
+ 16,
1739
+ 240,
1740
+ 206,
1741
+ 93,
1742
+ 128,
1743
+ 151,
1744
+ 39
1480
1745
  ]
1481
1746
  }
1482
1747
  ],
@@ -1707,14 +1972,132 @@ var jlp_d_program_default = {
1707
1972
  msg: "Test mode required: FLAG_TEST_MODE must be set for devnet/localnet builds"
1708
1973
  },
1709
1974
  {
1710
- code: 6045,
1711
- name: "NotAdmin",
1712
- msg: "Unauthorized: not admin"
1713
- }
1714
- ],
1715
- types: [
1716
- {
1717
- name: "Deposited",
1975
+ code: 6045,
1976
+ name: "NotAdmin",
1977
+ msg: "Unauthorized: not admin"
1978
+ },
1979
+ {
1980
+ code: 6046,
1981
+ name: "TokenAccountNotEmpty",
1982
+ msg: "Token account balance must be zero before closing"
1983
+ },
1984
+ {
1985
+ code: 6047,
1986
+ name: "TokenAccountOwnerMismatch",
1987
+ msg: "Token account not owned by expected PDA"
1988
+ },
1989
+ {
1990
+ code: 6048,
1991
+ name: "EpochEnded",
1992
+ msg: "Epoch has ended - call process_epoch first"
1993
+ },
1994
+ {
1995
+ code: 6049,
1996
+ name: "EpochNotEnded",
1997
+ msg: "Epoch has not ended yet"
1998
+ },
1999
+ {
2000
+ code: 6050,
2001
+ name: "ClaimNotAvailableYet",
2002
+ msg: "Claim not available yet - wait for next epoch"
2003
+ },
2004
+ {
2005
+ code: 6051,
2006
+ name: "InvalidEpochInterval",
2007
+ msg: "Withdraw epoch interval must be > 0"
2008
+ },
2009
+ {
2010
+ code: 6052,
2011
+ name: "ActiveWithdrawReserves",
2012
+ msg: "Cannot update epoch interval with active reserves"
2013
+ },
2014
+ {
2015
+ code: 6053,
2016
+ name: "EpochIdMismatch",
2017
+ msg: "Epoch ID mismatch"
2018
+ },
2019
+ {
2020
+ code: 6054,
2021
+ name: "WithdrawRequestNotProcessed",
2022
+ msg: "Withdraw request not processed yet"
2023
+ },
2024
+ {
2025
+ code: 6055,
2026
+ name: "WithdrawRequestAlreadyProcessed",
2027
+ msg: "Withdraw request already processed"
2028
+ }
2029
+ ],
2030
+ types: [
2031
+ {
2032
+ name: "Deposited",
2033
+ type: {
2034
+ kind: "struct",
2035
+ fields: [
2036
+ {
2037
+ name: "stv",
2038
+ type: "pubkey"
2039
+ },
2040
+ {
2041
+ name: "user",
2042
+ type: "pubkey"
2043
+ },
2044
+ {
2045
+ name: "amount_base",
2046
+ docs: [
2047
+ "Amount of base asset deposited"
2048
+ ],
2049
+ type: "u64"
2050
+ },
2051
+ {
2052
+ name: "shares_minted",
2053
+ type: "u64"
2054
+ },
2055
+ {
2056
+ name: "pps",
2057
+ type: "u64"
2058
+ }
2059
+ ]
2060
+ }
2061
+ },
2062
+ {
2063
+ name: "Direction",
2064
+ docs: [
2065
+ "Direction of jlX token movement between STV and Vault"
2066
+ ],
2067
+ type: {
2068
+ kind: "enum",
2069
+ variants: [
2070
+ {
2071
+ name: "ToVault"
2072
+ },
2073
+ {
2074
+ name: "FromVault"
2075
+ }
2076
+ ]
2077
+ }
2078
+ },
2079
+ {
2080
+ name: "EpochAdvanced",
2081
+ type: {
2082
+ kind: "struct",
2083
+ fields: [
2084
+ {
2085
+ name: "stv",
2086
+ type: "pubkey"
2087
+ },
2088
+ {
2089
+ name: "new_epoch_id",
2090
+ type: "u32"
2091
+ },
2092
+ {
2093
+ name: "new_next_epoch_ts",
2094
+ type: "u32"
2095
+ }
2096
+ ]
2097
+ }
2098
+ },
2099
+ {
2100
+ name: "EpochProcessed",
1718
2101
  type: {
1719
2102
  kind: "struct",
1720
2103
  fields: [
@@ -1723,40 +2106,28 @@ var jlp_d_program_default = {
1723
2106
  type: "pubkey"
1724
2107
  },
1725
2108
  {
1726
- name: "user",
1727
- type: "pubkey"
2109
+ name: "epoch_id",
2110
+ type: "u32"
1728
2111
  },
1729
2112
  {
1730
- name: "amount_base",
1731
- docs: [
1732
- "Amount of base asset deposited"
1733
- ],
2113
+ name: "pps",
1734
2114
  type: "u64"
1735
2115
  },
1736
2116
  {
1737
- name: "shares_minted",
2117
+ name: "total_shares",
1738
2118
  type: "u64"
1739
2119
  },
1740
2120
  {
1741
- name: "pps",
2121
+ name: "total_base",
1742
2122
  type: "u64"
1743
- }
1744
- ]
1745
- }
1746
- },
1747
- {
1748
- name: "Direction",
1749
- docs: [
1750
- "Direction of jlX token movement between STV and Vault"
1751
- ],
1752
- type: {
1753
- kind: "enum",
1754
- variants: [
2123
+ },
1755
2124
  {
1756
- name: "ToVault"
2125
+ name: "new_epoch_id",
2126
+ type: "u32"
1757
2127
  },
1758
2128
  {
1759
- name: "FromVault"
2129
+ name: "new_next_epoch_ts",
2130
+ type: "u32"
1760
2131
  }
1761
2132
  ]
1762
2133
  }
@@ -1946,6 +2317,13 @@ var jlp_d_program_default = {
1946
2317
  "Minimum deposit amount in base asset (0 = no minimum)"
1947
2318
  ],
1948
2319
  type: "u64"
2320
+ },
2321
+ {
2322
+ name: "epoch_sec",
2323
+ docs: [
2324
+ "Epoch duration in seconds for delayed withdrawals"
2325
+ ],
2326
+ type: "u32"
1949
2327
  }
1950
2328
  ]
1951
2329
  }
@@ -2391,7 +2769,7 @@ var jlp_d_program_default = {
2391
2769
  docs: [
2392
2770
  "STV - Single Token Vault account",
2393
2771
  'Seeds: ["stv", base_mint.key().as_ref()]',
2394
- "Size: 8 (discriminator) + 160 (data) = 168 bytes"
2772
+ "Size: 8 (discriminator) + 200 (data) = 208 bytes"
2395
2773
  ],
2396
2774
  serialization: "bytemuck",
2397
2775
  repr: {
@@ -2473,6 +2851,50 @@ var jlp_d_program_default = {
2473
2851
  ],
2474
2852
  type: "u64"
2475
2853
  },
2854
+ {
2855
+ name: "requested_base",
2856
+ docs: [
2857
+ "Estimated base for current epoch's withdrawal requests (reset on process_epoch)",
2858
+ "Manager reads this to know how much to unwind before next epoch"
2859
+ ],
2860
+ type: "u64"
2861
+ },
2862
+ {
2863
+ name: "reserved_base",
2864
+ docs: [
2865
+ "Base earmarked for unclaimed withdrawals (+process_epoch, -claim_withdraw)",
2866
+ "Subtracted from NAV so reserved funds don't inflate PPS"
2867
+ ],
2868
+ type: "u64"
2869
+ },
2870
+ {
2871
+ name: "epoch_pps",
2872
+ docs: [
2873
+ "PPS locked at first process_epoch batch (0 = not set, reset on epoch advance)"
2874
+ ],
2875
+ type: "u64"
2876
+ },
2877
+ {
2878
+ name: "next_epoch_ts",
2879
+ docs: [
2880
+ "Unix timestamp when current epoch ends"
2881
+ ],
2882
+ type: "u32"
2883
+ },
2884
+ {
2885
+ name: "epoch_sec",
2886
+ docs: [
2887
+ "Epoch duration in seconds"
2888
+ ],
2889
+ type: "u32"
2890
+ },
2891
+ {
2892
+ name: "current_epoch_id",
2893
+ docs: [
2894
+ "Incrementing epoch counter"
2895
+ ],
2896
+ type: "u32"
2897
+ },
2476
2898
  {
2477
2899
  name: "mgmt_fee_bps",
2478
2900
  docs: [
@@ -2507,6 +2929,18 @@ var jlp_d_program_default = {
2507
2929
  "PDA bump seed"
2508
2930
  ],
2509
2931
  type: "u8"
2932
+ },
2933
+ {
2934
+ name: "_padding",
2935
+ docs: [
2936
+ "Alignment padding"
2937
+ ],
2938
+ type: {
2939
+ array: [
2940
+ "u8",
2941
+ 4
2942
+ ]
2943
+ }
2510
2944
  }
2511
2945
  ]
2512
2946
  }
@@ -2870,12 +3304,21 @@ var jlp_d_program_default = {
2870
3304
  type: {
2871
3305
  option: "u64"
2872
3306
  }
3307
+ },
3308
+ {
3309
+ name: "epoch_sec",
3310
+ docs: [
3311
+ "Optional new epoch duration in seconds"
3312
+ ],
3313
+ type: {
3314
+ option: "u32"
3315
+ }
2873
3316
  }
2874
3317
  ]
2875
3318
  }
2876
3319
  },
2877
3320
  {
2878
- name: "Withdrawn",
3321
+ name: "WithdrawClaimed",
2879
3322
  type: {
2880
3323
  kind: "struct",
2881
3324
  fields: [
@@ -2888,19 +3331,113 @@ var jlp_d_program_default = {
2888
3331
  type: "pubkey"
2889
3332
  },
2890
3333
  {
2891
- name: "shares_burned",
3334
+ name: "shares",
2892
3335
  type: "u64"
2893
3336
  },
2894
3337
  {
2895
- name: "amount_base",
3338
+ name: "base_amount",
3339
+ type: "u64"
3340
+ },
3341
+ {
3342
+ name: "epoch_id",
3343
+ type: "u32"
3344
+ }
3345
+ ]
3346
+ }
3347
+ },
3348
+ {
3349
+ name: "WithdrawRequest",
3350
+ docs: [
3351
+ "WithdrawRequest - Per-user per-epoch withdrawal request",
3352
+ 'Seeds: ["withdraw_request", stv.key(), user.key(), &epoch_id.to_le_bytes()]',
3353
+ "",
3354
+ "One PDA per user per STV per epoch. Multiple request_withdraw calls",
3355
+ "in the same epoch accumulate into the same PDA.",
3356
+ "",
3357
+ "Lifecycle:",
3358
+ "1. Created by request_withdraw (user escrows jvX into request's ATA)",
3359
+ "2. Processed by process_epoch (jvX burned, pps + claim_available_after set)",
3360
+ "3. Closed by claim_withdraw (base transferred, PDA + ATA closed)"
3361
+ ],
3362
+ type: {
3363
+ kind: "struct",
3364
+ fields: [
3365
+ {
3366
+ name: "stv",
3367
+ docs: [
3368
+ "Back-reference to the STV"
3369
+ ],
3370
+ type: "pubkey"
3371
+ },
3372
+ {
3373
+ name: "user",
3374
+ docs: [
3375
+ "The user who requested the withdrawal"
3376
+ ],
3377
+ type: "pubkey"
3378
+ },
3379
+ {
3380
+ name: "shares",
2896
3381
  docs: [
2897
- "Amount of base asset withdrawn"
3382
+ "Total jvX shares escrowed (accumulated across multiple requests in same epoch)"
2898
3383
  ],
2899
3384
  type: "u64"
2900
3385
  },
2901
3386
  {
2902
3387
  name: "pps",
3388
+ docs: [
3389
+ "PPS at process time (0 = unprocessed)"
3390
+ ],
3391
+ type: "u64"
3392
+ },
3393
+ {
3394
+ name: "epoch_id",
3395
+ docs: [
3396
+ "Epoch when request was made"
3397
+ ],
3398
+ type: "u32"
3399
+ },
3400
+ {
3401
+ name: "claim_available_after",
3402
+ docs: [
3403
+ "Unix timestamp after which claim is available (0 = unprocessed)"
3404
+ ],
3405
+ type: "u32"
3406
+ },
3407
+ {
3408
+ name: "bump",
3409
+ docs: [
3410
+ "PDA bump seed"
3411
+ ],
3412
+ type: "u8"
3413
+ }
3414
+ ]
3415
+ }
3416
+ },
3417
+ {
3418
+ name: "WithdrawRequested",
3419
+ type: {
3420
+ kind: "struct",
3421
+ fields: [
3422
+ {
3423
+ name: "stv",
3424
+ type: "pubkey"
3425
+ },
3426
+ {
3427
+ name: "user",
3428
+ type: "pubkey"
3429
+ },
3430
+ {
3431
+ name: "shares",
3432
+ type: "u64"
3433
+ },
3434
+ {
3435
+ name: "total_shares",
2903
3436
  type: "u64"
3437
+ },
3438
+ {
3439
+ name: "epoch_id",
3440
+ type: "u32"
2904
3441
  }
2905
3442
  ]
2906
3443
  }
@@ -2935,6 +3472,7 @@ var JUPITER_SWAP_PROGRAM_ID = new import_web32.PublicKey(
2935
3472
  );
2936
3473
  var SEED_JLP_VAULT = "jlp_vault";
2937
3474
  var SEED_STV = "stv";
3475
+ var SEED_WITHDRAW_REQUEST = "withdraw_request";
2938
3476
  var FLAG_PAUSED = 1;
2939
3477
  var FLAG_DEPOSITS_DISABLED = 2;
2940
3478
  var FLAG_WITHDRAWALS_DISABLED = 4;
@@ -2971,6 +3509,7 @@ var JUPITER_PERPS_PROGRAM_ID = new import_web32.PublicKey("PERPHjGBqRHArX4DySjwM
2971
3509
  var import_web33 = require("@solana/web3.js");
2972
3510
  var SEED_JLP_VAULT_BUFFER = Buffer.from(SEED_JLP_VAULT);
2973
3511
  var SEED_STV_BUFFER = Buffer.from(SEED_STV);
3512
+ var SEED_WITHDRAW_REQUEST_BUFFER = Buffer.from(SEED_WITHDRAW_REQUEST);
2974
3513
  var pdaCache = /* @__PURE__ */ new Map();
2975
3514
  function deriveVaultPda(programId) {
2976
3515
  const key = `vault:${programId.toBase58()}`;
@@ -2996,6 +3535,20 @@ function deriveStvPda(baseMint, programId) {
2996
3535
  }
2997
3536
  return cached;
2998
3537
  }
3538
+ function deriveWithdrawRequestPda(stvPda, user, epochId, programId) {
3539
+ const key = `wr:${stvPda.toBase58()}:${user.toBase58()}:${epochId}:${programId.toBase58()}`;
3540
+ let cached = pdaCache.get(key);
3541
+ if (!cached) {
3542
+ const epochIdBuffer = Buffer.alloc(4);
3543
+ epochIdBuffer.writeUInt32LE(epochId);
3544
+ cached = import_web33.PublicKey.findProgramAddressSync(
3545
+ [SEED_WITHDRAW_REQUEST_BUFFER, stvPda.toBuffer(), user.toBuffer(), epochIdBuffer],
3546
+ programId
3547
+ );
3548
+ pdaCache.set(key, cached);
3549
+ }
3550
+ return cached;
3551
+ }
2999
3552
  function clearPdaCache() {
3000
3553
  pdaCache.clear();
3001
3554
  }
@@ -3074,7 +3627,7 @@ function parseVault(data) {
3074
3627
  // src/accounts/stv.ts
3075
3628
  var import_web35 = require("@solana/web3.js");
3076
3629
  var import_anchor3 = require("@coral-xyz/anchor");
3077
- var STV_DATA_SIZE = 160;
3630
+ var STV_DATA_SIZE = 200;
3078
3631
  var STV_ACCOUNT_SIZE = 8 + STV_DATA_SIZE;
3079
3632
  var STV_DISCRIMINATOR = Buffer.from([
3080
3633
  214,
@@ -3119,6 +3672,18 @@ function parseStv(data) {
3119
3672
  offset += 8;
3120
3673
  const minDeposit = new import_anchor3.BN(data.subarray(offset, offset + 8), "le");
3121
3674
  offset += 8;
3675
+ const requestedBase = new import_anchor3.BN(data.subarray(offset, offset + 8), "le");
3676
+ offset += 8;
3677
+ const reservedBase = new import_anchor3.BN(data.subarray(offset, offset + 8), "le");
3678
+ offset += 8;
3679
+ const epochPps = new import_anchor3.BN(data.subarray(offset, offset + 8), "le");
3680
+ offset += 8;
3681
+ const nextEpochTs = data.readUInt32LE(offset);
3682
+ offset += 4;
3683
+ const epochSec = data.readUInt32LE(offset);
3684
+ offset += 4;
3685
+ const currentEpochId = data.readUInt32LE(offset);
3686
+ offset += 4;
3122
3687
  const mgmtFeeBps = data.readUInt16LE(offset);
3123
3688
  offset += 2;
3124
3689
  const perfFeeBps = data.readUInt16LE(offset);
@@ -3128,7 +3693,6 @@ function parseStv(data) {
3128
3693
  const version = data.readUInt8(offset);
3129
3694
  offset += 1;
3130
3695
  const bump = data.readUInt8(offset);
3131
- offset += 1;
3132
3696
  return {
3133
3697
  baseMint,
3134
3698
  jlMint,
@@ -3140,6 +3704,12 @@ function parseStv(data) {
3140
3704
  accruedFeesJlx,
3141
3705
  maxDeposit,
3142
3706
  minDeposit,
3707
+ requestedBase,
3708
+ reservedBase,
3709
+ epochPps,
3710
+ nextEpochTs,
3711
+ epochSec,
3712
+ currentEpochId,
3143
3713
  mgmtFeeBps,
3144
3714
  perfFeeBps,
3145
3715
  flags,
@@ -3190,9 +3760,13 @@ var EXCHANGE_RATE_PRECISION_BI = BigInt(EXCHANGE_RATE_PRECISION);
3190
3760
  var RETURN_PERCENT_PRECISION = EXCHANGE_RATE_PRECISION_BI * 100n;
3191
3761
  var SECONDS_PER_YEAR = BigInt(365 * 24 * 60 * 60);
3192
3762
  var MAX_REWARDS_RATE = 50n * EXCHANGE_RATE_PRECISION_BI;
3193
- function calculateNav(stvBaseBalance, stvJlxBalance, exchangeRate, baseLoaned) {
3763
+ function calculateNav(stvBaseBalance, stvJlxBalance, exchangeRate, baseLoaned, reservedBase) {
3194
3764
  const jlxValue = stvJlxBalance.mul(new import_anchor4.BN(exchangeRate.toString())).div(EXCHANGE_RATE_PRECISION_BN);
3195
- return stvBaseBalance.add(jlxValue).add(baseLoaned);
3765
+ let nav = stvBaseBalance.add(jlxValue).add(baseLoaned);
3766
+ if (reservedBase && !reservedBase.isZero()) {
3767
+ nav = nav.sub(reservedBase);
3768
+ }
3769
+ return nav;
3196
3770
  }
3197
3771
  function calculatePps(nav, jvSupply) {
3198
3772
  if (jvSupply.isZero()) {
@@ -3639,7 +4213,8 @@ async function createInitializeStvInstruction(program, params, accounts) {
3639
4213
  mgmtFeeBps: params.mgmtFeeBps,
3640
4214
  perfFeeBps: params.perfFeeBps,
3641
4215
  maxDeposit: params.maxDeposit,
3642
- minDeposit: params.minDeposit
4216
+ minDeposit: params.minDeposit,
4217
+ epochSec: params.epochSec
3643
4218
  }).accounts({
3644
4219
  admin: accounts.admin,
3645
4220
  jlpVault: accounts.jlpVault,
@@ -3659,7 +4234,8 @@ async function createUpdateStvInstruction(program, params, accounts) {
3659
4234
  jlMint: params.jlMint,
3660
4235
  pps: params.pps,
3661
4236
  hwm: params.hwm,
3662
- baseLoaned: params.baseLoaned
4237
+ baseLoaned: params.baseLoaned,
4238
+ epochSec: params.epochSec
3663
4239
  }).accounts({
3664
4240
  admin: accounts.admin,
3665
4241
  jlpVault: accounts.jlpVault,
@@ -3683,20 +4259,32 @@ async function createDepositInstruction(program, amount, accounts, remainingAcco
3683
4259
  tokenProgram: accounts.tokenProgram
3684
4260
  }).remainingAccounts(remainingAccounts).instruction();
3685
4261
  }
3686
- async function createWithdrawInstruction(program, sharesToBurn, accounts, remainingAccounts = []) {
3687
- return await program.methods.withdraw(sharesToBurn).accounts({
4262
+ async function createRequestWithdrawInstruction(program, params, accounts) {
4263
+ return await program.methods.requestWithdraw(params.shares, params.epochId).accounts({
3688
4264
  user: accounts.user,
3689
4265
  jlpVault: accounts.jlpVault,
3690
4266
  stv: accounts.stv,
4267
+ jvMint: accounts.jvMint,
4268
+ userJvxAta: accounts.userJvxAta,
4269
+ withdrawRequest: accounts.withdrawRequest,
4270
+ requestJvxAta: accounts.requestJvxAta,
4271
+ tokenProgram: accounts.tokenProgram,
4272
+ associatedTokenProgram: accounts.associatedTokenProgram,
4273
+ systemProgram: accounts.systemProgram
4274
+ }).instruction();
4275
+ }
4276
+ async function createClaimWithdrawInstruction(program, accounts) {
4277
+ return await program.methods.claimWithdraw().accounts({
4278
+ user: accounts.user,
4279
+ stv: accounts.stv,
3691
4280
  baseMint: accounts.baseMint,
3692
- jlMint: accounts.jlMint,
3693
4281
  jvMint: accounts.jvMint,
3694
4282
  userBaseAta: accounts.userBaseAta,
3695
- userJvxAta: accounts.userJvxAta,
3696
4283
  stvBaseAta: accounts.stvBaseAta,
3697
- stvJlxAta: accounts.stvJlxAta,
4284
+ withdrawRequest: accounts.withdrawRequest,
4285
+ requestJvxAta: accounts.requestJvxAta,
3698
4286
  tokenProgram: accounts.tokenProgram
3699
- }).remainingAccounts(remainingAccounts).instruction();
4287
+ }).instruction();
3700
4288
  }
3701
4289
 
3702
4290
  // src/instructions/manager.ts
@@ -3755,6 +4343,19 @@ async function createSwapJlxJlpInstruction(program, params, accounts, remainingA
3755
4343
  jupiterProgram: accounts.jupiterProgram
3756
4344
  }).remainingAccounts(remainingAccounts).instruction();
3757
4345
  }
4346
+ async function createProcessEpochInstruction(program, accounts, remainingAccounts = []) {
4347
+ return await program.methods.processEpoch().accounts({
4348
+ payer: accounts.payer,
4349
+ jlpVault: accounts.jlpVault,
4350
+ stv: accounts.stv,
4351
+ baseMint: accounts.baseMint,
4352
+ jlMint: accounts.jlMint,
4353
+ jvMint: accounts.jvMint,
4354
+ stvBaseAta: accounts.stvBaseAta,
4355
+ stvJlxAta: accounts.stvJlxAta,
4356
+ tokenProgram: accounts.tokenProgram
4357
+ }).remainingAccounts(remainingAccounts).instruction();
4358
+ }
3758
4359
  async function createSettleYieldInstruction(program, params, accounts, remainingAccounts = []) {
3759
4360
  return await program.methods.settleYield().accounts({
3760
4361
  jlpVault: accounts.jlpVault,
@@ -4044,8 +4645,8 @@ var PoolContext = class {
4044
4645
  }).compileToV0Message();
4045
4646
  return new import_web39.VersionedTransaction(message);
4046
4647
  }
4047
- // Burn jvX shares and withdraw base asset
4048
- async withdraw(params) {
4648
+ // Request withdrawal: escrow jvX shares for the current epoch
4649
+ async requestWithdraw(params) {
4049
4650
  if (params.shares.isZero() || params.shares.isNeg()) {
4050
4651
  throw new JlpdClientError("Withdraw shares must be positive");
4051
4652
  }
@@ -4054,28 +4655,66 @@ var PoolContext = class {
4054
4655
  this.client.connection.getLatestBlockhash("confirmed")
4055
4656
  ]);
4056
4657
  if (!stv) throw new JlpdClientError("STV not found");
4658
+ const epochId = stv.currentEpochId;
4659
+ const [withdrawRequestPda] = deriveWithdrawRequestPda(
4660
+ this.stvPda,
4661
+ params.user,
4662
+ epochId,
4663
+ this.client.programId
4664
+ );
4665
+ const requestJvxAta = (0, import_spl_token5.getAssociatedTokenAddressSync)(stv.jvMint, withdrawRequestPda, true);
4057
4666
  const userAtas = deriveUserAtas(this.pool.mint, stv.jvMint, params.user);
4058
- const erAccounts = this.pool.hasJupiterLend ? buildExchangeRateAccounts(this.pool) : null;
4059
- const ix = await createWithdrawInstruction(
4667
+ const ix = await createRequestWithdrawInstruction(
4060
4668
  this.client.program,
4061
- params.shares,
4669
+ { shares: params.shares, epochId },
4062
4670
  {
4063
4671
  user: params.user,
4064
4672
  jlpVault: this.client.vaultPda,
4065
4673
  stv: this.stvPda,
4674
+ jvMint: stv.jvMint,
4675
+ userJvxAta: userAtas.jvxAta,
4676
+ withdrawRequest: withdrawRequestPda,
4677
+ requestJvxAta,
4678
+ tokenProgram: import_spl_token5.TOKEN_PROGRAM_ID,
4679
+ associatedTokenProgram: import_spl_token5.ASSOCIATED_TOKEN_PROGRAM_ID,
4680
+ systemProgram: import_web39.SystemProgram.programId
4681
+ }
4682
+ );
4683
+ const message = new import_web39.TransactionMessage({
4684
+ payerKey: params.user,
4685
+ recentBlockhash: blockhash,
4686
+ instructions: [ix]
4687
+ }).compileToV0Message();
4688
+ return new import_web39.VersionedTransaction(message);
4689
+ }
4690
+ // Claim withdrawal: receive base tokens for a processed WithdrawRequest
4691
+ async claimWithdraw(params) {
4692
+ const [stv, { blockhash }] = await Promise.all([
4693
+ this.client.fetchStv(this.pool.mint),
4694
+ this.client.connection.getLatestBlockhash("confirmed")
4695
+ ]);
4696
+ if (!stv) throw new JlpdClientError("STV not found");
4697
+ const [withdrawRequestPda] = deriveWithdrawRequestPda(
4698
+ this.stvPda,
4699
+ params.user,
4700
+ params.epochId,
4701
+ this.client.programId
4702
+ );
4703
+ const requestJvxAta = (0, import_spl_token5.getAssociatedTokenAddressSync)(stv.jvMint, withdrawRequestPda, true);
4704
+ const userAtas = deriveUserAtas(this.pool.mint, stv.jvMint, params.user);
4705
+ const ix = await createClaimWithdrawInstruction(
4706
+ this.client.program,
4707
+ {
4708
+ user: params.user,
4709
+ stv: this.stvPda,
4066
4710
  baseMint: this.pool.mint,
4067
- jlMint: this.pool.fTokenMint,
4068
4711
  jvMint: stv.jvMint,
4069
4712
  userBaseAta: userAtas.baseAta,
4070
- userJvxAta: userAtas.jvxAta,
4071
4713
  stvBaseAta: this.stvBaseAta,
4072
- stvJlxAta: this.stvJlxAta,
4714
+ withdrawRequest: withdrawRequestPda,
4715
+ requestJvxAta,
4073
4716
  tokenProgram: import_spl_token5.TOKEN_PROGRAM_ID
4074
- },
4075
- erAccounts ? [
4076
- { pubkey: erAccounts.lending, isSigner: false, isWritable: false },
4077
- { pubkey: erAccounts.rewardsRateModel, isSigner: false, isWritable: false }
4078
- ] : []
4717
+ }
4079
4718
  );
4080
4719
  const message = new import_web39.TransactionMessage({
4081
4720
  payerKey: params.user,
@@ -4179,7 +4818,8 @@ var PoolContext = class {
4179
4818
  jlMint: params.jlMint ?? null,
4180
4819
  pps: params.pps ?? null,
4181
4820
  hwm: params.hwm ?? null,
4182
- baseLoaned: params.baseLoaned ?? null
4821
+ baseLoaned: params.baseLoaned ?? null,
4822
+ epochSec: params.epochSec ?? null
4183
4823
  },
4184
4824
  {
4185
4825
  admin: params.admin,
@@ -4303,7 +4943,8 @@ var AdminContext = class {
4303
4943
  mgmtFeeBps: params.mgmtFeeBps,
4304
4944
  perfFeeBps: params.perfFeeBps,
4305
4945
  maxDeposit: params.maxDeposit,
4306
- minDeposit: params.minDeposit
4946
+ minDeposit: params.minDeposit,
4947
+ epochSec: params.withdrawEpochSec
4307
4948
  },
4308
4949
  {
4309
4950
  admin: params.admin,
@@ -4316,6 +4957,46 @@ var AdminContext = class {
4316
4957
  );
4317
4958
  return this.client.buildTransaction(params.admin, [ix]);
4318
4959
  }
4960
+ // Process epoch for a pool (manager operation)
4961
+ async processEpoch(params) {
4962
+ const pool = getPoolByName(params.poolName);
4963
+ if (!pool) throw new JlpdClientError(`Unknown pool: ${params.poolName}`);
4964
+ const [stvPda] = deriveStvPda(pool.mint, this.client.programId);
4965
+ const stv = await this.client.fetchStv(pool.mint);
4966
+ if (!stv) throw new JlpdClientError(`STV not found for pool: ${params.poolName}`);
4967
+ const stvAtas = deriveStvAtas(pool.mint, pool.fTokenMint, stvPda);
4968
+ const erAccounts = pool.hasJupiterLend ? buildExchangeRateAccounts(pool) : null;
4969
+ const remainingAccounts = [];
4970
+ if (erAccounts) {
4971
+ remainingAccounts.push(
4972
+ { pubkey: erAccounts.lending, isSigner: false, isWritable: false },
4973
+ { pubkey: erAccounts.rewardsRateModel, isSigner: false, isWritable: false }
4974
+ );
4975
+ }
4976
+ for (const wrPubkey of params.withdrawRequests) {
4977
+ const requestJvxAta = (0, import_spl_token5.getAssociatedTokenAddressSync)(stv.jvMint, wrPubkey, true);
4978
+ remainingAccounts.push(
4979
+ { pubkey: wrPubkey, isSigner: false, isWritable: true },
4980
+ { pubkey: requestJvxAta, isSigner: false, isWritable: true }
4981
+ );
4982
+ }
4983
+ const ix = await createProcessEpochInstruction(
4984
+ this.client.program,
4985
+ {
4986
+ payer: params.payer,
4987
+ jlpVault: this.client.vaultPda,
4988
+ stv: stvPda,
4989
+ baseMint: pool.mint,
4990
+ jlMint: pool.fTokenMint,
4991
+ jvMint: stv.jvMint,
4992
+ stvBaseAta: stvAtas.baseAta,
4993
+ stvJlxAta: stvAtas.jlxAta,
4994
+ tokenProgram: import_spl_token5.TOKEN_PROGRAM_ID
4995
+ },
4996
+ remainingAccounts
4997
+ );
4998
+ return this.client.buildTransaction(params.payer, [ix]);
4999
+ }
4319
5000
  // Settle yield across all STVs
4320
5001
  async settleYield(params) {
4321
5002
  const poolNames = ["BTC", "ETH", "SOL", "USDC", "JupUSD"];
@@ -4373,6 +5054,50 @@ var AdminContext = class {
4373
5054
  return this.client.buildTransaction(params.manager, [ix]);
4374
5055
  }
4375
5056
  };
5057
+
5058
+ // src/accounts/withdraw_request.ts
5059
+ var import_web310 = require("@solana/web3.js");
5060
+ var import_anchor7 = require("@coral-xyz/anchor");
5061
+ var WITHDRAW_REQUEST_DATA_SIZE = 89;
5062
+ var WITHDRAW_REQUEST_ACCOUNT_SIZE = 8 + WITHDRAW_REQUEST_DATA_SIZE;
5063
+ var WITHDRAW_REQUEST_DISCRIMINATOR = Buffer.from([
5064
+ 186,
5065
+ 239,
5066
+ 174,
5067
+ 191,
5068
+ 189,
5069
+ 13,
5070
+ 47,
5071
+ 196
5072
+ ]);
5073
+ function parseWithdrawRequest(data) {
5074
+ if (data.length < WITHDRAW_REQUEST_ACCOUNT_SIZE) {
5075
+ throw new Error(
5076
+ `Invalid WithdrawRequest data size: expected ${WITHDRAW_REQUEST_ACCOUNT_SIZE}, got ${data.length}`
5077
+ );
5078
+ }
5079
+ const discriminator = data.subarray(0, 8);
5080
+ if (!discriminator.equals(WITHDRAW_REQUEST_DISCRIMINATOR)) {
5081
+ throw new Error(
5082
+ `Invalid WithdrawRequest discriminator: expected ${WITHDRAW_REQUEST_DISCRIMINATOR.toString("hex")}, got ${discriminator.toString("hex")}`
5083
+ );
5084
+ }
5085
+ let offset = 8;
5086
+ const stv = new import_web310.PublicKey(data.subarray(offset, offset + 32));
5087
+ offset += 32;
5088
+ const user = new import_web310.PublicKey(data.subarray(offset, offset + 32));
5089
+ offset += 32;
5090
+ const shares = new import_anchor7.BN(data.subarray(offset, offset + 8), "le");
5091
+ offset += 8;
5092
+ const pps = new import_anchor7.BN(data.subarray(offset, offset + 8), "le");
5093
+ offset += 8;
5094
+ const epochId = data.readUInt32LE(offset);
5095
+ offset += 4;
5096
+ const claimAvailableAfter = data.readUInt32LE(offset);
5097
+ offset += 4;
5098
+ const bump = data.readUInt8(offset);
5099
+ return { stv, user, shares, pps, epochId, claimAvailableAfter, bump };
5100
+ }
4376
5101
  // Annotate the CommonJS export names for ESM import in node:
4377
5102
  0 && (module.exports = {
4378
5103
  AdminContext,
@@ -4404,6 +5129,7 @@ var AdminContext = class {
4404
5129
  PoolContext,
4405
5130
  SEED_JLP_VAULT,
4406
5131
  SEED_STV,
5132
+ SEED_WITHDRAW_REQUEST,
4407
5133
  STV_ACCOUNT_SIZE,
4408
5134
  STV_DATA_SIZE,
4409
5135
  STV_DISCRIMINATOR,
@@ -4412,6 +5138,9 @@ var AdminContext = class {
4412
5138
  USDC_POOL,
4413
5139
  WBTC_POOL,
4414
5140
  WETH_POOL,
5141
+ WITHDRAW_REQUEST_ACCOUNT_SIZE,
5142
+ WITHDRAW_REQUEST_DATA_SIZE,
5143
+ WITHDRAW_REQUEST_DISCRIMINATOR,
4415
5144
  WSOL_POOL,
4416
5145
  baseToJlx,
4417
5146
  baseToShares,
@@ -4425,22 +5154,25 @@ var AdminContext = class {
4425
5154
  clearAtaCache,
4426
5155
  clearPdaCache,
4427
5156
  createClaimFeesInstruction,
5157
+ createClaimWithdrawInstruction,
4428
5158
  createDepositInstruction,
4429
5159
  createInitOrUpdateVaultInstruction,
4430
5160
  createInitializeStvInstruction,
4431
5161
  createJupEarnInstruction,
4432
5162
  createMoveJlxInstruction,
5163
+ createProcessEpochInstruction,
4433
5164
  createProgram,
5165
+ createRequestWithdrawInstruction,
4434
5166
  createSettleYieldInstruction,
4435
5167
  createSwapJlxJlpInstruction,
4436
5168
  createUpdateStvInstruction,
4437
- createWithdrawInstruction,
4438
5169
  deriveAta,
4439
5170
  deriveStvAtas,
4440
5171
  deriveStvPda,
4441
5172
  deriveUserAtas,
4442
5173
  deriveVaultAtas,
4443
5174
  deriveVaultPda,
5175
+ deriveWithdrawRequestPda,
4444
5176
  fetchAddressLookupTables,
4445
5177
  fetchJlpRate,
4446
5178
  fetchJupiterPriceUsd,
@@ -4454,5 +5186,6 @@ var AdminContext = class {
4454
5186
  parseStv,
4455
5187
  parseSwapRemainingAccounts,
4456
5188
  parseVault,
5189
+ parseWithdrawRequest,
4457
5190
  sharesToBase
4458
5191
  });