@wireio/stake 0.4.1 → 0.4.3
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 +994 -302
- package/lib/stake.browser.js.map +1 -1
- package/lib/stake.d.ts +786 -163
- package/lib/stake.js +973 -276
- package/lib/stake.js.map +1 -1
- package/lib/stake.m.js +994 -302
- package/lib/stake.m.js.map +1 -1
- package/package.json +2 -2
- package/src/assets/solana/idl/liqsol_core.json +760 -150
- package/src/assets/solana/idl/liqsol_token.json +1 -1
- package/src/assets/solana/idl/transfer_hook.json +6 -1
- package/src/assets/solana/idl/validator_leaderboard.json +4 -1
- package/src/assets/solana/types/liqsol_core.ts +760 -150
- package/src/assets/solana/types/liqsol_token.ts +1 -1
- package/src/assets/solana/types/transfer_hook.ts +6 -1
- package/src/assets/solana/types/validator_leaderboard.ts +4 -1
- package/src/networks/ethereum/ethereum.ts +153 -85
- package/src/networks/solana/clients/deposit.client.ts +5 -4
- package/src/networks/solana/constants.ts +14 -0
- package/src/networks/solana/solana.ts +52 -28
- package/src/types.ts +22 -10
|
@@ -193,7 +193,7 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
193
193
|
* Handles tx build, sign, send, and confirmation.
|
|
194
194
|
*/
|
|
195
195
|
async deposit(amountLamports: bigint): Promise<string> {
|
|
196
|
-
this.
|
|
196
|
+
this.ensureUser();
|
|
197
197
|
if (amountLamports <= BigInt(0)) {
|
|
198
198
|
throw new Error('Deposit amount must be greater than zero.');
|
|
199
199
|
}
|
|
@@ -219,7 +219,7 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
219
219
|
* Actual SOL payout happens later via the operator-side flow.
|
|
220
220
|
*/
|
|
221
221
|
async withdraw(amountLamports: bigint): Promise<string> {
|
|
222
|
-
this.
|
|
222
|
+
this.ensureUser();
|
|
223
223
|
if (amountLamports <= BigInt(0)) {
|
|
224
224
|
throw new Error('Withdraw amount must be greater than zero.');
|
|
225
225
|
}
|
|
@@ -238,7 +238,7 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
238
238
|
* Stake liqSOL into Outpost (liqSOL → pool) via liqsol_core::synd.
|
|
239
239
|
*/
|
|
240
240
|
async stake(amountLamports: bigint): Promise<string> {
|
|
241
|
-
this.
|
|
241
|
+
this.ensureUser();
|
|
242
242
|
|
|
243
243
|
if (!amountLamports || amountLamports <= BigInt(0)) {
|
|
244
244
|
throw new Error('Stake amount must be greater than zero.');
|
|
@@ -246,11 +246,14 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
246
246
|
|
|
247
247
|
const user = this.solPubKey;
|
|
248
248
|
|
|
249
|
+
// Build compute budget increase instruction
|
|
250
|
+
const cuIx = ComputeBudgetProgram.setComputeUnitLimit({ units: 400_000 });
|
|
251
|
+
|
|
249
252
|
// Build the Outpost synd instruction
|
|
250
253
|
const ix = await this.outpostClient.buildStakeIx(amountLamports, user);
|
|
251
254
|
|
|
252
255
|
// Wrap in a transaction and send
|
|
253
|
-
const tx = new Transaction().add(ix);
|
|
256
|
+
const tx = new Transaction().add(cuIx, ix);
|
|
254
257
|
const prepared = await this.prepareTx(tx);
|
|
255
258
|
const signed = await this.signTransaction(prepared.tx);
|
|
256
259
|
|
|
@@ -261,7 +264,7 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
261
264
|
* Unstake liqSOL from Outpost (pool → liqSOL) via liqsol_core::desynd.
|
|
262
265
|
*/
|
|
263
266
|
async unstake(amountLamports: bigint): Promise<string> {
|
|
264
|
-
this.
|
|
267
|
+
this.ensureUser();
|
|
265
268
|
|
|
266
269
|
if (!amountLamports || amountLamports <= BigInt(0)) {
|
|
267
270
|
throw new Error('Unstake amount must be greater than zero.');
|
|
@@ -269,11 +272,14 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
269
272
|
|
|
270
273
|
const user = this.solPubKey;
|
|
271
274
|
|
|
275
|
+
// Build compute budget increase instruction
|
|
276
|
+
const cuIx = ComputeBudgetProgram.setComputeUnitLimit({ units: 400_000 });
|
|
277
|
+
|
|
272
278
|
// Build the Outpost desynd instruction
|
|
273
279
|
const ix = await this.outpostClient.buildUnstakeIx(amountLamports, user);
|
|
274
280
|
|
|
275
281
|
// Wrap in a transaction and send
|
|
276
|
-
const tx = new Transaction().add(ix);
|
|
282
|
+
const tx = new Transaction().add(cuIx, ix);
|
|
277
283
|
const prepared = await this.prepareTx(tx);
|
|
278
284
|
const signed = await this.signTransaction(prepared.tx);
|
|
279
285
|
|
|
@@ -287,7 +293,7 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
287
293
|
* instruction under the new IDL (no more native-SOL purchase).
|
|
288
294
|
*/
|
|
289
295
|
async buy(amountLamports: bigint): Promise<string> {
|
|
290
|
-
this.
|
|
296
|
+
this.ensureUser();
|
|
291
297
|
if (!amountLamports || amountLamports <= BigInt(0)) {
|
|
292
298
|
throw new Error('liqSOL pretoken purchase requires a positive amount.');
|
|
293
299
|
}
|
|
@@ -376,7 +382,7 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
376
382
|
// - totalShares: globalState.totalShares
|
|
377
383
|
// - userShares: outpostAccount.stakedShares
|
|
378
384
|
// - estimatedClaimLiqsol: floor(userShares * index / INDEX_SCALE)
|
|
379
|
-
// -
|
|
385
|
+
// - estimatedYield: max(0, estimatedClaim - stakedLiqsol)
|
|
380
386
|
//
|
|
381
387
|
// This matches the capital-staking math:
|
|
382
388
|
// sharesToTokens(shares, index) = shares * index / INDEX_SCALE
|
|
@@ -392,15 +398,15 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
392
398
|
const totalShares = BigInt(totalSharesStr);
|
|
393
399
|
const userShares = BigInt(userSharesStr);
|
|
394
400
|
|
|
395
|
-
let
|
|
396
|
-
let
|
|
401
|
+
let estimatedClaim = BigInt(0);
|
|
402
|
+
let estimatedYield = BigInt(0);
|
|
397
403
|
|
|
398
404
|
if (userShares > BigInt(0) && currentIndex > BigInt(0)) {
|
|
399
405
|
// sharesToTokens(userShares, currentIndex)
|
|
400
|
-
|
|
406
|
+
estimatedClaim = (userShares * currentIndex) / INDEX_SCALE;
|
|
401
407
|
|
|
402
|
-
if (
|
|
403
|
-
|
|
408
|
+
if (estimatedClaim > stakedLiqsol) {
|
|
409
|
+
estimatedYield = estimatedClaim - stakedLiqsol;
|
|
404
410
|
}
|
|
405
411
|
}
|
|
406
412
|
|
|
@@ -435,8 +441,8 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
435
441
|
totalShares,
|
|
436
442
|
userShares,
|
|
437
443
|
// liqSOL amounts (lamports) implied by index/shares
|
|
438
|
-
|
|
439
|
-
|
|
444
|
+
estimatedClaim,
|
|
445
|
+
estimatedYield,
|
|
440
446
|
},
|
|
441
447
|
extras: {
|
|
442
448
|
userLiqsolAta: userLiqsolAta.toBase58(),
|
|
@@ -453,6 +459,33 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
453
459
|
};
|
|
454
460
|
}
|
|
455
461
|
|
|
462
|
+
/**
|
|
463
|
+
* Convenience helper to fetch the distribution userRecord for the current user.
|
|
464
|
+
* Used by balance-correction flows and debugging.
|
|
465
|
+
*/
|
|
466
|
+
async getUserRecord() {
|
|
467
|
+
if (!this.pubKey) throw new Error('User pubKey is undefined');
|
|
468
|
+
return this.distributionClient.getUserRecord(this.solPubKey);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
|
|
472
|
+
// ---------------------------------------------------------------------
|
|
473
|
+
// READ-ONLY Public Methods
|
|
474
|
+
// ---------------------------------------------------------------------
|
|
475
|
+
|
|
476
|
+
// Estimated total APY for staking yeild
|
|
477
|
+
getSystemAPY(): Promise<number> {
|
|
478
|
+
// TODO
|
|
479
|
+
return Promise.resolve(0);
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
// Protocol fee charged for deposit from Native to LIQ
|
|
483
|
+
getDepositFee(amount: bigint): Promise<bigint> {
|
|
484
|
+
// Returning 1% for now,
|
|
485
|
+
// TODO: fetch real fee from on-chain config
|
|
486
|
+
return Promise.resolve((amount * BigInt(1)) / BigInt(100));
|
|
487
|
+
}
|
|
488
|
+
|
|
456
489
|
/**
|
|
457
490
|
* Unified, chain-agnostic tranche snapshot for Solana.
|
|
458
491
|
*
|
|
@@ -493,15 +526,6 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
493
526
|
});
|
|
494
527
|
}
|
|
495
528
|
|
|
496
|
-
/**
|
|
497
|
-
* Convenience helper to fetch the distribution userRecord for the current user.
|
|
498
|
-
* Used by balance-correction flows and debugging.
|
|
499
|
-
*/
|
|
500
|
-
async getUserRecord() {
|
|
501
|
-
if (!this.pubKey) throw new Error('User pubKey is undefined');
|
|
502
|
-
return this.distributionClient.getUserRecord(this.solPubKey);
|
|
503
|
-
}
|
|
504
|
-
|
|
505
529
|
// ---------------------------------------------------------------------
|
|
506
530
|
// Tx helpers
|
|
507
531
|
// ---------------------------------------------------------------------
|
|
@@ -514,7 +538,7 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
514
538
|
signed: SolanaTransaction,
|
|
515
539
|
ctx: { blockhash: string; lastValidBlockHeight: number },
|
|
516
540
|
): Promise<string> {
|
|
517
|
-
this.
|
|
541
|
+
this.ensureUser();
|
|
518
542
|
|
|
519
543
|
const signature = await this.connection.sendRawTransaction(
|
|
520
544
|
signed.serialize(),
|
|
@@ -549,7 +573,7 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
549
573
|
async signTransaction(
|
|
550
574
|
tx: SolanaTransaction,
|
|
551
575
|
): Promise<SolanaTransaction> {
|
|
552
|
-
this.
|
|
576
|
+
this.ensureUser();
|
|
553
577
|
return this.anchor.wallet.signTransaction(tx);
|
|
554
578
|
}
|
|
555
579
|
|
|
@@ -560,7 +584,7 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
560
584
|
async sendTransaction(
|
|
561
585
|
signed: SolanaTransaction,
|
|
562
586
|
): Promise<TransactionSignature> {
|
|
563
|
-
this.
|
|
587
|
+
this.ensureUser();
|
|
564
588
|
return this.anchor.sendAndConfirm(signed);
|
|
565
589
|
}
|
|
566
590
|
|
|
@@ -586,7 +610,7 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
586
610
|
* Guard for all write operations (deposit/withdraw/stake/unstake/buy).
|
|
587
611
|
* Ensures we have a Wire pubKey and an Anchor wallet pubKey, and that they match.
|
|
588
612
|
*/
|
|
589
|
-
|
|
613
|
+
ensureUser() {
|
|
590
614
|
if (!this.pubKey || !this.anchor.wallet.publicKey) {
|
|
591
615
|
throw new Error('User Authorization required: pubKey is undefined');
|
|
592
616
|
}
|
package/src/types.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { ethers } from 'ethers';
|
|
|
5
5
|
|
|
6
6
|
export type StakerConfig = {
|
|
7
7
|
network: ExternalNetwork;
|
|
8
|
-
provider
|
|
8
|
+
provider?: BaseSignerWalletAdapter | ethers.providers.Web3Provider;
|
|
9
9
|
pubKey?: PublicKey;
|
|
10
10
|
}
|
|
11
11
|
|
|
@@ -23,6 +23,12 @@ export interface IStakingClient {
|
|
|
23
23
|
/** Fetch the complete user portfolio */
|
|
24
24
|
getPortfolio(): Promise<Portfolio>;
|
|
25
25
|
|
|
26
|
+
// Estimated total APY for staking yeild
|
|
27
|
+
getSystemAPY(): Promise<number>;
|
|
28
|
+
|
|
29
|
+
// Protocol fee charged for deposit from Native to LIQ
|
|
30
|
+
getDepositFee(amount: bigint): Promise<bigint>;
|
|
31
|
+
|
|
26
32
|
/**
|
|
27
33
|
* Program-level prelaunch WIRE/tranche snapshot for this chain.
|
|
28
34
|
*
|
|
@@ -35,6 +41,12 @@ export interface IStakingClient {
|
|
|
35
41
|
windowBefore?: number;
|
|
36
42
|
windowAfter?: number;
|
|
37
43
|
}): Promise<TrancheSnapshot | null>;
|
|
44
|
+
|
|
45
|
+
// Estimated total APY for staking yeild
|
|
46
|
+
getSystemAPY(): Promise<number>;
|
|
47
|
+
|
|
48
|
+
// Protocol fee charged for deposit from Native to LIQ
|
|
49
|
+
getDepositFee(amount: bigint): Promise<bigint>;
|
|
38
50
|
}
|
|
39
51
|
|
|
40
52
|
/**
|
|
@@ -106,9 +118,9 @@ export interface BalanceView {
|
|
|
106
118
|
}
|
|
107
119
|
|
|
108
120
|
/**
|
|
109
|
-
*
|
|
121
|
+
* Outpost yield view.
|
|
110
122
|
*
|
|
111
|
-
* All amounts are integers in base units (lamports for liqSOL).
|
|
123
|
+
* All amounts are integers in base units (lamports for liqSOL, wei for liqETH).
|
|
112
124
|
*
|
|
113
125
|
* Math matches capital-staking:
|
|
114
126
|
* INDEX_SCALE = 1e12
|
|
@@ -135,20 +147,20 @@ export interface YieldView {
|
|
|
135
147
|
userShares: bigint;
|
|
136
148
|
|
|
137
149
|
/**
|
|
138
|
-
* Total
|
|
150
|
+
* Total liq (wei/lamports) the user could claim right now if they fully
|
|
139
151
|
* unwound their stake:
|
|
140
|
-
*
|
|
152
|
+
* estimatedClaim = userShares * currentIndex / indexScale
|
|
141
153
|
*/
|
|
142
|
-
|
|
154
|
+
estimatedClaim?: bigint;
|
|
143
155
|
|
|
144
156
|
/**
|
|
145
|
-
* Portion of
|
|
146
|
-
*
|
|
157
|
+
* Portion of estimatedClaim that is “yield” above principal:
|
|
158
|
+
* estimatedYield = max(0, estimatedClaim - staked)
|
|
147
159
|
*
|
|
148
|
-
* NOTE:
|
|
160
|
+
* NOTE: staked principal itself is surfaced separately as
|
|
149
161
|
* Portfolio.staked.amount.
|
|
150
162
|
*/
|
|
151
|
-
|
|
163
|
+
estimatedYield?: bigint;
|
|
152
164
|
}
|
|
153
165
|
|
|
154
166
|
export interface TrancheLadderItem {
|