@wireio/stake 2.2.1 → 2.3.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/README.md +185 -243
- package/lib/stake.browser.js +343 -202
- package/lib/stake.browser.js.map +1 -1
- package/lib/stake.d.ts +104 -23
- package/lib/stake.js +511 -331
- package/lib/stake.js.map +1 -1
- package/lib/stake.m.js +343 -202
- package/lib/stake.m.js.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +2 -2
- package/src/networks/ethereum/clients/receipt.client.ts +54 -69
- package/src/networks/ethereum/clients/validator.client.ts +61 -0
- package/src/networks/ethereum/ethereum.ts +21 -1
- package/src/networks/ethereum/types.ts +21 -17
- package/src/networks/solana/clients/convert.client.ts +339 -0
- package/src/networks/solana/solana.ts +35 -6
- package/src/networks/solana/types.ts +22 -0
- package/src/networks/solana/utils.ts +8 -1
- package/src/types.ts +40 -2
- package/src/networks/solana/clients/deposit.client.ts +0 -291
|
@@ -1,291 +0,0 @@
|
|
|
1
|
-
import { AnchorProvider, BN, Program, Wallet } from '@coral-xyz/anchor';
|
|
2
|
-
import {
|
|
3
|
-
SystemProgram,
|
|
4
|
-
Transaction,
|
|
5
|
-
TransactionInstruction,
|
|
6
|
-
StakeProgram,
|
|
7
|
-
SYSVAR_INSTRUCTIONS_PUBKEY,
|
|
8
|
-
SYSVAR_CLOCK_PUBKEY,
|
|
9
|
-
SYSVAR_RENT_PUBKEY,
|
|
10
|
-
SYSVAR_STAKE_HISTORY_PUBKEY,
|
|
11
|
-
Connection,
|
|
12
|
-
PublicKey,
|
|
13
|
-
TransactionMessage,
|
|
14
|
-
LAMPORTS_PER_SOL,
|
|
15
|
-
Signer,
|
|
16
|
-
} from '@solana/web3.js';
|
|
17
|
-
|
|
18
|
-
import {
|
|
19
|
-
TOKEN_2022_PROGRAM_ID,
|
|
20
|
-
ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
21
|
-
getAssociatedTokenAddressSync,
|
|
22
|
-
} from '@solana/spl-token';
|
|
23
|
-
import * as multisig from "@sqds/multisig";
|
|
24
|
-
|
|
25
|
-
import { LiqsolCoreClientIdl, SolanaProgramService } from '../program';
|
|
26
|
-
|
|
27
|
-
import { GlobalAccount, WalletLike } from '../types';
|
|
28
|
-
|
|
29
|
-
export class DepositClient {
|
|
30
|
-
private program: Program<LiqsolCoreClientIdl>;
|
|
31
|
-
|
|
32
|
-
get connection() {
|
|
33
|
-
return this.provider.connection;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
get wallet(): WalletLike {
|
|
37
|
-
return this.provider.wallet;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
constructor(
|
|
41
|
-
private readonly provider: AnchorProvider,
|
|
42
|
-
private readonly pgs: SolanaProgramService
|
|
43
|
-
) {
|
|
44
|
-
this.program = pgs.getProgram('liqsolCore');
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Build a deposit transaction:
|
|
49
|
-
* SOL -> liqSOL via liqsol_core::deposit.
|
|
50
|
-
*/
|
|
51
|
-
async buildDepositTx(
|
|
52
|
-
amount: bigint,
|
|
53
|
-
user = this.wallet.publicKey,
|
|
54
|
-
): Promise<TransactionInstruction> {
|
|
55
|
-
if (!user) {
|
|
56
|
-
throw new Error(
|
|
57
|
-
'DepositClient.buildDepositTx: wallet not connected',
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
|
-
if (!amount || amount <= BigInt(0)) {
|
|
61
|
-
throw new Error(
|
|
62
|
-
'DepositClient.buildDepositTx: amount must be greater than zero.',
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// -------------------------------------------------------------
|
|
67
|
-
// PDAs
|
|
68
|
-
// -------------------------------------------------------------
|
|
69
|
-
const depositAuthority = this.pgs.deriveDepositAuthorityPda();
|
|
70
|
-
const liqsolMint = this.pgs.deriveLiqsolMintPda();
|
|
71
|
-
const liqsolMintAuthority = this.pgs.deriveLiqsolMintAuthorityPda();
|
|
72
|
-
const reservePool = this.pgs.deriveReservePoolPda();
|
|
73
|
-
const vault = this.pgs.deriveVaultPda();
|
|
74
|
-
const controllerState = this.pgs.deriveStakeControllerStatePda();
|
|
75
|
-
const payoutState = this.pgs.derivePayoutStatePda();
|
|
76
|
-
const bucketAuthority = this.pgs.deriveBucketAuthorityPda();
|
|
77
|
-
const payRateHistory = this.pgs.derivePayRateHistoryPda();
|
|
78
|
-
const globalConfig = this.pgs.deriveGlobalConfigPda();
|
|
79
|
-
|
|
80
|
-
// -------------------------------------------------------------
|
|
81
|
-
// Token-2022 ATAs
|
|
82
|
-
// -------------------------------------------------------------
|
|
83
|
-
const userAta = getAssociatedTokenAddressSync(
|
|
84
|
-
liqsolMint,
|
|
85
|
-
user,
|
|
86
|
-
true,
|
|
87
|
-
TOKEN_2022_PROGRAM_ID,
|
|
88
|
-
);
|
|
89
|
-
|
|
90
|
-
// -------------------------------------------------------------
|
|
91
|
-
// Distribution state + user_record (KEYED BY TOKEN ACCOUNT)
|
|
92
|
-
// -------------------------------------------------------------
|
|
93
|
-
const distributionState = this.pgs.deriveDistributionStatePda();
|
|
94
|
-
const userRecord = this.pgs.deriveUserRecordPda(userAta);
|
|
95
|
-
|
|
96
|
-
const bucketTokenAccount = getAssociatedTokenAddressSync(
|
|
97
|
-
liqsolMint,
|
|
98
|
-
bucketAuthority,
|
|
99
|
-
true,
|
|
100
|
-
TOKEN_2022_PROGRAM_ID,
|
|
101
|
-
);
|
|
102
|
-
|
|
103
|
-
// -------------------------------------------------------------
|
|
104
|
-
// Ephemeral stake
|
|
105
|
-
// -------------------------------------------------------------
|
|
106
|
-
const seed = Math.floor(Math.random() * 2 ** 32);
|
|
107
|
-
const ephemeralStake = await this.pgs.deriveEphemeralStakeAddress(user, seed);
|
|
108
|
-
|
|
109
|
-
// -------------------------------------------------------------
|
|
110
|
-
// BUILD IX (MUST MATCH IDL)
|
|
111
|
-
// -------------------------------------------------------------
|
|
112
|
-
return await this.program.methods
|
|
113
|
-
.deposit(new BN(amount.toString()), seed)
|
|
114
|
-
.accounts({
|
|
115
|
-
user,
|
|
116
|
-
depositAuthority,
|
|
117
|
-
systemProgram: SystemProgram.programId,
|
|
118
|
-
tokenProgram: TOKEN_2022_PROGRAM_ID,
|
|
119
|
-
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
120
|
-
liqsolProgram: this.pgs.PROGRAM_IDS.LIQSOL_TOKEN,
|
|
121
|
-
stakeProgram: StakeProgram.programId,
|
|
122
|
-
liqsolMint,
|
|
123
|
-
userAta,
|
|
124
|
-
liqsolMintAuthority,
|
|
125
|
-
reservePool,
|
|
126
|
-
vault,
|
|
127
|
-
ephemeralStake,
|
|
128
|
-
controllerState,
|
|
129
|
-
payoutState,
|
|
130
|
-
bucketAuthority,
|
|
131
|
-
bucketTokenAccount,
|
|
132
|
-
userRecord,
|
|
133
|
-
distributionState,
|
|
134
|
-
payRateHistory,
|
|
135
|
-
instructionsSysvar: SYSVAR_INSTRUCTIONS_PUBKEY,
|
|
136
|
-
clock: SYSVAR_CLOCK_PUBKEY,
|
|
137
|
-
stakeHistory: SYSVAR_STAKE_HISTORY_PUBKEY,
|
|
138
|
-
rent: SYSVAR_RENT_PUBKEY,
|
|
139
|
-
globalConfig
|
|
140
|
-
})
|
|
141
|
-
.instruction();
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Build a withdraw-request transaction:
|
|
146
|
-
* liqSOL -> SOL via liqsol_core::requestWithdraw.
|
|
147
|
-
*
|
|
148
|
-
* This:
|
|
149
|
-
* - burns liqSOL from the user
|
|
150
|
-
* - increments totalEncumberedFunds in global state
|
|
151
|
-
* - mints an NFT receipt (liqReceiptData + NFT ATA for owner)
|
|
152
|
-
*/
|
|
153
|
-
async buildWithdrawTx(
|
|
154
|
-
amount: bigint,
|
|
155
|
-
user = this.wallet.publicKey,
|
|
156
|
-
): Promise<TransactionInstruction> {
|
|
157
|
-
if (!user) {
|
|
158
|
-
throw new Error(
|
|
159
|
-
'DepositClient.buildWithdrawTx: wallet not connected',
|
|
160
|
-
);
|
|
161
|
-
}
|
|
162
|
-
if (!amount || amount <= BigInt(0)) {
|
|
163
|
-
throw new Error(
|
|
164
|
-
'DepositClient.buildWithdrawTx: amount must be greater than zero.',
|
|
165
|
-
);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// -------------------------------------------------------------
|
|
169
|
-
// Core program + liqSOL mint / user ATA
|
|
170
|
-
// -------------------------------------------------------------
|
|
171
|
-
const liqsolMint = this.pgs.deriveLiqsolMintPda();
|
|
172
|
-
|
|
173
|
-
const userAta = getAssociatedTokenAddressSync(
|
|
174
|
-
liqsolMint,
|
|
175
|
-
user,
|
|
176
|
-
true,
|
|
177
|
-
TOKEN_2022_PROGRAM_ID,
|
|
178
|
-
);
|
|
179
|
-
|
|
180
|
-
// Distribution / balance-tracking
|
|
181
|
-
// user_record is keyed by the user’s liqSOL ATA (same convention
|
|
182
|
-
// as deposit/purchase).
|
|
183
|
-
const userRecord = this.pgs.deriveUserRecordPda(userAta);
|
|
184
|
-
const distributionState = this.pgs.deriveDistributionStatePda();
|
|
185
|
-
|
|
186
|
-
// Reserve + stake controller PDAs
|
|
187
|
-
const global = this.pgs.deriveWithdrawGlobalPda(); // withdraw operator state
|
|
188
|
-
const reservePool = this.pgs.deriveReservePoolPda();
|
|
189
|
-
const stakeAllocationState = this.pgs.deriveStakeAllocationStatePda();
|
|
190
|
-
const stakeMetrics = this.pgs.deriveStakeMetricsPda();
|
|
191
|
-
const maintenanceLedger = this.pgs.deriveMaintenanceLedgerPda();
|
|
192
|
-
const globalConfig = this.pgs.deriveGlobalConfigPda(); // liqSOL config / roles
|
|
193
|
-
|
|
194
|
-
// -------------------------------------------------------------
|
|
195
|
-
// Need nextReceiptId from withdraw global state
|
|
196
|
-
// -------------------------------------------------------------
|
|
197
|
-
const globalAcct: GlobalAccount = await this.program.account.global.fetch(global);
|
|
198
|
-
|
|
199
|
-
const rawId = globalAcct.nextReceiptId;
|
|
200
|
-
let receiptId: bigint;
|
|
201
|
-
|
|
202
|
-
if (typeof rawId === 'bigint') {
|
|
203
|
-
// New-style IDL / accounts returning bigint directly
|
|
204
|
-
receiptId = rawId;
|
|
205
|
-
} else if (rawId != null && typeof rawId === 'object' && 'toString' in rawId) {
|
|
206
|
-
// Anchor BN / bn.js or similar – normalize through string
|
|
207
|
-
receiptId = BigInt(rawId.toString());
|
|
208
|
-
} else if (typeof rawId === 'number') {
|
|
209
|
-
// Just in case someone typed it as a JS number in tests
|
|
210
|
-
receiptId = BigInt(rawId);
|
|
211
|
-
} else {
|
|
212
|
-
throw new Error(
|
|
213
|
-
`DepositClient.buildWithdrawTx: unexpected nextReceiptId type (${typeof rawId})`,
|
|
214
|
-
);
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
// -------------------------------------------------------------
|
|
218
|
-
// NFT receipt PDAs (mint, metadata, data, ATA)
|
|
219
|
-
// -------------------------------------------------------------
|
|
220
|
-
const mintAuthority = this.pgs.deriveWithdrawMintAuthorityPda();
|
|
221
|
-
const metadata = this.pgs.deriveWithdrawMintMetadataPda();
|
|
222
|
-
|
|
223
|
-
const nftMint = this.pgs.deriveWithdrawNftMintPda(receiptId);
|
|
224
|
-
const receiptData = this.pgs.deriveLiqReceiptDataPda(nftMint);
|
|
225
|
-
|
|
226
|
-
const owner = user;
|
|
227
|
-
const nftAta = getAssociatedTokenAddressSync(
|
|
228
|
-
nftMint,
|
|
229
|
-
owner,
|
|
230
|
-
true,
|
|
231
|
-
TOKEN_2022_PROGRAM_ID,
|
|
232
|
-
);
|
|
233
|
-
|
|
234
|
-
// Bucket token account (same bucket used by deposit/distribution)
|
|
235
|
-
const bucketAuthority = this.pgs.deriveBucketAuthorityPda();
|
|
236
|
-
const bucketTokenAccount = getAssociatedTokenAddressSync(
|
|
237
|
-
liqsolMint,
|
|
238
|
-
bucketAuthority,
|
|
239
|
-
true,
|
|
240
|
-
TOKEN_2022_PROGRAM_ID,
|
|
241
|
-
);
|
|
242
|
-
|
|
243
|
-
// -------------------------------------------------------------
|
|
244
|
-
// BUILD IX (MUST MATCH requestWithdraw IDL)
|
|
245
|
-
// -------------------------------------------------------------
|
|
246
|
-
return await this.program.methods
|
|
247
|
-
.requestWithdraw(new BN(amount.toString()))
|
|
248
|
-
.accounts({
|
|
249
|
-
user,
|
|
250
|
-
owner,
|
|
251
|
-
global,
|
|
252
|
-
liqsolMint,
|
|
253
|
-
userAta,
|
|
254
|
-
userRecord,
|
|
255
|
-
reservePool,
|
|
256
|
-
stakeAllocationState,
|
|
257
|
-
stakeMetrics,
|
|
258
|
-
maintenanceLedger,
|
|
259
|
-
clock: SYSVAR_CLOCK_PUBKEY,
|
|
260
|
-
mintAuthority,
|
|
261
|
-
receiptData,
|
|
262
|
-
metadata,
|
|
263
|
-
nftMint,
|
|
264
|
-
nftAta,
|
|
265
|
-
distributionState,
|
|
266
|
-
bucketTokenAccount,
|
|
267
|
-
tokenProgram: TOKEN_2022_PROGRAM_ID,
|
|
268
|
-
tokenInterface: TOKEN_2022_PROGRAM_ID,
|
|
269
|
-
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
270
|
-
systemProgram: SystemProgram.programId,
|
|
271
|
-
rent: SYSVAR_RENT_PUBKEY,
|
|
272
|
-
globalConfig,
|
|
273
|
-
})
|
|
274
|
-
.instruction();
|
|
275
|
-
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
// A “wallet-adapter-like” shape (AnchorProvider.wallet matches this)
|
|
280
|
-
type WalletLikeSigner = {
|
|
281
|
-
publicKey: PublicKey;
|
|
282
|
-
signTransaction: (tx: Transaction) => Promise<Transaction>;
|
|
283
|
-
};
|
|
284
|
-
|
|
285
|
-
function isKeypairSigner(x: any): x is { publicKey: PublicKey; secretKey: Uint8Array } {
|
|
286
|
-
return !!x && x.publicKey instanceof PublicKey && x.secretKey instanceof Uint8Array;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
function isWalletLikeSigner(x: any): x is WalletLikeSigner {
|
|
290
|
-
return !!x && x.publicKey instanceof PublicKey && typeof x.signTransaction === "function";
|
|
291
|
-
}
|