@wireio/stake 0.3.1 → 0.4.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/lib/stake.browser.js +3601 -1920
- package/lib/stake.browser.js.map +1 -1
- package/lib/stake.d.ts +3269 -1361
- package/lib/stake.js +4374 -2733
- package/lib/stake.js.map +1 -1
- package/lib/stake.m.js +3601 -1920
- package/lib/stake.m.js.map +1 -1
- package/package.json +3 -1
- package/src/assets/solana/idl/liqsol_core.json +2327 -887
- package/src/assets/solana/idl/liqsol_token.json +1 -1
- package/src/assets/solana/idl/transfer_hook.json +192 -0
- package/src/assets/solana/idl/validator_leaderboard.json +147 -4
- package/src/assets/solana/types/liqsol_core.ts +2327 -887
- package/src/assets/solana/types/liqsol_token.ts +1 -1
- package/src/assets/solana/types/transfer_hook.ts +198 -0
- package/src/assets/solana/types/validator_leaderboard.ts +147 -4
- package/src/networks/ethereum/ethereum.ts +0 -5
- package/src/networks/ethereum/utils.ts +1 -1
- package/src/networks/solana/clients/deposit.client.ts +154 -8
- package/src/networks/solana/clients/distribution.client.ts +72 -291
- package/src/networks/solana/clients/leaderboard.client.ts +59 -14
- package/src/networks/solana/clients/outpost.client.ts +188 -359
- package/src/networks/solana/clients/token.client.ts +85 -100
- package/src/networks/solana/constants.ts +155 -64
- package/src/networks/solana/solana.ts +273 -154
- package/src/networks/solana/types.ts +532 -71
- package/src/networks/solana/utils.ts +68 -51
- package/src/types.ts +108 -17
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* IDL can be found at `target/idl/liqsol_token.json`.
|
|
6
6
|
*/
|
|
7
7
|
export type LiqsolToken = {
|
|
8
|
-
"address": "
|
|
8
|
+
"address": "6hiJ8PrSyYLr7H9MA9VYh9fvGoHxZ2TXdDAMzjeUVSXZ",
|
|
9
9
|
"metadata": {
|
|
10
10
|
"name": "liqsolToken",
|
|
11
11
|
"version": "0.1.0",
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Program IDL in camelCase format in order to be used in JS/TS.
|
|
3
|
+
*
|
|
4
|
+
* Note that this is only a type helper and is not the actual IDL. The original
|
|
5
|
+
* IDL can be found at `target/idl/transfer_hook.json`.
|
|
6
|
+
*/
|
|
7
|
+
export type TransferHook = {
|
|
8
|
+
"address": "EtqCLddkPNGjkgiH9rVUmK3M5X2FKFprQvgscBJ8g6hX",
|
|
9
|
+
"metadata": {
|
|
10
|
+
"name": "transferHook",
|
|
11
|
+
"version": "0.1.0",
|
|
12
|
+
"spec": "0.1.0",
|
|
13
|
+
"description": "Created with Anchor"
|
|
14
|
+
},
|
|
15
|
+
"instructions": [
|
|
16
|
+
{
|
|
17
|
+
"name": "initializeExtraAccountMetaList",
|
|
18
|
+
"discriminator": [
|
|
19
|
+
43,
|
|
20
|
+
34,
|
|
21
|
+
13,
|
|
22
|
+
49,
|
|
23
|
+
167,
|
|
24
|
+
88,
|
|
25
|
+
235,
|
|
26
|
+
235
|
|
27
|
+
],
|
|
28
|
+
"accounts": [
|
|
29
|
+
{
|
|
30
|
+
"name": "payer",
|
|
31
|
+
"writable": true,
|
|
32
|
+
"signer": true
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"name": "extraAccountMetaList",
|
|
36
|
+
"writable": true
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"name": "mint"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"name": "systemProgram"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"name": "liqsolCore"
|
|
46
|
+
}
|
|
47
|
+
],
|
|
48
|
+
"args": []
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"name": "transferHook",
|
|
52
|
+
"discriminator": [
|
|
53
|
+
105,
|
|
54
|
+
37,
|
|
55
|
+
101,
|
|
56
|
+
197,
|
|
57
|
+
75,
|
|
58
|
+
251,
|
|
59
|
+
102,
|
|
60
|
+
26
|
|
61
|
+
],
|
|
62
|
+
"accounts": [
|
|
63
|
+
{
|
|
64
|
+
"name": "sourceToken"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"name": "mint"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"name": "destinationToken"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"name": "authority"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"name": "extraAccountMetaList"
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"name": "liqsolCore"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"name": "senderUserRecord",
|
|
83
|
+
"writable": true
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"name": "receiverUserRecord",
|
|
87
|
+
"writable": true
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"name": "distributionState",
|
|
91
|
+
"writable": true
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"name": "bucketTokenAccount"
|
|
95
|
+
}
|
|
96
|
+
],
|
|
97
|
+
"args": [
|
|
98
|
+
{
|
|
99
|
+
"name": "amount",
|
|
100
|
+
"type": "u64"
|
|
101
|
+
}
|
|
102
|
+
]
|
|
103
|
+
}
|
|
104
|
+
],
|
|
105
|
+
"accounts": [
|
|
106
|
+
{
|
|
107
|
+
"name": "distributionState",
|
|
108
|
+
"discriminator": [
|
|
109
|
+
7,
|
|
110
|
+
25,
|
|
111
|
+
94,
|
|
112
|
+
15,
|
|
113
|
+
208,
|
|
114
|
+
170,
|
|
115
|
+
4,
|
|
116
|
+
103
|
|
117
|
+
]
|
|
118
|
+
}
|
|
119
|
+
],
|
|
120
|
+
"errors": [
|
|
121
|
+
{
|
|
122
|
+
"code": 6000,
|
|
123
|
+
"name": "amountTooBig"
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"code": 6001,
|
|
127
|
+
"name": "isNotCurrentlyTransferring"
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"code": 6002,
|
|
131
|
+
"name": "tlvAccountResolutionError"
|
|
132
|
+
}
|
|
133
|
+
],
|
|
134
|
+
"types": [
|
|
135
|
+
{
|
|
136
|
+
"name": "distributionState",
|
|
137
|
+
"type": {
|
|
138
|
+
"kind": "struct",
|
|
139
|
+
"fields": [
|
|
140
|
+
{
|
|
141
|
+
"name": "liqsolMint",
|
|
142
|
+
"type": "pubkey"
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"name": "currentIndex",
|
|
146
|
+
"type": "u64"
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"name": "totalShares",
|
|
150
|
+
"docs": [
|
|
151
|
+
"Sum of all user shares across the system"
|
|
152
|
+
],
|
|
153
|
+
"type": "u64"
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"name": "lastBucketBalance",
|
|
157
|
+
"docs": [
|
|
158
|
+
"Last observed bucket balance used for incremental index updates"
|
|
159
|
+
],
|
|
160
|
+
"type": "u64"
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
"name": "bump",
|
|
164
|
+
"type": "u8"
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
"name": "bucketBump",
|
|
168
|
+
"docs": [
|
|
169
|
+
"Cached bucket authority bump to avoid repeated find_program_address calls"
|
|
170
|
+
],
|
|
171
|
+
"type": "u8"
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
"name": "poolBump",
|
|
175
|
+
"docs": [
|
|
176
|
+
"Cached pool authority bump to avoid repeated find_program_address calls"
|
|
177
|
+
],
|
|
178
|
+
"type": "u8"
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
"name": "bucketAuthority",
|
|
182
|
+
"docs": [
|
|
183
|
+
"Cached bucket authority pubkey for transfer-hook optimization"
|
|
184
|
+
],
|
|
185
|
+
"type": "pubkey"
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
"name": "poolAuthority",
|
|
189
|
+
"docs": [
|
|
190
|
+
"Cached pool authority pubkey for transfer-hook optimization"
|
|
191
|
+
],
|
|
192
|
+
"type": "pubkey"
|
|
193
|
+
}
|
|
194
|
+
]
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
]
|
|
198
|
+
};
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* IDL can be found at `target/idl/validator_leaderboard.json`.
|
|
6
6
|
*/
|
|
7
7
|
export type ValidatorLeaderboard = {
|
|
8
|
-
"address": "
|
|
8
|
+
"address": "H6CWj2PgxCE9Z5dPi9nMrR2VxT1C4DQcqR1QjmLeon47",
|
|
9
9
|
"metadata": {
|
|
10
10
|
"name": "validatorLeaderboard",
|
|
11
11
|
"version": "0.1.0",
|
|
@@ -69,6 +69,149 @@ export type ValidatorLeaderboard = {
|
|
|
69
69
|
],
|
|
70
70
|
"args": []
|
|
71
71
|
},
|
|
72
|
+
{
|
|
73
|
+
"name": "testClearLeaderboard",
|
|
74
|
+
"discriminator": [
|
|
75
|
+
118,
|
|
76
|
+
207,
|
|
77
|
+
26,
|
|
78
|
+
205,
|
|
79
|
+
180,
|
|
80
|
+
7,
|
|
81
|
+
75,
|
|
82
|
+
244
|
|
83
|
+
],
|
|
84
|
+
"accounts": [
|
|
85
|
+
{
|
|
86
|
+
"name": "leaderboardState",
|
|
87
|
+
"writable": true
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"name": "authority",
|
|
91
|
+
"signer": true
|
|
92
|
+
}
|
|
93
|
+
],
|
|
94
|
+
"args": []
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"name": "testForceRegisterValidator",
|
|
98
|
+
"discriminator": [
|
|
99
|
+
136,
|
|
100
|
+
156,
|
|
101
|
+
132,
|
|
102
|
+
32,
|
|
103
|
+
96,
|
|
104
|
+
240,
|
|
105
|
+
7,
|
|
106
|
+
115
|
|
107
|
+
],
|
|
108
|
+
"accounts": [
|
|
109
|
+
{
|
|
110
|
+
"name": "registrant",
|
|
111
|
+
"writable": true,
|
|
112
|
+
"signer": true
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"name": "voteAccount"
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"name": "validatorRecord",
|
|
119
|
+
"writable": true
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"name": "leaderboardState",
|
|
123
|
+
"writable": true
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"name": "systemProgram"
|
|
127
|
+
}
|
|
128
|
+
],
|
|
129
|
+
"args": [
|
|
130
|
+
{
|
|
131
|
+
"name": "vpp",
|
|
132
|
+
"type": "u8"
|
|
133
|
+
}
|
|
134
|
+
]
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"name": "testForceUpdateVpp",
|
|
138
|
+
"discriminator": [
|
|
139
|
+
67,
|
|
140
|
+
51,
|
|
141
|
+
28,
|
|
142
|
+
174,
|
|
143
|
+
200,
|
|
144
|
+
214,
|
|
145
|
+
203,
|
|
146
|
+
162
|
|
147
|
+
],
|
|
148
|
+
"accounts": [
|
|
149
|
+
{
|
|
150
|
+
"name": "registrant",
|
|
151
|
+
"writable": true,
|
|
152
|
+
"signer": true
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
"name": "voteAccount"
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
"name": "validatorRecord",
|
|
159
|
+
"writable": true
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
"name": "leaderboardState",
|
|
163
|
+
"writable": true
|
|
164
|
+
}
|
|
165
|
+
],
|
|
166
|
+
"args": [
|
|
167
|
+
{
|
|
168
|
+
"name": "vpp",
|
|
169
|
+
"type": "u8"
|
|
170
|
+
}
|
|
171
|
+
]
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
"name": "testSeedRandomValidators",
|
|
175
|
+
"discriminator": [
|
|
176
|
+
48,
|
|
177
|
+
155,
|
|
178
|
+
181,
|
|
179
|
+
112,
|
|
180
|
+
163,
|
|
181
|
+
242,
|
|
182
|
+
43,
|
|
183
|
+
146
|
|
184
|
+
],
|
|
185
|
+
"accounts": [
|
|
186
|
+
{
|
|
187
|
+
"name": "registrant",
|
|
188
|
+
"writable": true,
|
|
189
|
+
"signer": true
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
"name": "leaderboardState",
|
|
193
|
+
"writable": true
|
|
194
|
+
}
|
|
195
|
+
],
|
|
196
|
+
"args": [
|
|
197
|
+
{
|
|
198
|
+
"name": "count",
|
|
199
|
+
"type": "u16"
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
"name": "seed",
|
|
203
|
+
"type": "u64"
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
"name": "minVpp",
|
|
207
|
+
"type": "u8"
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
"name": "maxVpp",
|
|
211
|
+
"type": "u8"
|
|
212
|
+
}
|
|
213
|
+
]
|
|
214
|
+
},
|
|
72
215
|
{
|
|
73
216
|
"name": "updateCommission",
|
|
74
217
|
"discriminator": [
|
|
@@ -163,7 +306,7 @@ export type ValidatorLeaderboard = {
|
|
|
163
306
|
"args": [
|
|
164
307
|
{
|
|
165
308
|
"name": "vpp",
|
|
166
|
-
"type": "
|
|
309
|
+
"type": "u8"
|
|
167
310
|
},
|
|
168
311
|
{
|
|
169
312
|
"name": "proposedRank",
|
|
@@ -360,12 +503,12 @@ export type ValidatorLeaderboard = {
|
|
|
360
503
|
{
|
|
361
504
|
"name": "scores",
|
|
362
505
|
"docs": [
|
|
363
|
-
"VPP scores indexed by registry_index",
|
|
506
|
+
"VPP scores indexed by registry_index (0-100 range)",
|
|
364
507
|
"registry_index is assigned on first validator registration and never changes"
|
|
365
508
|
],
|
|
366
509
|
"type": {
|
|
367
510
|
"array": [
|
|
368
|
-
"
|
|
511
|
+
"u8",
|
|
369
512
|
1024
|
|
370
513
|
]
|
|
371
514
|
}
|
|
@@ -242,11 +242,6 @@ export class EthereumStakingClient implements IStakingClient {
|
|
|
242
242
|
decimals: nativeDecimals,
|
|
243
243
|
symbol: liqSymbol,
|
|
244
244
|
},
|
|
245
|
-
tracked: {
|
|
246
|
-
amount: liqBalance.toBigInt(),
|
|
247
|
-
decimals: nativeDecimals,
|
|
248
|
-
symbol: liqSymbol,
|
|
249
|
-
},
|
|
250
245
|
staked: {
|
|
251
246
|
amount: stakedLiqBalance.toBigInt(),
|
|
252
247
|
decimals: nativeDecimals,
|
|
@@ -300,7 +300,7 @@ export async function buildEthereumTrancheSnapshot(options: {
|
|
|
300
300
|
priceGrowthBps,
|
|
301
301
|
currentTrancheSupply,
|
|
302
302
|
initialTrancheSupply,
|
|
303
|
-
|
|
303
|
+
totalPretokensSold: totalTrancheSupply,
|
|
304
304
|
nativePriceUsd: ethPriceUsd,
|
|
305
305
|
nativePriceTimestamp,
|
|
306
306
|
ladder,
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { AnchorProvider, BN, Program } from '@coral-xyz/anchor';
|
|
2
2
|
import {
|
|
3
|
-
PublicKey,
|
|
4
3
|
SystemProgram,
|
|
5
4
|
Transaction,
|
|
6
5
|
TransactionInstruction,
|
|
@@ -27,26 +26,54 @@ import {
|
|
|
27
26
|
deriveReservePoolPda,
|
|
28
27
|
deriveVaultPda,
|
|
29
28
|
deriveStakeControllerStatePda,
|
|
29
|
+
derivePayoutStatePda,
|
|
30
30
|
deriveBucketAuthorityPda,
|
|
31
31
|
derivePayRateHistoryPda,
|
|
32
32
|
deriveDistributionStatePda,
|
|
33
33
|
deriveUserRecordPda,
|
|
34
|
-
derivePayoutStatePda,
|
|
35
34
|
deriveEphemeralStakeAddress,
|
|
35
|
+
deriveWithdrawGlobalPda,
|
|
36
|
+
deriveStakeAllocationStatePda,
|
|
37
|
+
deriveStakeMetricsPda,
|
|
38
|
+
deriveMaintenanceLedgerPda,
|
|
39
|
+
deriveWithdrawMintAuthorityPda,
|
|
40
|
+
deriveWithdrawMintMetadataPda,
|
|
41
|
+
deriveWithdrawNftMintPda,
|
|
42
|
+
deriveLiqReceiptDataPda,
|
|
36
43
|
} from '../constants';
|
|
37
44
|
import { WalletLike } from '../types';
|
|
38
45
|
|
|
39
46
|
export class DepositClient {
|
|
40
47
|
private program: Program<LiqsolCore>;
|
|
41
48
|
|
|
42
|
-
get wallet(): WalletLike {
|
|
49
|
+
get wallet(): WalletLike {
|
|
50
|
+
return this.provider.wallet;
|
|
51
|
+
}
|
|
43
52
|
|
|
44
53
|
constructor(private provider: AnchorProvider) {
|
|
45
54
|
const svc = new SolanaProgramService(provider);
|
|
46
55
|
this.program = svc.getProgram('liqsolCore');
|
|
47
56
|
}
|
|
48
57
|
|
|
49
|
-
|
|
58
|
+
/**
|
|
59
|
+
* Build a deposit transaction:
|
|
60
|
+
* SOL -> liqSOL via liqsol_core::deposit.
|
|
61
|
+
*/
|
|
62
|
+
async buildDepositTx(
|
|
63
|
+
amount: bigint,
|
|
64
|
+
user = this.wallet.publicKey,
|
|
65
|
+
): Promise<Transaction> {
|
|
66
|
+
if (!user) {
|
|
67
|
+
throw new Error(
|
|
68
|
+
'DepositClient.buildDepositTx: wallet not connected',
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
if (!amount || amount <= BigInt(0)) {
|
|
72
|
+
throw new Error(
|
|
73
|
+
'DepositClient.buildDepositTx: amount must be greater than zero.',
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
50
77
|
// -------------------------------------------------------------
|
|
51
78
|
// PDAs
|
|
52
79
|
// -------------------------------------------------------------
|
|
@@ -59,8 +86,6 @@ export class DepositClient {
|
|
|
59
86
|
const payoutState = derivePayoutStatePda();
|
|
60
87
|
const bucketAuthority = deriveBucketAuthorityPda();
|
|
61
88
|
const payRateHistory = derivePayRateHistoryPda();
|
|
62
|
-
const distributionState = deriveDistributionStatePda();
|
|
63
|
-
const userRecord = deriveUserRecordPda(user);
|
|
64
89
|
|
|
65
90
|
// -------------------------------------------------------------
|
|
66
91
|
// Token-2022 ATAs
|
|
@@ -69,14 +94,20 @@ export class DepositClient {
|
|
|
69
94
|
liqsolMint,
|
|
70
95
|
user,
|
|
71
96
|
false,
|
|
72
|
-
TOKEN_2022_PROGRAM_ID
|
|
97
|
+
TOKEN_2022_PROGRAM_ID,
|
|
73
98
|
);
|
|
74
99
|
|
|
100
|
+
// -------------------------------------------------------------
|
|
101
|
+
// Distribution state + user_record (KEYED BY TOKEN ACCOUNT)
|
|
102
|
+
// -------------------------------------------------------------
|
|
103
|
+
const distributionState = deriveDistributionStatePda();
|
|
104
|
+
const userRecord = deriveUserRecordPda(userAta);
|
|
105
|
+
|
|
75
106
|
const bucketTokenAccount = getAssociatedTokenAddressSync(
|
|
76
107
|
liqsolMint,
|
|
77
108
|
bucketAuthority,
|
|
78
109
|
true,
|
|
79
|
-
TOKEN_2022_PROGRAM_ID
|
|
110
|
+
TOKEN_2022_PROGRAM_ID,
|
|
80
111
|
);
|
|
81
112
|
|
|
82
113
|
// -------------------------------------------------------------
|
|
@@ -124,4 +155,119 @@ export class DepositClient {
|
|
|
124
155
|
|
|
125
156
|
return new Transaction().add(ix);
|
|
126
157
|
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Build a withdraw-request transaction:
|
|
161
|
+
* liqSOL -> SOL via liqsol_core::requestWithdraw.
|
|
162
|
+
*
|
|
163
|
+
* This:
|
|
164
|
+
* - burns liqSOL from the user
|
|
165
|
+
* - increments totalEncumberedFunds in global state
|
|
166
|
+
* - mints an NFT receipt (liqReceiptData + NFT ATA for owner)
|
|
167
|
+
*/
|
|
168
|
+
async buildWithdrawTx(
|
|
169
|
+
amount: bigint,
|
|
170
|
+
user = this.wallet.publicKey,
|
|
171
|
+
): Promise<Transaction> {
|
|
172
|
+
if (!user) {
|
|
173
|
+
throw new Error(
|
|
174
|
+
'DepositClient.buildWithdrawTx: wallet not connected',
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
if (!amount || amount <= BigInt(0)) {
|
|
178
|
+
throw new Error(
|
|
179
|
+
'DepositClient.buildWithdrawTx: amount must be greater than zero.',
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// -------------------------------------------------------------
|
|
184
|
+
// Core program + liqSOL mint / user ATA
|
|
185
|
+
// -------------------------------------------------------------
|
|
186
|
+
const liqsolMint = deriveLiqsolMintPda();
|
|
187
|
+
|
|
188
|
+
const userAta = getAssociatedTokenAddressSync(
|
|
189
|
+
liqsolMint,
|
|
190
|
+
user,
|
|
191
|
+
false,
|
|
192
|
+
TOKEN_2022_PROGRAM_ID,
|
|
193
|
+
);
|
|
194
|
+
|
|
195
|
+
// Distribution / balance-tracking
|
|
196
|
+
// user_record is keyed by the user’s liqSOL ATA (same convention as deposit/purchase)
|
|
197
|
+
const userRecord = deriveUserRecordPda(userAta);
|
|
198
|
+
const distributionState = deriveDistributionStatePda();
|
|
199
|
+
|
|
200
|
+
// Reserve + stake controller PDAs
|
|
201
|
+
const global = deriveWithdrawGlobalPda();
|
|
202
|
+
const reservePool = deriveReservePoolPda();
|
|
203
|
+
const stakeAllocationState = deriveStakeAllocationStatePda();
|
|
204
|
+
const stakeMetrics = deriveStakeMetricsPda();
|
|
205
|
+
const maintenanceLedger = deriveMaintenanceLedgerPda();
|
|
206
|
+
|
|
207
|
+
// -------------------------------------------------------------
|
|
208
|
+
// Need nextReceiptId from withdraw global state
|
|
209
|
+
// -------------------------------------------------------------
|
|
210
|
+
const globalState = await this.program.account.global.fetch(global);
|
|
211
|
+
const receiptId = (globalState.nextReceiptId as BN).toBigInt();
|
|
212
|
+
|
|
213
|
+
// -------------------------------------------------------------
|
|
214
|
+
// NFT receipt PDAs (mint, metadata, data, ATA)
|
|
215
|
+
// -------------------------------------------------------------
|
|
216
|
+
const mintAuthority = deriveWithdrawMintAuthorityPda();
|
|
217
|
+
const metadata = deriveWithdrawMintMetadataPda();
|
|
218
|
+
|
|
219
|
+
const nftMint = deriveWithdrawNftMintPda(receiptId);
|
|
220
|
+
const receiptData = deriveLiqReceiptDataPda(nftMint);
|
|
221
|
+
|
|
222
|
+
const owner = user;
|
|
223
|
+
const nftAta = getAssociatedTokenAddressSync(
|
|
224
|
+
nftMint,
|
|
225
|
+
owner,
|
|
226
|
+
false,
|
|
227
|
+
TOKEN_2022_PROGRAM_ID,
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
// Bucket token account (same bucket used by deposit/distribution)
|
|
231
|
+
const bucketAuthority = deriveBucketAuthorityPda();
|
|
232
|
+
const bucketTokenAccount = getAssociatedTokenAddressSync(
|
|
233
|
+
liqsolMint,
|
|
234
|
+
bucketAuthority,
|
|
235
|
+
true,
|
|
236
|
+
TOKEN_2022_PROGRAM_ID,
|
|
237
|
+
);
|
|
238
|
+
|
|
239
|
+
// -------------------------------------------------------------
|
|
240
|
+
// BUILD IX (MUST MATCH requestWithdraw IDL)
|
|
241
|
+
// -------------------------------------------------------------
|
|
242
|
+
const ix: TransactionInstruction = await this.program.methods
|
|
243
|
+
.requestWithdraw(new BN(amount.toString()))
|
|
244
|
+
.accounts({
|
|
245
|
+
user,
|
|
246
|
+
owner,
|
|
247
|
+
global,
|
|
248
|
+
liqsolMint,
|
|
249
|
+
userAta,
|
|
250
|
+
userRecord,
|
|
251
|
+
reservePool,
|
|
252
|
+
stakeAllocationState,
|
|
253
|
+
stakeMetrics,
|
|
254
|
+
maintenanceLedger,
|
|
255
|
+
clock: SYSVAR_CLOCK_PUBKEY,
|
|
256
|
+
mintAuthority,
|
|
257
|
+
receiptData,
|
|
258
|
+
metadata,
|
|
259
|
+
nftMint,
|
|
260
|
+
nftAta,
|
|
261
|
+
distributionState,
|
|
262
|
+
bucketTokenAccount,
|
|
263
|
+
tokenProgram: TOKEN_2022_PROGRAM_ID,
|
|
264
|
+
tokenInterface: TOKEN_2022_PROGRAM_ID,
|
|
265
|
+
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
266
|
+
systemProgram: SystemProgram.programId,
|
|
267
|
+
rent: SYSVAR_RENT_PUBKEY,
|
|
268
|
+
})
|
|
269
|
+
.instruction();
|
|
270
|
+
|
|
271
|
+
return new Transaction().add(ix);
|
|
272
|
+
}
|
|
127
273
|
}
|