@wireio/stake 0.7.3 → 1.0.1
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 +446 -1057
- package/lib/stake.browser.js.map +1 -1
- package/lib/stake.d.ts +131 -542
- package/lib/stake.js +446 -1059
- package/lib/stake.js.map +1 -1
- package/lib/stake.m.js +446 -1057
- package/lib/stake.m.js.map +1 -1
- package/package.json +1 -1
- package/src/assets/solana/idl/liqsol_core.json +114 -377
- package/src/assets/solana/idl/validator_leaderboard.json +0 -146
- package/src/assets/solana/types/liqsol_core.ts +114 -377
- package/src/assets/solana/types/validator_leaderboard.ts +0 -146
- package/src/networks/ethereum/contract.ts +66 -31
- package/src/networks/ethereum/ethereum.ts +53 -53
- package/src/networks/ethereum/types.ts +1 -2
- package/src/networks/solana/constants.ts +1 -1
- package/src/networks/solana/solana.ts +268 -220
- package/src/staker.ts +1 -3
|
@@ -207,14 +207,22 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
207
207
|
throw new Error('Deposit amount must be greater than zero.');
|
|
208
208
|
}
|
|
209
209
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
210
|
+
try {
|
|
211
|
+
// Build compute budget increase instruction
|
|
212
|
+
const cuIx = ComputeBudgetProgram.setComputeUnitLimit({ units: 400_000 });
|
|
213
|
+
|
|
214
|
+
// Build the Outpost synd instruction
|
|
215
|
+
const ix = await this.depositClient.buildDepositTx(amountLamports);
|
|
216
|
+
|
|
217
|
+
// Wrap in a transaction and send
|
|
218
|
+
const tx = new Transaction().add(cuIx, ix);
|
|
219
|
+
const prepared = await this.prepareTx(tx);
|
|
220
|
+
const signed = await this.signTransaction(prepared.tx);
|
|
221
|
+
|
|
222
|
+
return this.sendAndConfirmHttp(signed, prepared);
|
|
223
|
+
} catch (err) {
|
|
224
|
+
throw new Error(`Failed to deposit Solana: ${err}`);
|
|
225
|
+
}
|
|
218
226
|
}
|
|
219
227
|
|
|
220
228
|
/**
|
|
@@ -233,14 +241,22 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
233
241
|
throw new Error('Withdraw amount must be greater than zero.');
|
|
234
242
|
}
|
|
235
243
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
+
try {
|
|
245
|
+
// Build compute budget increase instruction
|
|
246
|
+
const cuIx = ComputeBudgetProgram.setComputeUnitLimit({ units: 400_000 });
|
|
247
|
+
|
|
248
|
+
// Build the Outpost synd instruction
|
|
249
|
+
const ix = await this.depositClient.buildWithdrawTx(amountLamports);
|
|
250
|
+
|
|
251
|
+
// Wrap in a transaction and send
|
|
252
|
+
const tx = new Transaction().add(cuIx, ix);
|
|
253
|
+
const prepared = await this.prepareTx(tx);
|
|
254
|
+
const signed = await this.signTransaction(prepared.tx);
|
|
255
|
+
|
|
256
|
+
return this.sendAndConfirmHttp(signed, prepared);
|
|
257
|
+
} catch (err) {
|
|
258
|
+
throw new Error(`Failed to withdraw Solana: ${err}`);
|
|
259
|
+
}
|
|
244
260
|
}
|
|
245
261
|
|
|
246
262
|
/**
|
|
@@ -253,20 +269,24 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
253
269
|
throw new Error('Stake amount must be greater than zero.');
|
|
254
270
|
}
|
|
255
271
|
|
|
256
|
-
|
|
272
|
+
try {
|
|
273
|
+
const user = this.solPubKey;
|
|
257
274
|
|
|
258
|
-
|
|
259
|
-
|
|
275
|
+
// Build compute budget increase instruction
|
|
276
|
+
const cuIx = ComputeBudgetProgram.setComputeUnitLimit({ units: 400_000 });
|
|
260
277
|
|
|
261
|
-
|
|
262
|
-
|
|
278
|
+
// Build the Outpost synd instruction
|
|
279
|
+
const ix = await this.outpostClient.buildStakeIx(amountLamports, user);
|
|
263
280
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
281
|
+
// Wrap in a transaction and send
|
|
282
|
+
const tx = new Transaction().add(cuIx, ix);
|
|
283
|
+
const prepared = await this.prepareTx(tx);
|
|
284
|
+
const signed = await this.signTransaction(prepared.tx);
|
|
268
285
|
|
|
269
|
-
|
|
286
|
+
return this.sendAndConfirmHttp(signed, prepared);
|
|
287
|
+
} catch (err) {
|
|
288
|
+
throw new Error(`Failed to stake Solana: ${err}`);
|
|
289
|
+
}
|
|
270
290
|
}
|
|
271
291
|
|
|
272
292
|
/**
|
|
@@ -279,20 +299,25 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
279
299
|
throw new Error('Unstake amount must be greater than zero.');
|
|
280
300
|
}
|
|
281
301
|
|
|
282
|
-
|
|
302
|
+
try {
|
|
303
|
+
const user = this.solPubKey;
|
|
283
304
|
|
|
284
|
-
|
|
285
|
-
|
|
305
|
+
// Build compute budget increase instruction
|
|
306
|
+
const cuIx = ComputeBudgetProgram.setComputeUnitLimit({ units: 400_000 });
|
|
286
307
|
|
|
287
|
-
|
|
288
|
-
|
|
308
|
+
// Build the Outpost desynd instruction
|
|
309
|
+
const ix = await this.outpostClient.buildUnstakeIx(amountLamports, user);
|
|
289
310
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
311
|
+
// Wrap in a transaction and send
|
|
312
|
+
const tx = new Transaction().add(cuIx, ix);
|
|
313
|
+
const prepared = await this.prepareTx(tx);
|
|
314
|
+
const signed = await this.signTransaction(prepared.tx);
|
|
294
315
|
|
|
295
|
-
|
|
316
|
+
return this.sendAndConfirmHttp(signed, prepared);
|
|
317
|
+
}
|
|
318
|
+
catch (err) {
|
|
319
|
+
throw new Error(`Failed to unstake Solana: ${err}`);
|
|
320
|
+
}
|
|
296
321
|
}
|
|
297
322
|
|
|
298
323
|
/**
|
|
@@ -307,17 +332,20 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
307
332
|
throw new Error('liqSOL pretoken purchase requires a positive amount.');
|
|
308
333
|
}
|
|
309
334
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
}
|
|
335
|
+
try {
|
|
336
|
+
const user = this.solPubKey;
|
|
337
|
+
const cuIx = ComputeBudgetProgram.setComputeUnitLimit({ units: 400_000 });
|
|
338
|
+
const ix = await this.tokenClient.buildPurchaseIx(amountLamports, user);
|
|
339
|
+
|
|
340
|
+
const tx = new Transaction().add(cuIx, ix);
|
|
341
|
+
const prepared = await this.prepareTx(tx);
|
|
342
|
+
const signed = await this.signTransaction(prepared.tx);
|
|
343
|
+
|
|
344
|
+
return this.sendAndConfirmHttp(signed, prepared);
|
|
345
|
+
}
|
|
346
|
+
catch (err) {
|
|
347
|
+
throw new Error(`Failed to buy liqSOL pretokens: ${err}`);
|
|
348
|
+
}
|
|
321
349
|
}
|
|
322
350
|
|
|
323
351
|
/**
|
|
@@ -332,140 +360,145 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
332
360
|
async getPortfolio(): Promise<Portfolio> {
|
|
333
361
|
if (!this.pubKey) throw new Error('User pubKey is undefined');
|
|
334
362
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
// NOTE:
|
|
350
|
-
// - nativeLamports: wallet SOL
|
|
351
|
-
// - actualBalResp: liqSOL balance in user ATA
|
|
352
|
-
// - snapshot: Outpost + pretokens + global index/shares
|
|
353
|
-
const [nativeLamports, actualBalResp, snapshot] = await Promise.all([
|
|
354
|
-
this.connection.getBalance(user, 'confirmed'),
|
|
355
|
-
this.connection
|
|
356
|
-
.getTokenAccountBalance(userLiqsolAta, 'confirmed')
|
|
357
|
-
.catch(() => null),
|
|
358
|
-
this.outpostClient.fetchWireState(user).catch(() => null),
|
|
359
|
-
]);
|
|
363
|
+
try {
|
|
364
|
+
const user = this.solPubKey;
|
|
365
|
+
|
|
366
|
+
const reservePoolPDA = deriveReservePoolPda();
|
|
367
|
+
const vaultPDA = deriveVaultPda();
|
|
368
|
+
const liqsolMint = deriveLiqsolMintPda();
|
|
369
|
+
|
|
370
|
+
const userLiqsolAta = getAssociatedTokenAddressSync(
|
|
371
|
+
liqsolMint,
|
|
372
|
+
user,
|
|
373
|
+
false,
|
|
374
|
+
TOKEN_2022_PROGRAM_ID,
|
|
375
|
+
ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
376
|
+
);
|
|
360
377
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
378
|
+
// NOTE:
|
|
379
|
+
// - nativeLamports: wallet SOL
|
|
380
|
+
// - actualBalResp: liqSOL balance in user ATA
|
|
381
|
+
// - snapshot: Outpost + pretokens + global index/shares
|
|
382
|
+
const [nativeLamports, actualBalResp, snapshot] = await Promise.all([
|
|
383
|
+
this.connection.getBalance(user, 'confirmed'),
|
|
384
|
+
this.connection
|
|
385
|
+
.getTokenAccountBalance(userLiqsolAta, 'confirmed')
|
|
386
|
+
.catch(() => null),
|
|
387
|
+
this.outpostClient.fetchWireState(user).catch(() => null),
|
|
388
|
+
]);
|
|
389
|
+
|
|
390
|
+
const LIQSOL_DECIMALS = 9;
|
|
391
|
+
|
|
392
|
+
const actualAmountStr = actualBalResp?.value?.amount ?? '0';
|
|
393
|
+
|
|
394
|
+
const globalState = snapshot?.globalState ?? null;
|
|
395
|
+
const outpostAccount = snapshot?.outpostAccount ?? null;
|
|
396
|
+
const trancheState = snapshot?.trancheState ?? null;
|
|
397
|
+
const userPretokenRecord = snapshot?.userPretokenRecord ?? null;
|
|
398
|
+
|
|
399
|
+
// -----------------------------
|
|
400
|
+
// Staked liqSOL (Outpost)
|
|
401
|
+
// -----------------------------
|
|
402
|
+
// This is the liqSOL that has been syndicated into Outpost via `synd`.
|
|
403
|
+
// It lives on the outpost account as `stakedLiqsol`.
|
|
404
|
+
const stakedLiqsolStr =
|
|
405
|
+
outpostAccount?.stakedLiqsol?.toString?.() ?? '0';
|
|
406
|
+
|
|
407
|
+
// -----------------------------
|
|
408
|
+
// WIRE pretokens (1e8 scale)
|
|
409
|
+
// -----------------------------
|
|
410
|
+
// This is NOT stake — it’s the prelaunch WIRE position.
|
|
411
|
+
const wirePretokensStr =
|
|
412
|
+
userPretokenRecord?.totalPretokensPurchased?.toString?.() ??
|
|
413
|
+
'0';
|
|
414
|
+
|
|
415
|
+
// -----------------------------
|
|
416
|
+
// Yield view (index + shares)
|
|
417
|
+
// -----------------------------
|
|
418
|
+
// We expose:
|
|
419
|
+
// - currentIndex: globalState.currentIndex (1e12 scale)
|
|
420
|
+
// - totalShares: globalState.totalShares
|
|
421
|
+
// - userShares: outpostAccount.stakedShares
|
|
422
|
+
// - estimatedClaimLiqsol: floor(userShares * index / INDEX_SCALE)
|
|
423
|
+
// - estimatedYield: max(0, estimatedClaim - stakedLiqsol)
|
|
424
|
+
//
|
|
425
|
+
// This matches the capital-staking math:
|
|
426
|
+
// sharesToTokens(shares, index) = shares * index / INDEX_SCALE
|
|
427
|
+
const currentIndexStr =
|
|
428
|
+
globalState?.currentIndex?.toString?.() ?? '0';
|
|
429
|
+
const totalSharesStr =
|
|
430
|
+
globalState?.totalShares?.toString?.() ?? '0';
|
|
431
|
+
const userSharesStr =
|
|
432
|
+
outpostAccount?.stakedShares?.toString?.() ?? '0';
|
|
433
|
+
|
|
434
|
+
const stakedLiqsol = BigInt(stakedLiqsolStr);
|
|
435
|
+
const currentIndex = BigInt(currentIndexStr);
|
|
436
|
+
const totalShares = BigInt(totalSharesStr);
|
|
437
|
+
const userShares = BigInt(userSharesStr);
|
|
438
|
+
|
|
439
|
+
let estimatedClaim = BigInt(0);
|
|
440
|
+
let estimatedYield = BigInt(0);
|
|
441
|
+
|
|
442
|
+
if (userShares > BigInt(0) && currentIndex > BigInt(0)) {
|
|
443
|
+
// sharesToTokens(userShares, currentIndex)
|
|
444
|
+
estimatedClaim = (userShares * currentIndex) / INDEX_SCALE;
|
|
445
|
+
|
|
446
|
+
if (estimatedClaim > stakedLiqsol) {
|
|
447
|
+
estimatedYield = estimatedClaim - stakedLiqsol;
|
|
448
|
+
}
|
|
419
449
|
}
|
|
420
|
-
}
|
|
421
450
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
451
|
+
return {
|
|
452
|
+
native: {
|
|
453
|
+
amount: BigInt(nativeLamports),
|
|
454
|
+
symbol: 'SOL',
|
|
455
|
+
decimals: 9,
|
|
456
|
+
},
|
|
457
|
+
liq: {
|
|
458
|
+
amount: BigInt(actualAmountStr),
|
|
459
|
+
symbol: 'LiqSOL',
|
|
460
|
+
decimals: LIQSOL_DECIMALS,
|
|
461
|
+
ata: userLiqsolAta,
|
|
462
|
+
},
|
|
463
|
+
staked: {
|
|
464
|
+
// liqSOL staked in Outpost via `synd`
|
|
465
|
+
amount: stakedLiqsol,
|
|
466
|
+
symbol: 'LiqSOL',
|
|
467
|
+
decimals: LIQSOL_DECIMALS,
|
|
468
|
+
},
|
|
469
|
+
wire: {
|
|
470
|
+
// Prelaunch WIRE pretokens (1e8 scale)
|
|
471
|
+
amount: BigInt(wirePretokensStr),
|
|
472
|
+
symbol: '$WIRE',
|
|
473
|
+
decimals: 8,
|
|
474
|
+
},
|
|
475
|
+
yield: {
|
|
476
|
+
// Raw primitives so the frontend can display curves, charts, etc.
|
|
477
|
+
currentIndex,
|
|
478
|
+
indexScale: INDEX_SCALE,
|
|
479
|
+
totalShares,
|
|
480
|
+
userShares,
|
|
481
|
+
// liqSOL amounts (lamports) implied by index/shares
|
|
482
|
+
estimatedClaim,
|
|
483
|
+
estimatedYield,
|
|
484
|
+
},
|
|
485
|
+
extras: {
|
|
486
|
+
userLiqsolAta: userLiqsolAta.toBase58(),
|
|
487
|
+
reservePoolPDA: reservePoolPDA.toBase58(),
|
|
488
|
+
vaultPDA: vaultPDA.toBase58(),
|
|
489
|
+
globalIndex: globalState?.currentIndex?.toString(),
|
|
490
|
+
totalShares: globalState?.totalShares?.toString(),
|
|
491
|
+
currentTrancheNumber:
|
|
492
|
+
trancheState?.currentTrancheNumber?.toString(),
|
|
493
|
+
currentTranchePriceUsd:
|
|
494
|
+
trancheState?.currentTranchePriceUsd?.toString(), // 1e8 USD
|
|
495
|
+
},
|
|
496
|
+
chainID: this.network.chainId,
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
catch (err) {
|
|
500
|
+
throw new Error(`Failed to get Solana portfolio: ${err}`);
|
|
501
|
+
}
|
|
469
502
|
}
|
|
470
503
|
|
|
471
504
|
/**
|
|
@@ -497,29 +530,34 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
497
530
|
windowBefore?: number;
|
|
498
531
|
windowAfter?: number;
|
|
499
532
|
}): Promise<TrancheSnapshot> {
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
533
|
+
try {
|
|
534
|
+
const {
|
|
535
|
+
chainID = SolChainID.WireTestnet,
|
|
536
|
+
windowBefore,
|
|
537
|
+
windowAfter,
|
|
538
|
+
} = options ?? {};
|
|
539
|
+
|
|
540
|
+
const [globalState, trancheState] = await Promise.all([
|
|
541
|
+
this.tokenClient.fetchGlobalState(),
|
|
542
|
+
this.tokenClient.fetchTrancheState(),
|
|
543
|
+
]);
|
|
544
|
+
|
|
545
|
+
const { price: solPriceUsd, timestamp } =
|
|
546
|
+
await this.tokenClient.getSolPriceUsdSafe();
|
|
547
|
+
|
|
548
|
+
return buildSolanaTrancheSnapshot({
|
|
549
|
+
chainID,
|
|
550
|
+
globalState,
|
|
551
|
+
trancheState,
|
|
552
|
+
solPriceUsd,
|
|
553
|
+
nativePriceTimestamp: timestamp,
|
|
554
|
+
ladderWindowBefore: windowBefore,
|
|
555
|
+
ladderWindowAfter: windowAfter,
|
|
556
|
+
});
|
|
557
|
+
}
|
|
558
|
+
catch (err) {
|
|
559
|
+
throw new Error(`Failed to build Solana tranche snapshot: ${err}`);
|
|
560
|
+
}
|
|
523
561
|
}
|
|
524
562
|
|
|
525
563
|
/**
|
|
@@ -528,16 +566,20 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
528
566
|
* cluster-derived epochs-per-year.
|
|
529
567
|
*/
|
|
530
568
|
async getSystemAPY(): Promise<number> {
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
569
|
+
try {
|
|
570
|
+
// 1) Per-epoch rate (decimal) from on-chain stakeMetrics
|
|
571
|
+
const ratePerEpoch = await this.getEpochRateDecimalFromProgram();
|
|
572
|
+
// 2) Live epochs-per-year estimate from cluster
|
|
573
|
+
const epochsPerYear = await this.getEpochsPerYearFromCluster();
|
|
574
|
+
// 3) Compound: (1 + r)^N - 1
|
|
575
|
+
const apyDecimal = Math.pow(1 + ratePerEpoch, epochsPerYear) - 1;
|
|
576
|
+
// 4) Convert to percent
|
|
577
|
+
const apyPercent = apyDecimal * 100;
|
|
578
|
+
|
|
579
|
+
return apyPercent;
|
|
580
|
+
} catch (err) {
|
|
581
|
+
throw new Error(`Failed to compute Solana system APY: ${err}`);
|
|
582
|
+
}
|
|
541
583
|
}
|
|
542
584
|
|
|
543
585
|
/**
|
|
@@ -546,18 +588,24 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
546
588
|
* de-scaled using PAY_RATE_SCALE_FACTOR (1e12).
|
|
547
589
|
*/
|
|
548
590
|
private async getEpochRateDecimalFromProgram(): Promise<number> {
|
|
549
|
-
|
|
550
|
-
const stakeMetricsPda = deriveStakeMetricsPda();
|
|
551
|
-
const stakeMetrics =
|
|
552
|
-
await liqSolCoreProgram.account.stakeMetrics.fetch(stakeMetricsPda);
|
|
591
|
+
try {
|
|
553
592
|
|
|
554
|
-
|
|
555
|
-
|
|
593
|
+
const liqSolCoreProgram = this.program.getProgram('liqsolCore');
|
|
594
|
+
const stakeMetricsPda = deriveStakeMetricsPda();
|
|
595
|
+
const stakeMetrics =
|
|
596
|
+
await liqSolCoreProgram.account.stakeMetrics.fetch(stakeMetricsPda);
|
|
556
597
|
|
|
557
|
-
|
|
558
|
-
|
|
598
|
+
// solSystemPayRate is stored on-chain with PAY_RATE_SCALE_FACTOR (1e12)
|
|
599
|
+
const raw = BigInt(stakeMetrics.solSystemPayRate.toString());
|
|
559
600
|
|
|
560
|
-
|
|
601
|
+
// Convert to JS number in **decimal per epoch** units
|
|
602
|
+
const rateDecimal = Number(raw) / Number(PAY_RATE_SCALE_FACTOR);
|
|
603
|
+
|
|
604
|
+
return rateDecimal;
|
|
605
|
+
}
|
|
606
|
+
catch (err) {
|
|
607
|
+
throw new Error(`Failed to read stakeMetrics from program: ${err}`);
|
|
608
|
+
}
|
|
561
609
|
}
|
|
562
610
|
|
|
563
611
|
// Simple cache so we don’t hammer RPC
|
package/src/staker.ts
CHANGED
|
@@ -36,13 +36,11 @@ export class Staker {
|
|
|
36
36
|
|
|
37
37
|
config.forEach((cfg) => {
|
|
38
38
|
switch (cfg.network.chainId) {
|
|
39
|
-
case SolChainID.
|
|
40
|
-
case SolChainID.WireTestnet:
|
|
39
|
+
case SolChainID.Mainnet:
|
|
41
40
|
this.clients.set(cfg.network.chainId, new SolanaStakingClient(cfg));
|
|
42
41
|
break;
|
|
43
42
|
|
|
44
43
|
case EvmChainID.Ethereum:
|
|
45
|
-
case EvmChainID.Hoodi:
|
|
46
44
|
this.clients.set(cfg.network.chainId, new EthereumStakingClient(cfg));
|
|
47
45
|
break;
|
|
48
46
|
|