@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.mjs CHANGED
@@ -3,11 +3,13 @@ import {
3
3
  PublicKey as PublicKey8,
4
4
  TransactionMessage,
5
5
  VersionedTransaction,
6
- ComputeBudgetProgram
6
+ ComputeBudgetProgram,
7
+ SystemProgram as SystemProgram2
7
8
  } from "@solana/web3.js";
8
9
  import { BN as BN5 } from "@coral-xyz/anchor";
9
10
  import {
10
11
  TOKEN_PROGRAM_ID as TOKEN_PROGRAM_ID2,
12
+ ASSOCIATED_TOKEN_PROGRAM_ID as ASSOCIATED_TOKEN_PROGRAM_ID2,
11
13
  getAssociatedTokenAddressSync as getAssociatedTokenAddressSync2
12
14
  } from "@solana/spl-token";
13
15
 
@@ -108,66 +110,71 @@ var jlp_d_program_default = {
108
110
  args: []
109
111
  },
110
112
  {
111
- name: "close_stv",
113
+ name: "claim_withdraw",
112
114
  docs: [
113
- "Close an STV account and return rent to admin",
114
- "Destructive operation - use only for cleanup/migration",
115
+ "Claim processed withdrawal (epoch-based delayed withdrawal)",
115
116
  "",
116
- "# Safety Checks",
117
- "- Validates jvX supply is 0 (no active shares)",
118
- "- Validates base_loaned is 0 (no outstanding loans)",
119
- "- Validates accrued_fees_jlx is 0 (no unclaimed fees)"
117
+ "# Flow",
118
+ "1. Verify request is processed (pps > 0) and claim period reached",
119
+ "2. Transfer base from STV to user",
120
+ "3. Close request's jvX ATA and WithdrawRequest PDA (rent to user)"
120
121
  ],
121
122
  discriminator: [
122
- 173,
123
- 189,
124
- 151,
125
- 131,
126
- 240,
127
- 39,
128
- 199,
129
- 147
123
+ 232,
124
+ 89,
125
+ 154,
126
+ 117,
127
+ 16,
128
+ 204,
129
+ 182,
130
+ 224
130
131
  ],
131
132
  accounts: [
132
133
  {
133
- name: "admin",
134
+ name: "user",
134
135
  docs: [
135
- "Admin must sign - verified via vault.has_one = admin"
136
+ "User claiming their withdrawal"
136
137
  ],
137
138
  writable: true,
138
- signer: true,
139
- relations: [
140
- "jlp_vault"
139
+ signer: true
140
+ },
141
+ {
142
+ name: "stv",
143
+ docs: [
144
+ "The STV PDA account (mut for reserved_base update)"
145
+ ],
146
+ writable: true
147
+ },
148
+ {
149
+ name: "base_mint",
150
+ docs: [
151
+ "Base asset mint (for transfer_checked)"
141
152
  ]
142
153
  },
143
154
  {
144
- name: "jlp_vault",
155
+ name: "jv_mint",
145
156
  docs: [
146
- "JLP Vault for admin validation"
157
+ "jvX mint (for ATA close verification)"
158
+ ]
159
+ },
160
+ {
161
+ name: "user_base_ata",
162
+ docs: [
163
+ "User's base token destination"
147
164
  ],
148
- pda: {
149
- seeds: [
150
- {
151
- kind: "const",
152
- value: [
153
- 106,
154
- 108,
155
- 112,
156
- 95,
157
- 118,
158
- 97,
159
- 117,
160
- 108,
161
- 116
162
- ]
163
- }
164
- ]
165
- }
165
+ writable: true
166
166
  },
167
167
  {
168
- name: "stv",
168
+ name: "stv_base_ata",
169
169
  docs: [
170
- "STV to close"
170
+ "STV's base ATA (source for base transfer)"
171
+ ],
172
+ writable: true
173
+ },
174
+ {
175
+ name: "withdraw_request",
176
+ docs: [
177
+ "WithdrawRequest PDA - closed after claim (rent to user)"
171
178
  ],
172
179
  writable: true,
173
180
  pda: {
@@ -175,33 +182,49 @@ var jlp_d_program_default = {
175
182
  {
176
183
  kind: "const",
177
184
  value: [
178
- 115,
185
+ 119,
186
+ 105,
179
187
  116,
180
- 118
188
+ 104,
189
+ 100,
190
+ 114,
191
+ 97,
192
+ 119,
193
+ 95,
194
+ 114,
195
+ 101,
196
+ 113,
197
+ 117,
198
+ 101,
199
+ 115,
200
+ 116
181
201
  ]
182
202
  },
183
203
  {
184
204
  kind: "account",
185
- path: "base_mint"
205
+ path: "stv"
206
+ },
207
+ {
208
+ kind: "account",
209
+ path: "user"
210
+ },
211
+ {
212
+ kind: "account",
213
+ path: "withdraw_request.epoch_id",
214
+ account: "WithdrawRequest"
186
215
  }
187
216
  ]
188
217
  }
189
218
  },
190
219
  {
191
- name: "jv_mint",
192
- docs: [
193
- "jvX mint for this STV - used to verify no active shares"
194
- ]
195
- },
196
- {
197
- name: "base_mint",
220
+ name: "request_jvx_ata",
198
221
  docs: [
199
- "Base asset mint for this STV"
200
- ]
222
+ "Empty jvX ATA owned by WithdrawRequest PDA (to close, rent to user)"
223
+ ],
224
+ writable: true
201
225
  },
202
226
  {
203
- name: "system_program",
204
- address: "11111111111111111111111111111111"
227
+ name: "token_program"
205
228
  }
206
229
  ],
207
230
  args: []
@@ -463,7 +486,7 @@ var jlp_d_program_default = {
463
486
  name: "jv_mint",
464
487
  docs: [
465
488
  "Vault share token mint (jvX) - STV is the mint authority",
466
- "Client generates keypair and passes it as signer"
489
+ "Uses init_if_needed in case mint exists from a previous STV initialization"
467
490
  ],
468
491
  writable: true,
469
492
  signer: true
@@ -762,36 +785,335 @@ var jlp_d_program_default = {
762
785
  ]
763
786
  },
764
787
  {
765
- name: "stv_jlx_ata",
766
- docs: [
767
- "STV's jlX ATA",
768
- "For base-only pools, this is the base ATA (jl_mint == base_mint)"
769
- ],
770
- writable: true
788
+ name: "stv_jlx_ata",
789
+ docs: [
790
+ "STV's jlX ATA",
791
+ "For base-only pools, this is the base ATA (jl_mint == base_mint)"
792
+ ],
793
+ writable: true
794
+ },
795
+ {
796
+ name: "vault_staging_ata",
797
+ docs: [
798
+ "Vault's staging jlX ATA (for this specific jl_mint)",
799
+ "For base-only pools, this is the staging base ATA"
800
+ ],
801
+ writable: true
802
+ },
803
+ {
804
+ name: "token_program",
805
+ docs: [
806
+ "Token program"
807
+ ]
808
+ }
809
+ ],
810
+ args: [
811
+ {
812
+ name: "params",
813
+ type: {
814
+ defined: {
815
+ name: "MoveJlxParams"
816
+ }
817
+ }
818
+ }
819
+ ]
820
+ },
821
+ {
822
+ name: "process_epoch",
823
+ docs: [
824
+ "Process epoch: burn jvX from withdraw requests, record PPS, earmark base",
825
+ "",
826
+ "Permissionless (anyone can call after epoch ends).",
827
+ "Processes WithdrawRequest pairs from remaining_accounts.",
828
+ "Uses epoch_pps for multi-batch consistency.",
829
+ "",
830
+ "# Remaining Accounts",
831
+ "- [0-1]: Jupiter Lend accounts (if jl_mint != base_mint)",
832
+ "- [N..]: pairs of [WithdrawRequest (mut), request_jvx_ata (mut)]"
833
+ ],
834
+ discriminator: [
835
+ 115,
836
+ 194,
837
+ 215,
838
+ 160,
839
+ 113,
840
+ 154,
841
+ 81,
842
+ 5
843
+ ],
844
+ accounts: [
845
+ {
846
+ name: "payer",
847
+ docs: [
848
+ "Payer/caller - permissionless (anyone can call after epoch ends)"
849
+ ],
850
+ writable: true,
851
+ signer: true
852
+ },
853
+ {
854
+ name: "jlp_vault",
855
+ docs: [
856
+ "The JLP Vault PDA account (for pause checks)"
857
+ ]
858
+ },
859
+ {
860
+ name: "stv",
861
+ docs: [
862
+ "The STV PDA account (mut for epoch state + fee crystallization)"
863
+ ],
864
+ writable: true
865
+ },
866
+ {
867
+ name: "base_mint",
868
+ docs: [
869
+ "Base asset mint (for NAV calc)"
870
+ ]
871
+ },
872
+ {
873
+ name: "jl_mint",
874
+ docs: [
875
+ "jlX mint (for exchange rate)"
876
+ ]
877
+ },
878
+ {
879
+ name: "jv_mint",
880
+ docs: [
881
+ "jvX mint (mut for burn - supply decreases)"
882
+ ],
883
+ writable: true
884
+ },
885
+ {
886
+ name: "stv_base_ata",
887
+ docs: [
888
+ "STV's base ATA (for NAV)"
889
+ ]
890
+ },
891
+ {
892
+ name: "stv_jlx_ata",
893
+ docs: [
894
+ "STV's jlX ATA (for NAV)"
895
+ ]
896
+ },
897
+ {
898
+ name: "token_program"
899
+ }
900
+ ],
901
+ args: []
902
+ },
903
+ {
904
+ name: "request_withdraw",
905
+ docs: [
906
+ "Request withdrawal of jvX shares (epoch-based delayed withdrawal)",
907
+ "",
908
+ "# Flow",
909
+ "1. Validate epoch is active and not ended",
910
+ "2. Create or accumulate into WithdrawRequest PDA for this epoch",
911
+ "3. Transfer jvX from user to request's escrow ATA",
912
+ "",
913
+ "User must wait for process_epoch + claim_withdraw to receive base."
914
+ ],
915
+ discriminator: [
916
+ 137,
917
+ 95,
918
+ 187,
919
+ 96,
920
+ 250,
921
+ 138,
922
+ 31,
923
+ 182
924
+ ],
925
+ accounts: [
926
+ {
927
+ name: "user",
928
+ docs: [
929
+ "User requesting withdrawal"
930
+ ],
931
+ writable: true,
932
+ signer: true
933
+ },
934
+ {
935
+ name: "jlp_vault",
936
+ docs: [
937
+ "The JLP Vault PDA account (for pause checks)"
938
+ ]
939
+ },
940
+ {
941
+ name: "stv",
942
+ docs: [
943
+ "The STV PDA account (for epoch validation)"
944
+ ],
945
+ writable: true
946
+ },
947
+ {
948
+ name: "jv_mint",
949
+ docs: [
950
+ "jvX mint (vault share token)"
951
+ ]
952
+ },
953
+ {
954
+ name: "user_jvx_ata",
955
+ docs: [
956
+ "User's jvX token account (source of shares)"
957
+ ],
958
+ writable: true
959
+ },
960
+ {
961
+ name: "withdraw_request",
962
+ docs: [
963
+ "WithdrawRequest PDA - created or accumulated into"
964
+ ],
965
+ writable: true,
966
+ pda: {
967
+ seeds: [
968
+ {
969
+ kind: "const",
970
+ value: [
971
+ 119,
972
+ 105,
973
+ 116,
974
+ 104,
975
+ 100,
976
+ 114,
977
+ 97,
978
+ 119,
979
+ 95,
980
+ 114,
981
+ 101,
982
+ 113,
983
+ 117,
984
+ 101,
985
+ 115,
986
+ 116
987
+ ]
988
+ },
989
+ {
990
+ kind: "account",
991
+ path: "stv"
992
+ },
993
+ {
994
+ kind: "account",
995
+ path: "user"
996
+ },
997
+ {
998
+ kind: "arg",
999
+ path: "epoch_id"
1000
+ }
1001
+ ]
1002
+ }
1003
+ },
1004
+ {
1005
+ name: "request_jvx_ata",
1006
+ docs: [
1007
+ "jvX ATA owned by the WithdrawRequest PDA (escrow for shares)"
1008
+ ],
1009
+ writable: true,
1010
+ pda: {
1011
+ seeds: [
1012
+ {
1013
+ kind: "account",
1014
+ path: "withdraw_request"
1015
+ },
1016
+ {
1017
+ kind: "const",
1018
+ value: [
1019
+ 6,
1020
+ 221,
1021
+ 246,
1022
+ 225,
1023
+ 215,
1024
+ 101,
1025
+ 161,
1026
+ 147,
1027
+ 217,
1028
+ 203,
1029
+ 225,
1030
+ 70,
1031
+ 206,
1032
+ 235,
1033
+ 121,
1034
+ 172,
1035
+ 28,
1036
+ 180,
1037
+ 133,
1038
+ 237,
1039
+ 95,
1040
+ 91,
1041
+ 55,
1042
+ 145,
1043
+ 58,
1044
+ 140,
1045
+ 245,
1046
+ 133,
1047
+ 126,
1048
+ 255,
1049
+ 0,
1050
+ 169
1051
+ ]
1052
+ },
1053
+ {
1054
+ kind: "account",
1055
+ path: "jv_mint"
1056
+ }
1057
+ ],
1058
+ program: {
1059
+ kind: "const",
1060
+ value: [
1061
+ 140,
1062
+ 151,
1063
+ 37,
1064
+ 143,
1065
+ 78,
1066
+ 36,
1067
+ 137,
1068
+ 241,
1069
+ 187,
1070
+ 61,
1071
+ 16,
1072
+ 41,
1073
+ 20,
1074
+ 142,
1075
+ 13,
1076
+ 131,
1077
+ 11,
1078
+ 90,
1079
+ 19,
1080
+ 153,
1081
+ 218,
1082
+ 255,
1083
+ 16,
1084
+ 132,
1085
+ 4,
1086
+ 142,
1087
+ 123,
1088
+ 216,
1089
+ 219,
1090
+ 233,
1091
+ 248,
1092
+ 89
1093
+ ]
1094
+ }
1095
+ }
1096
+ },
1097
+ {
1098
+ name: "token_program"
771
1099
  },
772
1100
  {
773
- name: "vault_staging_ata",
774
- docs: [
775
- "Vault's staging jlX ATA (for this specific jl_mint)",
776
- "For base-only pools, this is the staging base ATA"
777
- ],
778
- writable: true
1101
+ name: "associated_token_program",
1102
+ address: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
779
1103
  },
780
1104
  {
781
- name: "token_program",
782
- docs: [
783
- "Token program"
784
- ]
1105
+ name: "system_program",
1106
+ address: "11111111111111111111111111111111"
785
1107
  }
786
1108
  ],
787
1109
  args: [
788
1110
  {
789
- name: "params",
790
- type: {
791
- defined: {
792
- name: "MoveJlxParams"
793
- }
794
- }
1111
+ name: "shares",
1112
+ type: "u64"
1113
+ },
1114
+ {
1115
+ name: "epoch_id",
1116
+ type: "u32"
795
1117
  }
796
1118
  ]
797
1119
  },
@@ -1041,121 +1363,6 @@ var jlp_d_program_default = {
1041
1363
  }
1042
1364
  }
1043
1365
  ]
1044
- },
1045
- {
1046
- name: "withdraw",
1047
- docs: [
1048
- "Withdraw base asset by burning jvX shares",
1049
- "",
1050
- "# Flow",
1051
- "1. Crystallize fees inline (ensures fair PPS)",
1052
- "2. Calculate base amount from shares at post-fee PPS",
1053
- "3. Burn jvX shares from user",
1054
- "4. Transfer base from STV's base ATA to user",
1055
- "",
1056
- "# Note",
1057
- "Requires sufficient base balance in STV's base ATA.",
1058
- "Manager must ensure liquidity by converting jlX to base via",
1059
- "jup_earn_deposit_withdraw instruction before user withdrawals.",
1060
- "",
1061
- "Remaining accounts (optional, for exchange rate):",
1062
- "[0] = Jupiter Lend lending account",
1063
- "[1] = Jupiter Lend rewards rate model"
1064
- ],
1065
- discriminator: [
1066
- 183,
1067
- 18,
1068
- 70,
1069
- 156,
1070
- 148,
1071
- 109,
1072
- 161,
1073
- 34
1074
- ],
1075
- accounts: [
1076
- {
1077
- name: "user",
1078
- docs: [
1079
- "User performing the withdrawal"
1080
- ],
1081
- writable: true,
1082
- signer: true
1083
- },
1084
- {
1085
- name: "jlp_vault",
1086
- docs: [
1087
- "The JLP Vault PDA account",
1088
- "Note: PDA verified in handler via get_pda() to avoid multiple loads"
1089
- ]
1090
- },
1091
- {
1092
- name: "stv",
1093
- docs: [
1094
- "The STV PDA account",
1095
- "Note: PDA verified in handler via get_pda() to avoid multiple loads"
1096
- ],
1097
- writable: true
1098
- },
1099
- {
1100
- name: "base_mint",
1101
- docs: [
1102
- "Base asset mint (underlying token: SOL, BTC, ETH, USDC)"
1103
- ]
1104
- },
1105
- {
1106
- name: "jl_mint",
1107
- docs: [
1108
- "jlX mint (Jupiter Lend token) - used for NAV calculation"
1109
- ]
1110
- },
1111
- {
1112
- name: "jv_mint",
1113
- docs: [
1114
- "jvX mint (vault share token) - STV is mint authority",
1115
- "Verified against STV.jv_mint in handler"
1116
- ],
1117
- writable: true
1118
- },
1119
- {
1120
- name: "user_base_ata",
1121
- docs: [
1122
- "User's base asset token account (destination for withdrawal)"
1123
- ],
1124
- writable: true
1125
- },
1126
- {
1127
- name: "user_jvx_ata",
1128
- docs: [
1129
- "User's jvX token account (source - shares to burn)"
1130
- ],
1131
- writable: true
1132
- },
1133
- {
1134
- name: "stv_base_ata",
1135
- docs: [
1136
- "STV's base ATA (source for base tokens to user)"
1137
- ],
1138
- writable: true
1139
- },
1140
- {
1141
- name: "stv_jlx_ata",
1142
- docs: [
1143
- "STV's jlX ATA (used for NAV calculation)"
1144
- ]
1145
- },
1146
- {
1147
- name: "token_program",
1148
- docs: [
1149
- "Token program"
1150
- ]
1151
- }
1152
- ],
1153
- args: [
1154
- {
1155
- name: "shares_to_burn",
1156
- type: "u64"
1157
- }
1158
- ]
1159
1366
  }
1160
1367
  ],
1161
1368
  accounts: [
@@ -1184,6 +1391,19 @@ var jlp_d_program_default = {
1184
1391
  17,
1185
1392
  230
1186
1393
  ]
1394
+ },
1395
+ {
1396
+ name: "WithdrawRequest",
1397
+ discriminator: [
1398
+ 186,
1399
+ 239,
1400
+ 174,
1401
+ 191,
1402
+ 189,
1403
+ 13,
1404
+ 47,
1405
+ 196
1406
+ ]
1187
1407
  }
1188
1408
  ],
1189
1409
  events: [
@@ -1200,6 +1420,32 @@ var jlp_d_program_default = {
1200
1420
  57
1201
1421
  ]
1202
1422
  },
1423
+ {
1424
+ name: "EpochAdvanced",
1425
+ discriminator: [
1426
+ 41,
1427
+ 220,
1428
+ 14,
1429
+ 123,
1430
+ 117,
1431
+ 70,
1432
+ 117,
1433
+ 157
1434
+ ]
1435
+ },
1436
+ {
1437
+ name: "EpochProcessed",
1438
+ discriminator: [
1439
+ 18,
1440
+ 238,
1441
+ 2,
1442
+ 247,
1443
+ 238,
1444
+ 178,
1445
+ 94,
1446
+ 138
1447
+ ]
1448
+ },
1203
1449
  {
1204
1450
  name: "FeesClaimSkipped",
1205
1451
  discriminator: [
@@ -1370,16 +1616,29 @@ var jlp_d_program_default = {
1370
1616
  ]
1371
1617
  },
1372
1618
  {
1373
- name: "Withdrawn",
1619
+ name: "WithdrawClaimed",
1374
1620
  discriminator: [
1375
- 20,
1621
+ 77,
1622
+ 130,
1376
1623
  89,
1377
- 223,
1378
- 198,
1379
- 194,
1380
- 124,
1381
- 219,
1382
- 13
1624
+ 38,
1625
+ 239,
1626
+ 172,
1627
+ 174,
1628
+ 85
1629
+ ]
1630
+ },
1631
+ {
1632
+ name: "WithdrawRequested",
1633
+ discriminator: [
1634
+ 114,
1635
+ 16,
1636
+ 240,
1637
+ 206,
1638
+ 93,
1639
+ 128,
1640
+ 151,
1641
+ 39
1383
1642
  ]
1384
1643
  }
1385
1644
  ],
@@ -1610,14 +1869,132 @@ var jlp_d_program_default = {
1610
1869
  msg: "Test mode required: FLAG_TEST_MODE must be set for devnet/localnet builds"
1611
1870
  },
1612
1871
  {
1613
- code: 6045,
1614
- name: "NotAdmin",
1615
- msg: "Unauthorized: not admin"
1616
- }
1617
- ],
1618
- types: [
1619
- {
1620
- name: "Deposited",
1872
+ code: 6045,
1873
+ name: "NotAdmin",
1874
+ msg: "Unauthorized: not admin"
1875
+ },
1876
+ {
1877
+ code: 6046,
1878
+ name: "TokenAccountNotEmpty",
1879
+ msg: "Token account balance must be zero before closing"
1880
+ },
1881
+ {
1882
+ code: 6047,
1883
+ name: "TokenAccountOwnerMismatch",
1884
+ msg: "Token account not owned by expected PDA"
1885
+ },
1886
+ {
1887
+ code: 6048,
1888
+ name: "EpochEnded",
1889
+ msg: "Epoch has ended - call process_epoch first"
1890
+ },
1891
+ {
1892
+ code: 6049,
1893
+ name: "EpochNotEnded",
1894
+ msg: "Epoch has not ended yet"
1895
+ },
1896
+ {
1897
+ code: 6050,
1898
+ name: "ClaimNotAvailableYet",
1899
+ msg: "Claim not available yet - wait for next epoch"
1900
+ },
1901
+ {
1902
+ code: 6051,
1903
+ name: "InvalidEpochInterval",
1904
+ msg: "Withdraw epoch interval must be > 0"
1905
+ },
1906
+ {
1907
+ code: 6052,
1908
+ name: "ActiveWithdrawReserves",
1909
+ msg: "Cannot update epoch interval with active reserves"
1910
+ },
1911
+ {
1912
+ code: 6053,
1913
+ name: "EpochIdMismatch",
1914
+ msg: "Epoch ID mismatch"
1915
+ },
1916
+ {
1917
+ code: 6054,
1918
+ name: "WithdrawRequestNotProcessed",
1919
+ msg: "Withdraw request not processed yet"
1920
+ },
1921
+ {
1922
+ code: 6055,
1923
+ name: "WithdrawRequestAlreadyProcessed",
1924
+ msg: "Withdraw request already processed"
1925
+ }
1926
+ ],
1927
+ types: [
1928
+ {
1929
+ name: "Deposited",
1930
+ type: {
1931
+ kind: "struct",
1932
+ fields: [
1933
+ {
1934
+ name: "stv",
1935
+ type: "pubkey"
1936
+ },
1937
+ {
1938
+ name: "user",
1939
+ type: "pubkey"
1940
+ },
1941
+ {
1942
+ name: "amount_base",
1943
+ docs: [
1944
+ "Amount of base asset deposited"
1945
+ ],
1946
+ type: "u64"
1947
+ },
1948
+ {
1949
+ name: "shares_minted",
1950
+ type: "u64"
1951
+ },
1952
+ {
1953
+ name: "pps",
1954
+ type: "u64"
1955
+ }
1956
+ ]
1957
+ }
1958
+ },
1959
+ {
1960
+ name: "Direction",
1961
+ docs: [
1962
+ "Direction of jlX token movement between STV and Vault"
1963
+ ],
1964
+ type: {
1965
+ kind: "enum",
1966
+ variants: [
1967
+ {
1968
+ name: "ToVault"
1969
+ },
1970
+ {
1971
+ name: "FromVault"
1972
+ }
1973
+ ]
1974
+ }
1975
+ },
1976
+ {
1977
+ name: "EpochAdvanced",
1978
+ type: {
1979
+ kind: "struct",
1980
+ fields: [
1981
+ {
1982
+ name: "stv",
1983
+ type: "pubkey"
1984
+ },
1985
+ {
1986
+ name: "new_epoch_id",
1987
+ type: "u32"
1988
+ },
1989
+ {
1990
+ name: "new_next_epoch_ts",
1991
+ type: "u32"
1992
+ }
1993
+ ]
1994
+ }
1995
+ },
1996
+ {
1997
+ name: "EpochProcessed",
1621
1998
  type: {
1622
1999
  kind: "struct",
1623
2000
  fields: [
@@ -1626,40 +2003,28 @@ var jlp_d_program_default = {
1626
2003
  type: "pubkey"
1627
2004
  },
1628
2005
  {
1629
- name: "user",
1630
- type: "pubkey"
2006
+ name: "epoch_id",
2007
+ type: "u32"
1631
2008
  },
1632
2009
  {
1633
- name: "amount_base",
1634
- docs: [
1635
- "Amount of base asset deposited"
1636
- ],
2010
+ name: "pps",
1637
2011
  type: "u64"
1638
2012
  },
1639
2013
  {
1640
- name: "shares_minted",
2014
+ name: "total_shares",
1641
2015
  type: "u64"
1642
2016
  },
1643
2017
  {
1644
- name: "pps",
2018
+ name: "total_base",
1645
2019
  type: "u64"
1646
- }
1647
- ]
1648
- }
1649
- },
1650
- {
1651
- name: "Direction",
1652
- docs: [
1653
- "Direction of jlX token movement between STV and Vault"
1654
- ],
1655
- type: {
1656
- kind: "enum",
1657
- variants: [
2020
+ },
1658
2021
  {
1659
- name: "ToVault"
2022
+ name: "new_epoch_id",
2023
+ type: "u32"
1660
2024
  },
1661
2025
  {
1662
- name: "FromVault"
2026
+ name: "new_next_epoch_ts",
2027
+ type: "u32"
1663
2028
  }
1664
2029
  ]
1665
2030
  }
@@ -1849,6 +2214,13 @@ var jlp_d_program_default = {
1849
2214
  "Minimum deposit amount in base asset (0 = no minimum)"
1850
2215
  ],
1851
2216
  type: "u64"
2217
+ },
2218
+ {
2219
+ name: "epoch_sec",
2220
+ docs: [
2221
+ "Epoch duration in seconds for delayed withdrawals"
2222
+ ],
2223
+ type: "u32"
1852
2224
  }
1853
2225
  ]
1854
2226
  }
@@ -2294,7 +2666,7 @@ var jlp_d_program_default = {
2294
2666
  docs: [
2295
2667
  "STV - Single Token Vault account",
2296
2668
  'Seeds: ["stv", base_mint.key().as_ref()]',
2297
- "Size: 8 (discriminator) + 160 (data) = 168 bytes"
2669
+ "Size: 8 (discriminator) + 200 (data) = 208 bytes"
2298
2670
  ],
2299
2671
  serialization: "bytemuck",
2300
2672
  repr: {
@@ -2376,6 +2748,50 @@ var jlp_d_program_default = {
2376
2748
  ],
2377
2749
  type: "u64"
2378
2750
  },
2751
+ {
2752
+ name: "requested_base",
2753
+ docs: [
2754
+ "Estimated base for current epoch's withdrawal requests (reset on process_epoch)",
2755
+ "Manager reads this to know how much to unwind before next epoch"
2756
+ ],
2757
+ type: "u64"
2758
+ },
2759
+ {
2760
+ name: "reserved_base",
2761
+ docs: [
2762
+ "Base earmarked for unclaimed withdrawals (+process_epoch, -claim_withdraw)",
2763
+ "Subtracted from NAV so reserved funds don't inflate PPS"
2764
+ ],
2765
+ type: "u64"
2766
+ },
2767
+ {
2768
+ name: "epoch_pps",
2769
+ docs: [
2770
+ "PPS locked at first process_epoch batch (0 = not set, reset on epoch advance)"
2771
+ ],
2772
+ type: "u64"
2773
+ },
2774
+ {
2775
+ name: "next_epoch_ts",
2776
+ docs: [
2777
+ "Unix timestamp when current epoch ends"
2778
+ ],
2779
+ type: "u32"
2780
+ },
2781
+ {
2782
+ name: "epoch_sec",
2783
+ docs: [
2784
+ "Epoch duration in seconds"
2785
+ ],
2786
+ type: "u32"
2787
+ },
2788
+ {
2789
+ name: "current_epoch_id",
2790
+ docs: [
2791
+ "Incrementing epoch counter"
2792
+ ],
2793
+ type: "u32"
2794
+ },
2379
2795
  {
2380
2796
  name: "mgmt_fee_bps",
2381
2797
  docs: [
@@ -2410,6 +2826,18 @@ var jlp_d_program_default = {
2410
2826
  "PDA bump seed"
2411
2827
  ],
2412
2828
  type: "u8"
2829
+ },
2830
+ {
2831
+ name: "_padding",
2832
+ docs: [
2833
+ "Alignment padding"
2834
+ ],
2835
+ type: {
2836
+ array: [
2837
+ "u8",
2838
+ 4
2839
+ ]
2840
+ }
2413
2841
  }
2414
2842
  ]
2415
2843
  }
@@ -2773,12 +3201,21 @@ var jlp_d_program_default = {
2773
3201
  type: {
2774
3202
  option: "u64"
2775
3203
  }
3204
+ },
3205
+ {
3206
+ name: "epoch_sec",
3207
+ docs: [
3208
+ "Optional new epoch duration in seconds"
3209
+ ],
3210
+ type: {
3211
+ option: "u32"
3212
+ }
2776
3213
  }
2777
3214
  ]
2778
3215
  }
2779
3216
  },
2780
3217
  {
2781
- name: "Withdrawn",
3218
+ name: "WithdrawClaimed",
2782
3219
  type: {
2783
3220
  kind: "struct",
2784
3221
  fields: [
@@ -2791,19 +3228,113 @@ var jlp_d_program_default = {
2791
3228
  type: "pubkey"
2792
3229
  },
2793
3230
  {
2794
- name: "shares_burned",
3231
+ name: "shares",
2795
3232
  type: "u64"
2796
3233
  },
2797
3234
  {
2798
- name: "amount_base",
3235
+ name: "base_amount",
3236
+ type: "u64"
3237
+ },
3238
+ {
3239
+ name: "epoch_id",
3240
+ type: "u32"
3241
+ }
3242
+ ]
3243
+ }
3244
+ },
3245
+ {
3246
+ name: "WithdrawRequest",
3247
+ docs: [
3248
+ "WithdrawRequest - Per-user per-epoch withdrawal request",
3249
+ 'Seeds: ["withdraw_request", stv.key(), user.key(), &epoch_id.to_le_bytes()]',
3250
+ "",
3251
+ "One PDA per user per STV per epoch. Multiple request_withdraw calls",
3252
+ "in the same epoch accumulate into the same PDA.",
3253
+ "",
3254
+ "Lifecycle:",
3255
+ "1. Created by request_withdraw (user escrows jvX into request's ATA)",
3256
+ "2. Processed by process_epoch (jvX burned, pps + claim_available_after set)",
3257
+ "3. Closed by claim_withdraw (base transferred, PDA + ATA closed)"
3258
+ ],
3259
+ type: {
3260
+ kind: "struct",
3261
+ fields: [
3262
+ {
3263
+ name: "stv",
3264
+ docs: [
3265
+ "Back-reference to the STV"
3266
+ ],
3267
+ type: "pubkey"
3268
+ },
3269
+ {
3270
+ name: "user",
3271
+ docs: [
3272
+ "The user who requested the withdrawal"
3273
+ ],
3274
+ type: "pubkey"
3275
+ },
3276
+ {
3277
+ name: "shares",
2799
3278
  docs: [
2800
- "Amount of base asset withdrawn"
3279
+ "Total jvX shares escrowed (accumulated across multiple requests in same epoch)"
2801
3280
  ],
2802
3281
  type: "u64"
2803
3282
  },
2804
3283
  {
2805
3284
  name: "pps",
3285
+ docs: [
3286
+ "PPS at process time (0 = unprocessed)"
3287
+ ],
3288
+ type: "u64"
3289
+ },
3290
+ {
3291
+ name: "epoch_id",
3292
+ docs: [
3293
+ "Epoch when request was made"
3294
+ ],
3295
+ type: "u32"
3296
+ },
3297
+ {
3298
+ name: "claim_available_after",
3299
+ docs: [
3300
+ "Unix timestamp after which claim is available (0 = unprocessed)"
3301
+ ],
3302
+ type: "u32"
3303
+ },
3304
+ {
3305
+ name: "bump",
3306
+ docs: [
3307
+ "PDA bump seed"
3308
+ ],
3309
+ type: "u8"
3310
+ }
3311
+ ]
3312
+ }
3313
+ },
3314
+ {
3315
+ name: "WithdrawRequested",
3316
+ type: {
3317
+ kind: "struct",
3318
+ fields: [
3319
+ {
3320
+ name: "stv",
3321
+ type: "pubkey"
3322
+ },
3323
+ {
3324
+ name: "user",
3325
+ type: "pubkey"
3326
+ },
3327
+ {
3328
+ name: "shares",
3329
+ type: "u64"
3330
+ },
3331
+ {
3332
+ name: "total_shares",
2806
3333
  type: "u64"
3334
+ },
3335
+ {
3336
+ name: "epoch_id",
3337
+ type: "u32"
2807
3338
  }
2808
3339
  ]
2809
3340
  }
@@ -2838,6 +3369,7 @@ var JUPITER_SWAP_PROGRAM_ID = new PublicKey(
2838
3369
  );
2839
3370
  var SEED_JLP_VAULT = "jlp_vault";
2840
3371
  var SEED_STV = "stv";
3372
+ var SEED_WITHDRAW_REQUEST = "withdraw_request";
2841
3373
  var FLAG_PAUSED = 1;
2842
3374
  var FLAG_DEPOSITS_DISABLED = 2;
2843
3375
  var FLAG_WITHDRAWALS_DISABLED = 4;
@@ -2874,6 +3406,7 @@ var JUPITER_PERPS_PROGRAM_ID = new PublicKey("PERPHjGBqRHArX4DySjwM6UJHiR3sWAatq
2874
3406
  import { PublicKey as PublicKey2 } from "@solana/web3.js";
2875
3407
  var SEED_JLP_VAULT_BUFFER = Buffer.from(SEED_JLP_VAULT);
2876
3408
  var SEED_STV_BUFFER = Buffer.from(SEED_STV);
3409
+ var SEED_WITHDRAW_REQUEST_BUFFER = Buffer.from(SEED_WITHDRAW_REQUEST);
2877
3410
  var pdaCache = /* @__PURE__ */ new Map();
2878
3411
  function deriveVaultPda(programId) {
2879
3412
  const key = `vault:${programId.toBase58()}`;
@@ -2899,6 +3432,20 @@ function deriveStvPda(baseMint, programId) {
2899
3432
  }
2900
3433
  return cached;
2901
3434
  }
3435
+ function deriveWithdrawRequestPda(stvPda, user, epochId, programId) {
3436
+ const key = `wr:${stvPda.toBase58()}:${user.toBase58()}:${epochId}:${programId.toBase58()}`;
3437
+ let cached = pdaCache.get(key);
3438
+ if (!cached) {
3439
+ const epochIdBuffer = Buffer.alloc(4);
3440
+ epochIdBuffer.writeUInt32LE(epochId);
3441
+ cached = PublicKey2.findProgramAddressSync(
3442
+ [SEED_WITHDRAW_REQUEST_BUFFER, stvPda.toBuffer(), user.toBuffer(), epochIdBuffer],
3443
+ programId
3444
+ );
3445
+ pdaCache.set(key, cached);
3446
+ }
3447
+ return cached;
3448
+ }
2902
3449
  function clearPdaCache() {
2903
3450
  pdaCache.clear();
2904
3451
  }
@@ -2977,7 +3524,7 @@ function parseVault(data) {
2977
3524
  // src/accounts/stv.ts
2978
3525
  import { PublicKey as PublicKey4 } from "@solana/web3.js";
2979
3526
  import { BN as BN2 } from "@coral-xyz/anchor";
2980
- var STV_DATA_SIZE = 160;
3527
+ var STV_DATA_SIZE = 200;
2981
3528
  var STV_ACCOUNT_SIZE = 8 + STV_DATA_SIZE;
2982
3529
  var STV_DISCRIMINATOR = Buffer.from([
2983
3530
  214,
@@ -3022,6 +3569,18 @@ function parseStv(data) {
3022
3569
  offset += 8;
3023
3570
  const minDeposit = new BN2(data.subarray(offset, offset + 8), "le");
3024
3571
  offset += 8;
3572
+ const requestedBase = new BN2(data.subarray(offset, offset + 8), "le");
3573
+ offset += 8;
3574
+ const reservedBase = new BN2(data.subarray(offset, offset + 8), "le");
3575
+ offset += 8;
3576
+ const epochPps = new BN2(data.subarray(offset, offset + 8), "le");
3577
+ offset += 8;
3578
+ const nextEpochTs = data.readUInt32LE(offset);
3579
+ offset += 4;
3580
+ const epochSec = data.readUInt32LE(offset);
3581
+ offset += 4;
3582
+ const currentEpochId = data.readUInt32LE(offset);
3583
+ offset += 4;
3025
3584
  const mgmtFeeBps = data.readUInt16LE(offset);
3026
3585
  offset += 2;
3027
3586
  const perfFeeBps = data.readUInt16LE(offset);
@@ -3031,7 +3590,6 @@ function parseStv(data) {
3031
3590
  const version = data.readUInt8(offset);
3032
3591
  offset += 1;
3033
3592
  const bump = data.readUInt8(offset);
3034
- offset += 1;
3035
3593
  return {
3036
3594
  baseMint,
3037
3595
  jlMint,
@@ -3043,6 +3601,12 @@ function parseStv(data) {
3043
3601
  accruedFeesJlx,
3044
3602
  maxDeposit,
3045
3603
  minDeposit,
3604
+ requestedBase,
3605
+ reservedBase,
3606
+ epochPps,
3607
+ nextEpochTs,
3608
+ epochSec,
3609
+ currentEpochId,
3046
3610
  mgmtFeeBps,
3047
3611
  perfFeeBps,
3048
3612
  flags,
@@ -3093,9 +3657,13 @@ var EXCHANGE_RATE_PRECISION_BI = BigInt(EXCHANGE_RATE_PRECISION);
3093
3657
  var RETURN_PERCENT_PRECISION = EXCHANGE_RATE_PRECISION_BI * 100n;
3094
3658
  var SECONDS_PER_YEAR = BigInt(365 * 24 * 60 * 60);
3095
3659
  var MAX_REWARDS_RATE = 50n * EXCHANGE_RATE_PRECISION_BI;
3096
- function calculateNav(stvBaseBalance, stvJlxBalance, exchangeRate, baseLoaned) {
3660
+ function calculateNav(stvBaseBalance, stvJlxBalance, exchangeRate, baseLoaned, reservedBase) {
3097
3661
  const jlxValue = stvJlxBalance.mul(new BN3(exchangeRate.toString())).div(EXCHANGE_RATE_PRECISION_BN);
3098
- return stvBaseBalance.add(jlxValue).add(baseLoaned);
3662
+ let nav = stvBaseBalance.add(jlxValue).add(baseLoaned);
3663
+ if (reservedBase && !reservedBase.isZero()) {
3664
+ nav = nav.sub(reservedBase);
3665
+ }
3666
+ return nav;
3099
3667
  }
3100
3668
  function calculatePps(nav, jvSupply) {
3101
3669
  if (jvSupply.isZero()) {
@@ -3545,7 +4113,8 @@ async function createInitializeStvInstruction(program, params, accounts) {
3545
4113
  mgmtFeeBps: params.mgmtFeeBps,
3546
4114
  perfFeeBps: params.perfFeeBps,
3547
4115
  maxDeposit: params.maxDeposit,
3548
- minDeposit: params.minDeposit
4116
+ minDeposit: params.minDeposit,
4117
+ epochSec: params.epochSec
3549
4118
  }).accounts({
3550
4119
  admin: accounts.admin,
3551
4120
  jlpVault: accounts.jlpVault,
@@ -3565,7 +4134,8 @@ async function createUpdateStvInstruction(program, params, accounts) {
3565
4134
  jlMint: params.jlMint,
3566
4135
  pps: params.pps,
3567
4136
  hwm: params.hwm,
3568
- baseLoaned: params.baseLoaned
4137
+ baseLoaned: params.baseLoaned,
4138
+ epochSec: params.epochSec
3569
4139
  }).accounts({
3570
4140
  admin: accounts.admin,
3571
4141
  jlpVault: accounts.jlpVault,
@@ -3589,20 +4159,32 @@ async function createDepositInstruction(program, amount, accounts, remainingAcco
3589
4159
  tokenProgram: accounts.tokenProgram
3590
4160
  }).remainingAccounts(remainingAccounts).instruction();
3591
4161
  }
3592
- async function createWithdrawInstruction(program, sharesToBurn, accounts, remainingAccounts = []) {
3593
- return await program.methods.withdraw(sharesToBurn).accounts({
4162
+ async function createRequestWithdrawInstruction(program, params, accounts) {
4163
+ return await program.methods.requestWithdraw(params.shares, params.epochId).accounts({
3594
4164
  user: accounts.user,
3595
4165
  jlpVault: accounts.jlpVault,
3596
4166
  stv: accounts.stv,
4167
+ jvMint: accounts.jvMint,
4168
+ userJvxAta: accounts.userJvxAta,
4169
+ withdrawRequest: accounts.withdrawRequest,
4170
+ requestJvxAta: accounts.requestJvxAta,
4171
+ tokenProgram: accounts.tokenProgram,
4172
+ associatedTokenProgram: accounts.associatedTokenProgram,
4173
+ systemProgram: accounts.systemProgram
4174
+ }).instruction();
4175
+ }
4176
+ async function createClaimWithdrawInstruction(program, accounts) {
4177
+ return await program.methods.claimWithdraw().accounts({
4178
+ user: accounts.user,
4179
+ stv: accounts.stv,
3597
4180
  baseMint: accounts.baseMint,
3598
- jlMint: accounts.jlMint,
3599
4181
  jvMint: accounts.jvMint,
3600
4182
  userBaseAta: accounts.userBaseAta,
3601
- userJvxAta: accounts.userJvxAta,
3602
4183
  stvBaseAta: accounts.stvBaseAta,
3603
- stvJlxAta: accounts.stvJlxAta,
4184
+ withdrawRequest: accounts.withdrawRequest,
4185
+ requestJvxAta: accounts.requestJvxAta,
3604
4186
  tokenProgram: accounts.tokenProgram
3605
- }).remainingAccounts(remainingAccounts).instruction();
4187
+ }).instruction();
3606
4188
  }
3607
4189
 
3608
4190
  // src/instructions/manager.ts
@@ -3661,6 +4243,19 @@ async function createSwapJlxJlpInstruction(program, params, accounts, remainingA
3661
4243
  jupiterProgram: accounts.jupiterProgram
3662
4244
  }).remainingAccounts(remainingAccounts).instruction();
3663
4245
  }
4246
+ async function createProcessEpochInstruction(program, accounts, remainingAccounts = []) {
4247
+ return await program.methods.processEpoch().accounts({
4248
+ payer: accounts.payer,
4249
+ jlpVault: accounts.jlpVault,
4250
+ stv: accounts.stv,
4251
+ baseMint: accounts.baseMint,
4252
+ jlMint: accounts.jlMint,
4253
+ jvMint: accounts.jvMint,
4254
+ stvBaseAta: accounts.stvBaseAta,
4255
+ stvJlxAta: accounts.stvJlxAta,
4256
+ tokenProgram: accounts.tokenProgram
4257
+ }).remainingAccounts(remainingAccounts).instruction();
4258
+ }
3664
4259
  async function createSettleYieldInstruction(program, params, accounts, remainingAccounts = []) {
3665
4260
  return await program.methods.settleYield().accounts({
3666
4261
  jlpVault: accounts.jlpVault,
@@ -3950,8 +4545,8 @@ var PoolContext = class {
3950
4545
  }).compileToV0Message();
3951
4546
  return new VersionedTransaction(message);
3952
4547
  }
3953
- // Burn jvX shares and withdraw base asset
3954
- async withdraw(params) {
4548
+ // Request withdrawal: escrow jvX shares for the current epoch
4549
+ async requestWithdraw(params) {
3955
4550
  if (params.shares.isZero() || params.shares.isNeg()) {
3956
4551
  throw new JlpdClientError("Withdraw shares must be positive");
3957
4552
  }
@@ -3960,28 +4555,66 @@ var PoolContext = class {
3960
4555
  this.client.connection.getLatestBlockhash("confirmed")
3961
4556
  ]);
3962
4557
  if (!stv) throw new JlpdClientError("STV not found");
4558
+ const epochId = stv.currentEpochId;
4559
+ const [withdrawRequestPda] = deriveWithdrawRequestPda(
4560
+ this.stvPda,
4561
+ params.user,
4562
+ epochId,
4563
+ this.client.programId
4564
+ );
4565
+ const requestJvxAta = getAssociatedTokenAddressSync2(stv.jvMint, withdrawRequestPda, true);
3963
4566
  const userAtas = deriveUserAtas(this.pool.mint, stv.jvMint, params.user);
3964
- const erAccounts = this.pool.hasJupiterLend ? buildExchangeRateAccounts(this.pool) : null;
3965
- const ix = await createWithdrawInstruction(
4567
+ const ix = await createRequestWithdrawInstruction(
3966
4568
  this.client.program,
3967
- params.shares,
4569
+ { shares: params.shares, epochId },
3968
4570
  {
3969
4571
  user: params.user,
3970
4572
  jlpVault: this.client.vaultPda,
3971
4573
  stv: this.stvPda,
4574
+ jvMint: stv.jvMint,
4575
+ userJvxAta: userAtas.jvxAta,
4576
+ withdrawRequest: withdrawRequestPda,
4577
+ requestJvxAta,
4578
+ tokenProgram: TOKEN_PROGRAM_ID2,
4579
+ associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID2,
4580
+ systemProgram: SystemProgram2.programId
4581
+ }
4582
+ );
4583
+ const message = new TransactionMessage({
4584
+ payerKey: params.user,
4585
+ recentBlockhash: blockhash,
4586
+ instructions: [ix]
4587
+ }).compileToV0Message();
4588
+ return new VersionedTransaction(message);
4589
+ }
4590
+ // Claim withdrawal: receive base tokens for a processed WithdrawRequest
4591
+ async claimWithdraw(params) {
4592
+ const [stv, { blockhash }] = await Promise.all([
4593
+ this.client.fetchStv(this.pool.mint),
4594
+ this.client.connection.getLatestBlockhash("confirmed")
4595
+ ]);
4596
+ if (!stv) throw new JlpdClientError("STV not found");
4597
+ const [withdrawRequestPda] = deriveWithdrawRequestPda(
4598
+ this.stvPda,
4599
+ params.user,
4600
+ params.epochId,
4601
+ this.client.programId
4602
+ );
4603
+ const requestJvxAta = getAssociatedTokenAddressSync2(stv.jvMint, withdrawRequestPda, true);
4604
+ const userAtas = deriveUserAtas(this.pool.mint, stv.jvMint, params.user);
4605
+ const ix = await createClaimWithdrawInstruction(
4606
+ this.client.program,
4607
+ {
4608
+ user: params.user,
4609
+ stv: this.stvPda,
3972
4610
  baseMint: this.pool.mint,
3973
- jlMint: this.pool.fTokenMint,
3974
4611
  jvMint: stv.jvMint,
3975
4612
  userBaseAta: userAtas.baseAta,
3976
- userJvxAta: userAtas.jvxAta,
3977
4613
  stvBaseAta: this.stvBaseAta,
3978
- stvJlxAta: this.stvJlxAta,
4614
+ withdrawRequest: withdrawRequestPda,
4615
+ requestJvxAta,
3979
4616
  tokenProgram: TOKEN_PROGRAM_ID2
3980
- },
3981
- erAccounts ? [
3982
- { pubkey: erAccounts.lending, isSigner: false, isWritable: false },
3983
- { pubkey: erAccounts.rewardsRateModel, isSigner: false, isWritable: false }
3984
- ] : []
4617
+ }
3985
4618
  );
3986
4619
  const message = new TransactionMessage({
3987
4620
  payerKey: params.user,
@@ -4085,7 +4718,8 @@ var PoolContext = class {
4085
4718
  jlMint: params.jlMint ?? null,
4086
4719
  pps: params.pps ?? null,
4087
4720
  hwm: params.hwm ?? null,
4088
- baseLoaned: params.baseLoaned ?? null
4721
+ baseLoaned: params.baseLoaned ?? null,
4722
+ epochSec: params.epochSec ?? null
4089
4723
  },
4090
4724
  {
4091
4725
  admin: params.admin,
@@ -4209,7 +4843,8 @@ var AdminContext = class {
4209
4843
  mgmtFeeBps: params.mgmtFeeBps,
4210
4844
  perfFeeBps: params.perfFeeBps,
4211
4845
  maxDeposit: params.maxDeposit,
4212
- minDeposit: params.minDeposit
4846
+ minDeposit: params.minDeposit,
4847
+ epochSec: params.withdrawEpochSec
4213
4848
  },
4214
4849
  {
4215
4850
  admin: params.admin,
@@ -4222,6 +4857,46 @@ var AdminContext = class {
4222
4857
  );
4223
4858
  return this.client.buildTransaction(params.admin, [ix]);
4224
4859
  }
4860
+ // Process epoch for a pool (manager operation)
4861
+ async processEpoch(params) {
4862
+ const pool = getPoolByName(params.poolName);
4863
+ if (!pool) throw new JlpdClientError(`Unknown pool: ${params.poolName}`);
4864
+ const [stvPda] = deriveStvPda(pool.mint, this.client.programId);
4865
+ const stv = await this.client.fetchStv(pool.mint);
4866
+ if (!stv) throw new JlpdClientError(`STV not found for pool: ${params.poolName}`);
4867
+ const stvAtas = deriveStvAtas(pool.mint, pool.fTokenMint, stvPda);
4868
+ const erAccounts = pool.hasJupiterLend ? buildExchangeRateAccounts(pool) : null;
4869
+ const remainingAccounts = [];
4870
+ if (erAccounts) {
4871
+ remainingAccounts.push(
4872
+ { pubkey: erAccounts.lending, isSigner: false, isWritable: false },
4873
+ { pubkey: erAccounts.rewardsRateModel, isSigner: false, isWritable: false }
4874
+ );
4875
+ }
4876
+ for (const wrPubkey of params.withdrawRequests) {
4877
+ const requestJvxAta = getAssociatedTokenAddressSync2(stv.jvMint, wrPubkey, true);
4878
+ remainingAccounts.push(
4879
+ { pubkey: wrPubkey, isSigner: false, isWritable: true },
4880
+ { pubkey: requestJvxAta, isSigner: false, isWritable: true }
4881
+ );
4882
+ }
4883
+ const ix = await createProcessEpochInstruction(
4884
+ this.client.program,
4885
+ {
4886
+ payer: params.payer,
4887
+ jlpVault: this.client.vaultPda,
4888
+ stv: stvPda,
4889
+ baseMint: pool.mint,
4890
+ jlMint: pool.fTokenMint,
4891
+ jvMint: stv.jvMint,
4892
+ stvBaseAta: stvAtas.baseAta,
4893
+ stvJlxAta: stvAtas.jlxAta,
4894
+ tokenProgram: TOKEN_PROGRAM_ID2
4895
+ },
4896
+ remainingAccounts
4897
+ );
4898
+ return this.client.buildTransaction(params.payer, [ix]);
4899
+ }
4225
4900
  // Settle yield across all STVs
4226
4901
  async settleYield(params) {
4227
4902
  const poolNames = ["BTC", "ETH", "SOL", "USDC", "JupUSD"];
@@ -4279,6 +4954,50 @@ var AdminContext = class {
4279
4954
  return this.client.buildTransaction(params.manager, [ix]);
4280
4955
  }
4281
4956
  };
4957
+
4958
+ // src/accounts/withdraw_request.ts
4959
+ import { PublicKey as PublicKey9 } from "@solana/web3.js";
4960
+ import { BN as BN6 } from "@coral-xyz/anchor";
4961
+ var WITHDRAW_REQUEST_DATA_SIZE = 89;
4962
+ var WITHDRAW_REQUEST_ACCOUNT_SIZE = 8 + WITHDRAW_REQUEST_DATA_SIZE;
4963
+ var WITHDRAW_REQUEST_DISCRIMINATOR = Buffer.from([
4964
+ 186,
4965
+ 239,
4966
+ 174,
4967
+ 191,
4968
+ 189,
4969
+ 13,
4970
+ 47,
4971
+ 196
4972
+ ]);
4973
+ function parseWithdrawRequest(data) {
4974
+ if (data.length < WITHDRAW_REQUEST_ACCOUNT_SIZE) {
4975
+ throw new Error(
4976
+ `Invalid WithdrawRequest data size: expected ${WITHDRAW_REQUEST_ACCOUNT_SIZE}, got ${data.length}`
4977
+ );
4978
+ }
4979
+ const discriminator = data.subarray(0, 8);
4980
+ if (!discriminator.equals(WITHDRAW_REQUEST_DISCRIMINATOR)) {
4981
+ throw new Error(
4982
+ `Invalid WithdrawRequest discriminator: expected ${WITHDRAW_REQUEST_DISCRIMINATOR.toString("hex")}, got ${discriminator.toString("hex")}`
4983
+ );
4984
+ }
4985
+ let offset = 8;
4986
+ const stv = new PublicKey9(data.subarray(offset, offset + 32));
4987
+ offset += 32;
4988
+ const user = new PublicKey9(data.subarray(offset, offset + 32));
4989
+ offset += 32;
4990
+ const shares = new BN6(data.subarray(offset, offset + 8), "le");
4991
+ offset += 8;
4992
+ const pps = new BN6(data.subarray(offset, offset + 8), "le");
4993
+ offset += 8;
4994
+ const epochId = data.readUInt32LE(offset);
4995
+ offset += 4;
4996
+ const claimAvailableAfter = data.readUInt32LE(offset);
4997
+ offset += 4;
4998
+ const bump = data.readUInt8(offset);
4999
+ return { stv, user, shares, pps, epochId, claimAvailableAfter, bump };
5000
+ }
4282
5001
  export {
4283
5002
  AdminContext,
4284
5003
  EXCHANGE_RATE_PRECISION,
@@ -4309,6 +5028,7 @@ export {
4309
5028
  PoolContext,
4310
5029
  SEED_JLP_VAULT,
4311
5030
  SEED_STV,
5031
+ SEED_WITHDRAW_REQUEST,
4312
5032
  STV_ACCOUNT_SIZE,
4313
5033
  STV_DATA_SIZE,
4314
5034
  STV_DISCRIMINATOR,
@@ -4317,6 +5037,9 @@ export {
4317
5037
  USDC_POOL,
4318
5038
  WBTC_POOL,
4319
5039
  WETH_POOL,
5040
+ WITHDRAW_REQUEST_ACCOUNT_SIZE,
5041
+ WITHDRAW_REQUEST_DATA_SIZE,
5042
+ WITHDRAW_REQUEST_DISCRIMINATOR,
4320
5043
  WSOL_POOL,
4321
5044
  baseToJlx,
4322
5045
  baseToShares,
@@ -4330,22 +5053,25 @@ export {
4330
5053
  clearAtaCache,
4331
5054
  clearPdaCache,
4332
5055
  createClaimFeesInstruction,
5056
+ createClaimWithdrawInstruction,
4333
5057
  createDepositInstruction,
4334
5058
  createInitOrUpdateVaultInstruction,
4335
5059
  createInitializeStvInstruction,
4336
5060
  createJupEarnInstruction,
4337
5061
  createMoveJlxInstruction,
5062
+ createProcessEpochInstruction,
4338
5063
  createProgram,
5064
+ createRequestWithdrawInstruction,
4339
5065
  createSettleYieldInstruction,
4340
5066
  createSwapJlxJlpInstruction,
4341
5067
  createUpdateStvInstruction,
4342
- createWithdrawInstruction,
4343
5068
  deriveAta,
4344
5069
  deriveStvAtas,
4345
5070
  deriveStvPda,
4346
5071
  deriveUserAtas,
4347
5072
  deriveVaultAtas,
4348
5073
  deriveVaultPda,
5074
+ deriveWithdrawRequestPda,
4349
5075
  fetchAddressLookupTables,
4350
5076
  fetchJlpRate,
4351
5077
  fetchJupiterPriceUsd,
@@ -4359,5 +5085,6 @@ export {
4359
5085
  parseStv,
4360
5086
  parseSwapRemainingAccounts,
4361
5087
  parseVault,
5088
+ parseWithdrawRequest,
4362
5089
  sharesToBase
4363
5090
  };