@wireio/stake 0.1.0 → 0.1.2

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.
Files changed (104) hide show
  1. package/README.md +57 -0
  2. package/lib/stake.browser.js +11836 -4103
  3. package/lib/stake.browser.js.map +1 -1
  4. package/lib/stake.d.ts +374 -556
  5. package/lib/stake.js +12089 -4303
  6. package/lib/stake.js.map +1 -1
  7. package/lib/stake.m.js +11836 -4103
  8. package/lib/stake.m.js.map +1 -1
  9. package/package.json +1 -1
  10. package/src/assets/ethereum/ABI/liqEth/DepositManager.sol/DepositManager.dbg.json +4 -0
  11. package/src/assets/ethereum/ABI/liqEth/DepositManager.sol/DepositManager.json +1153 -0
  12. package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IAccounting.dbg.json +4 -0
  13. package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IAccounting.json +172 -0
  14. package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IDepositContract.dbg.json +4 -0
  15. package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IDepositContract.json +39 -0
  16. package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IDepositManager.dbg.json +4 -0
  17. package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IDepositManager.json +64 -0
  18. package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/ILiqEthBurn.dbg.json +4 -0
  19. package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/ILiqEthBurn.json +24 -0
  20. package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/ILiqEthMint.dbg.json +4 -0
  21. package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/ILiqEthMint.json +35 -0
  22. package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IRewardsERC20.dbg.json +4 -0
  23. package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IRewardsERC20.json +213 -0
  24. package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IStakingModule.dbg.json +4 -0
  25. package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IStakingModule.json +138 -0
  26. package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IValidatorBalanceVerifier.dbg.json +4 -0
  27. package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IValidatorBalanceVerifier.json +70 -0
  28. package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IWithdrawalRecord.dbg.json +4 -0
  29. package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IWithdrawalRecord.json +64 -0
  30. package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/LiqEthCommon.dbg.json +4 -0
  31. package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/LiqEthCommon.json +10 -0
  32. package/src/assets/ethereum/ABI/liqEth/RewardsERC20.sol/RewardsERC20.dbg.json +4 -0
  33. package/src/assets/ethereum/ABI/liqEth/RewardsERC20.sol/RewardsERC20.json +749 -0
  34. package/src/assets/ethereum/ABI/liqEth/RewardsERC20Pausable.sol/RewardsERC20Pausable.dbg.json +4 -0
  35. package/src/assets/ethereum/ABI/liqEth/RewardsERC20Pausable.sol/RewardsERC20Pausable.json +812 -0
  36. package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/BeaconRoots.dbg.json +4 -0
  37. package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/BeaconRoots.json +10 -0
  38. package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/SSZ.dbg.json +4 -0
  39. package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/SSZ.json +10 -0
  40. package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/ValidatorBalanceVerifier.dbg.json +4 -0
  41. package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/ValidatorBalanceVerifier.json +225 -0
  42. package/src/assets/ethereum/ABI/liqEth/Yield.sol/BeaconRoots.dbg.json +4 -0
  43. package/src/assets/ethereum/ABI/liqEth/Yield.sol/BeaconRoots.json +10 -0
  44. package/src/assets/ethereum/ABI/liqEth/Yield.sol/SSZ.dbg.json +4 -0
  45. package/src/assets/ethereum/ABI/liqEth/Yield.sol/SSZ.json +10 -0
  46. package/src/assets/ethereum/ABI/liqEth/Yield.sol/YieldOracle.dbg.json +4 -0
  47. package/src/assets/ethereum/ABI/liqEth/Yield.sol/YieldOracle.json +813 -0
  48. package/src/assets/ethereum/ABI/liqEth/accounting.sol/Accounting.dbg.json +4 -0
  49. package/src/assets/ethereum/ABI/liqEth/accounting.sol/Accounting.json +651 -0
  50. package/src/assets/ethereum/ABI/liqEth/liqEth.sol/LiqEthToken.dbg.json +4 -0
  51. package/src/assets/ethereum/ABI/liqEth/liqEth.sol/LiqEthToken.json +1110 -0
  52. package/src/assets/ethereum/ABI/liqEth/liqEthBurn.sol/LiqEthBurn.dbg.json +4 -0
  53. package/src/assets/ethereum/ABI/liqEth/liqEthBurn.sol/LiqEthBurn.json +391 -0
  54. package/src/assets/ethereum/ABI/liqEth/liqEthMint.sol/LiqEthMint.dbg.json +4 -0
  55. package/src/assets/ethereum/ABI/liqEth/liqEthMint.sol/LiqEthMint.json +402 -0
  56. package/src/assets/ethereum/ABI/liqEth/stakingModule.sol/StakingModule.dbg.json +4 -0
  57. package/src/assets/ethereum/ABI/liqEth/stakingModule.sol/StakingModule.json +1225 -0
  58. package/src/assets/ethereum/ABI/liqEth/withdrawalQueue.sol/WithdrawalQueue.dbg.json +4 -0
  59. package/src/assets/ethereum/ABI/liqEth/withdrawalQueue.sol/WithdrawalQueue.json +927 -0
  60. package/src/assets/ethereum/ABI/liqEth/withdrawalVault.sol/Uint64BE.dbg.json +4 -0
  61. package/src/assets/ethereum/ABI/liqEth/withdrawalVault.sol/Uint64BE.json +10 -0
  62. package/src/assets/ethereum/ABI/liqEth/withdrawalVault.sol/WithdrawalVault.dbg.json +4 -0
  63. package/src/assets/ethereum/ABI/liqEth/withdrawalVault.sol/WithdrawalVault.json +447 -0
  64. package/src/assets/solana/idl/liqsol_core.json +4239 -0
  65. package/src/assets/solana/idl/liqsol_token.json +183 -0
  66. package/src/assets/solana/idl/validator_leaderboard.json +270 -265
  67. package/src/assets/solana/types/liqsol_core.ts +4245 -0
  68. package/src/assets/solana/types/liqsol_token.ts +189 -0
  69. package/src/assets/solana/types/validator_leaderboard.ts +270 -265
  70. package/src/index.ts +1 -3
  71. package/src/networks/ethereum/contract.ts +101 -36
  72. package/src/networks/ethereum/ethereum.ts +141 -45
  73. package/src/networks/ethereum/types.ts +30 -2
  74. package/src/networks/solana/clients/deposit.client.ts +71 -109
  75. package/src/networks/solana/clients/distribution.client.ts +256 -383
  76. package/src/networks/solana/clients/leaderboard.client.ts +38 -133
  77. package/src/networks/solana/constants.ts +214 -130
  78. package/src/networks/solana/program.ts +25 -38
  79. package/src/networks/solana/solana.ts +120 -105
  80. package/src/networks/solana/types.ts +37 -47
  81. package/src/networks/solana/utils.ts +551 -0
  82. package/src/scripts/tsconfig.json +17 -0
  83. package/src/staker/staker.ts +10 -6
  84. package/src/staker/types.ts +14 -9
  85. package/src/assets/solana/idl/deposit.json +0 -296
  86. package/src/assets/solana/idl/distribution.json +0 -768
  87. package/src/assets/solana/idl/liq_sol_token.json +0 -298
  88. package/src/assets/solana/idl/mint_helper.json +0 -110
  89. package/src/assets/solana/idl/read_tracked_balance.json +0 -140
  90. package/src/assets/solana/idl/stake_controller.json +0 -2149
  91. package/src/assets/solana/idl/treasury.json +0 -110
  92. package/src/assets/solana/idl/validator_registry.json +0 -487
  93. package/src/assets/solana/idl/yield_oracle.json +0 -32
  94. package/src/assets/solana/types/deposit.ts +0 -302
  95. package/src/assets/solana/types/distribution.ts +0 -774
  96. package/src/assets/solana/types/liq_sol_token.ts +0 -304
  97. package/src/assets/solana/types/mint_helper.ts +0 -116
  98. package/src/assets/solana/types/read_tracked_balance.ts +0 -146
  99. package/src/assets/solana/types/stake_controller.ts +0 -2155
  100. package/src/assets/solana/types/stake_registry.ts +0 -441
  101. package/src/assets/solana/types/treasury.ts +0 -116
  102. package/src/assets/solana/types/validator_registry.ts +0 -493
  103. package/src/assets/solana/types/yield_oracle.ts +0 -38
  104. package/src/common/utils.ts +0 -9
package/lib/stake.d.ts CHANGED
@@ -1,18 +1,12 @@
1
+ import * as _wireio_core from '@wireio/core';
1
2
  import { PublicKey, ExternalNetwork, ChainID } from '@wireio/core';
2
3
  import { BaseSignerWalletAdapter } from '@solana/wallet-adapter-base';
3
- import { PublicKey as PublicKey$1, Transaction, VersionedTransaction, Connection, TransactionSignature, Signer as Signer$1, TransactionInstruction } from '@solana/web3.js';
4
- import { ethers, Signer, Contract } from 'ethers';
4
+ import * as _solana_web3_js from '@solana/web3.js';
5
+ import { PublicKey as PublicKey$1, Transaction, VersionedTransaction, TokenAmount, Connection, TransactionSignature, Keypair } from '@solana/web3.js';
6
+ import { ethers, BigNumberish, BigNumber, Signer, Contract } from 'ethers';
5
7
  import { JsonFragment } from '@ethersproject/abi';
6
8
  import { ErrorDescription } from '@ethersproject/abi/lib/interface';
7
- import { AnchorProvider, Program } from '@coral-xyz/anchor';
8
- export { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_2022_PROGRAM_ID } from '@solana/spl-token';
9
-
10
- /**
11
- * Static utility functions for working with Wire Network Staking Protocol.
12
- *
13
- * @module utils
14
- */
15
- declare const hi: (name: string) => string;
9
+ import { AnchorProvider, Program, BN } from '@coral-xyz/anchor';
16
10
 
17
11
  interface IStakingClient {
18
12
  pubKey: PublicKey;
@@ -20,7 +14,6 @@ interface IStakingClient {
20
14
  /** Amount is in the chain's smallest unit (lamports/wei, etc.) */
21
15
  deposit(amount: number): Promise<string>;
22
16
  /** Register any untracked LIQ staked tokens */
23
- register(): Promise<string>;
24
17
  /** Fetch the portfolio for the LIQ stake user */
25
18
  getPortfolio(): Promise<Portfolio>;
26
19
  }
@@ -30,17 +23,22 @@ type StakerConfig = {
30
23
  pubKey: PublicKey;
31
24
  };
32
25
  interface Portfolio {
33
- /** Native SOL balance on chain */
26
+ /** Native balance on chain: ETH, SOL */
34
27
  native: BalanceView;
35
- /** Actual liquid SOL balance from ATA */
36
- actual: BalanceView;
37
- /** Tracked liquid SOL balance from distribution program */
38
- tracked: BalanceView;
28
+ /** Actual Liquid balance of LiqETH, LiqSOL*/
29
+ liq: BalanceView;
30
+ /** Outpost Staked balance */
31
+ staked: BalanceView;
32
+ /** SOL ONLY!
33
+ * Tracked liqSOL balance from distribution program */
34
+ tracked?: BalanceView;
39
35
  /** Extra PDAs and account addresses */
40
36
  extras?: Record<string, any>;
37
+ /** Chain ID of the network for which this portfolio is from */
38
+ chainID: ChainID;
41
39
  }
42
40
  type BalanceView = {
43
- amount: bigint;
41
+ amount: BigNumberish;
44
42
  decimals: number;
45
43
  symbol?: string;
46
44
  ata?: PublicKey$1;
@@ -66,55 +64,77 @@ declare class Staker {
66
64
  setChain(chainID: ChainID): boolean;
67
65
  }
68
66
 
69
- declare class EthereumStakingClient {
67
+ declare class EthereumStakingClient implements IStakingClient {
70
68
  private config;
71
69
  readonly pubKey: PublicKey;
72
70
  private readonly provider;
73
71
  private readonly signer;
74
- private readonly contract;
72
+ private readonly contractService;
73
+ get contract(): {
74
+ Accounting: ethers.Contract;
75
+ DepositManager: ethers.Contract;
76
+ LiqEth: ethers.Contract;
77
+ LiqEthBurn: ethers.Contract;
78
+ LiqEthMint: ethers.Contract;
79
+ StakingModule: ethers.Contract;
80
+ WithdrawalQueue: ethers.Contract;
81
+ WithdrawalVault: ethers.Contract;
82
+ };
83
+ get network(): _wireio_core.ExternalNetwork;
75
84
  constructor(config: StakerConfig);
76
- /** Submit a deposit; returns the transaction hash */
77
- deposit(amount: number): Promise<string>;
78
- /** (Optional) dry-run via eth_call */
79
- simulateDeposit(amount: number): Promise<any>;
85
+ /**
86
+ * Deposit native ETH into the liqETH protocol via DepositManager.
87
+ * @param amount Amount in wei (or something convertible to BigNumber).
88
+ * Keep this as a bigint / string in the caller; avoid JS floats.
89
+ * @returns transaction hash
90
+ */
91
+ deposit(amount: number | string | bigint | BigNumber): Promise<string>;
92
+ /**
93
+ * Simulate a deposit via callStatic.
94
+ *
95
+ * Useful for pre-flight checks; will throw with the same revert
96
+ * reason as a real tx if it would fail.
97
+ */
98
+ simulateDeposit(amount: number | string | bigint | BigNumber): Promise<void>;
99
+ private performDeposit;
100
+ /**
101
+ * Resolve the user's ETH + liqETH balances.
102
+ *
103
+ * native = ETH in wallet
104
+ * actual = liqETH token balance (ERC-20)
105
+ * tracked = liqETH tracked balance (protocol/accounting view)
106
+ */
107
+ getPortfolio(): Promise<Portfolio>;
80
108
  }
81
109
 
82
- declare const CONTRACT_NAMES: readonly ["Stake"];
110
+ declare const CONTRACT_NAMES: readonly ["Accounting", "DepositManager", "LiqEth", "LiqEthBurn", "LiqEthMint", "StakingModule", "WithdrawalQueue", "WithdrawalVault"];
83
111
  type ContractName = typeof CONTRACT_NAMES[number];
84
112
  type AddressBook = Record<ContractName, string>;
113
+ interface DepositEvent {
114
+ user: string;
115
+ netEth: BigNumber;
116
+ fee: BigNumber;
117
+ shares: BigNumber;
118
+ }
119
+ interface DepositResult {
120
+ /** EVM transaction hash */
121
+ txHash: string;
122
+ /** Full receipt, if you want it */
123
+ receipt: ethers.providers.TransactionReceipt;
124
+ /** Parsed Deposited event, if present */
125
+ deposited?: DepositEvent;
126
+ }
85
127
 
86
128
  type types$1_AddressBook = AddressBook;
87
129
  declare const types$1_CONTRACT_NAMES: typeof CONTRACT_NAMES;
88
130
  type types$1_ContractName = ContractName;
131
+ type types$1_DepositEvent = DepositEvent;
132
+ type types$1_DepositResult = DepositResult;
89
133
  declare namespace types$1 {
90
134
  export { types$1_CONTRACT_NAMES as CONTRACT_NAMES };
91
- export type { types$1_AddressBook as AddressBook, types$1_ContractName as ContractName };
135
+ export type { types$1_AddressBook as AddressBook, types$1_ContractName as ContractName, types$1_DepositEvent as DepositEvent, types$1_DepositResult as DepositResult };
92
136
  }
93
137
 
94
- /**
95
- * @module EthereumContractService
96
- *
97
- * Provides a unified service for interacting with Ethereum smart contracts using ethers.js.
98
- *
99
- * This module includes:
100
- * - ABI imports for ERC20, ERC721, and ERC1155 token standards.
101
- * - Address book and contract configuration types.
102
- * - A service class for managing contract instances, interfaces, and utility methods for read/write access.
103
- * - Utility for decoding custom errors and events using a combined interface of all known ABIs.
104
- *
105
- * @remarks
106
- * - Update the `ADDRESSES` and `CONTRACTS` objects to match your deployment.
107
- * - The service supports both read-only and write-enabled contract handles, depending on the presence of a signer.
108
- * - The `omniInterface` property allows decoding of errors and events across all included ABIs.
109
- *
110
- * @example
111
- * ```typescript
112
- * const service = new EthereumContractService({ provider, signer });
113
- * const stakeContract = service.getContract('Stake');
114
- * const address = service.getAddress('Stake');
115
- * ```
116
- */
117
-
118
138
  declare const ERC20Abi: ({
119
139
  inputs: {
120
140
  internalType: string;
@@ -298,69 +318,64 @@ declare class EthereumContractService {
298
318
  getInterface(name: ContractName): ethers.utils.Interface;
299
319
  /** Get live Contract instance */
300
320
  getContract(name: ContractName): ethers.Contract;
301
- /** A unified Interface containing all ABIs (addresses + extra decoding-only)
302
- * to parse custom errors or events. */
321
+ /** A unified Interface containing all ABIs to parse custom errors or events. */
303
322
  get omniInterface(): ethers.utils.Interface;
304
323
  /** Decode a revert or custom error payload */
305
324
  parseError(revertData: string): ErrorDescription;
306
325
  }
307
326
 
308
327
  type SolanaTransaction = Transaction | VersionedTransaction;
309
- /** Raw mismatch row (per user with a userRecord) */
310
- type MismatchCandidate = {
311
- /** Wallet that owns the ATA (decoded from token account) */
312
- owner: PublicKey$1;
313
- /** user_record PDA */
314
- userRecordPda: PublicKey$1;
315
- /** user’s ATA for liqSOL */
328
+ type UserRecord = {
316
329
  userAta: PublicKey$1;
317
- /** protocol tracked balance (u64) */
318
- tracked: bigint;
319
- /** actual on-chain token balance (u64) */
330
+ trackedBalance: bigint;
331
+ claimBalance: bigint;
332
+ lastClaimTimestamp: bigint;
333
+ bump: number;
334
+ };
335
+ type DistributionState = {
336
+ liqsolMint: PublicKey$1;
337
+ availableBalance: bigint;
338
+ totalTrackedBalance: bigint;
339
+ bump: number;
340
+ };
341
+ type ParsedAccountInfo = {
342
+ extensions: Array<{
343
+ extension: string;
344
+ }>;
345
+ isNative: boolean;
346
+ mint: string;
347
+ owner: string;
348
+ state: string;
349
+ tokenAmount: TokenAmount;
350
+ };
351
+ interface MismatchCandidate {
352
+ owner: PublicKey$1;
320
353
  actual: bigint;
321
- /** tracked - actual (positive means “freeable”) */
354
+ tracked: bigint;
322
355
  delta: bigint;
323
- };
324
- /** Output when choosing candidates to free liquidity */
325
- type CorrectionPlan = {
326
- /** selected candidates sorted by delta desc */
327
- selected: MismatchCandidate[];
328
- /** total delta we’ll free by correcting selected */
329
- willFree: bigint;
330
- /** how much still missing after selection (0 if we can meet the target) */
356
+ }
357
+ interface CorrectRegisterPlan {
331
358
  deficit: bigint;
332
- };
333
- /** What the builder returns to your caller/UI */
334
- type CorrectAndRegisterBuild = {
335
- /** The ready-to-send transaction (if buildable) */
336
- transaction?: Transaction;
337
- /** True if the tx can succeed with current state */
359
+ willFree: bigint;
360
+ selected: MismatchCandidate[];
361
+ }
362
+ interface CorrectRegisterBuildResult {
363
+ needToRegister: boolean;
338
364
  canSucceed: boolean;
339
- /** Explanation if not buildable */
340
365
  reason?: string;
341
- /** Current liqSOL mint; useful for UI */
342
- liqsolMint: PublicKey$1;
343
- /** Amount you need to register (actual - tracked if positive) */
344
- needToRegister: bigint;
345
- /** Distribution “availableBalance” before this action */
346
- availableBefore: bigint;
347
- /** Candidates we scanned (already sorted by delta desc) */
348
- candidates: MismatchCandidate[];
349
- /** Subset we’d correct (maybe empty) */
350
- plan: CorrectionPlan;
351
- /** Convenience for caller */
352
- accounts: {
353
- selfUserRecordPda: PublicKey$1;
354
- selfUserAta: PublicKey$1;
355
- };
356
- };
366
+ transaction?: Transaction;
367
+ plan: CorrectRegisterPlan;
368
+ }
357
369
 
358
- type types_CorrectAndRegisterBuild = CorrectAndRegisterBuild;
359
- type types_CorrectionPlan = CorrectionPlan;
370
+ type types_CorrectRegisterBuildResult = CorrectRegisterBuildResult;
371
+ type types_CorrectRegisterPlan = CorrectRegisterPlan;
372
+ type types_DistributionState = DistributionState;
360
373
  type types_MismatchCandidate = MismatchCandidate;
374
+ type types_ParsedAccountInfo = ParsedAccountInfo;
361
375
  type types_SolanaTransaction = SolanaTransaction;
376
+ type types_UserRecord = UserRecord;
362
377
  declare namespace types {
363
- export type { types_CorrectAndRegisterBuild as CorrectAndRegisterBuild, types_CorrectionPlan as CorrectionPlan, types_MismatchCandidate as MismatchCandidate, types_SolanaTransaction as SolanaTransaction };
378
+ export type { types_CorrectRegisterBuildResult as CorrectRegisterBuildResult, types_CorrectRegisterPlan as CorrectRegisterPlan, types_DistributionState as DistributionState, types_MismatchCandidate as MismatchCandidate, types_ParsedAccountInfo as ParsedAccountInfo, types_SolanaTransaction as SolanaTransaction, types_UserRecord as UserRecord };
364
379
  }
365
380
 
366
381
  declare class SolanaStakingClient implements IStakingClient {
@@ -370,6 +385,7 @@ declare class SolanaStakingClient implements IStakingClient {
370
385
  anchor: AnchorProvider;
371
386
  private depositClient;
372
387
  private distributionClient;
388
+ private leaderboardClient;
373
389
  get solPubKey(): PublicKey$1;
374
390
  get network(): ExternalNetwork;
375
391
  constructor(config: StakerConfig);
@@ -383,9 +399,16 @@ declare class SolanaStakingClient implements IStakingClient {
383
399
  /**
384
400
  * Optional: fetch your Distribution program user record
385
401
  * (often contains per-user deposit/claim state).
402
+ * @returns UserRecord or null
386
403
  */
387
- getUserRecord(): Promise<any | null>;
404
+ getUserRecord(): Promise<UserRecord | null>;
388
405
  getProtocolFee(): void;
406
+ /**
407
+ * Deposit funds into the staking pool.
408
+ * @param lamports The amount to deposit (in lamports).
409
+ * @returns The transaction signature.
410
+ */
411
+ deposit(lamports: number): Promise<string>;
389
412
  /**
390
413
  * Build, sign, and submit a single transaction that:
391
414
  * - Corrects other users (if needed) to free available balance, then
@@ -394,13 +417,7 @@ declare class SolanaStakingClient implements IStakingClient {
394
417
  * @param amount Optional: register a smaller amount than your full untracked balance.
395
418
  * @returns signature string
396
419
  */
397
- register(amount?: bigint): Promise<string>;
398
- /**
399
- * Deposit funds into the staking pool.
400
- * @param lamports The amount to deposit (in lamports).
401
- * @returns The transaction signature.
402
- */
403
- deposit(lamports: number): Promise<string>;
420
+ correctBalance(amount?: bigint): Promise<string>;
404
421
  private sendAndConfirmHttp;
405
422
  signTransaction(tx: SolanaTransaction): Promise<SolanaTransaction>;
406
423
  sendTransaction(signed: SolanaTransaction): Promise<TransactionSignature>;
@@ -417,496 +434,297 @@ interface TxResult {
417
434
  }
418
435
 
419
436
  /**
420
- * Program IDL in camelCase format in order to be used in JS/TS.
437
+ * ---------------------------------------------------------------------------
438
+ * PROGRAM IDS
439
+ * ---------------------------------------------------------------------------
421
440
  *
422
- * Note that this is only a type helper and is not the actual IDL. The original
423
- * IDL can be found at `target/idl/deposit.json`.
441
+ * These should match:
442
+ * - `metadata.address` in your Anchor IDLs under src/assets/solana/idl/*.json
443
+ * - The program IDs printed by your deploy scripts
424
444
  */
425
- type Deposit = {
426
- "address": "GqksbjX3r7SHZ5e8c6nFyPecZNnBSUTYHbF8U2YDb5Qf";
427
- "metadata": {
428
- "name": "deposit";
429
- "version": "0.1.0";
430
- "spec": "0.1.0";
431
- "description": "Created with Anchor";
432
- };
433
- "instructions": [
434
- {
435
- "name": "deposit";
436
- "discriminator": [
437
- 242,
438
- 35,
439
- 198,
440
- 137,
441
- 82,
442
- 225,
443
- 242,
444
- 182
445
- ];
446
- "accounts": [
447
- {
448
- "name": "user";
449
- "writable": true;
450
- "signer": true;
451
- },
452
- {
453
- "name": "programAuthority";
454
- "writable": true;
455
- "pda": {
456
- "seeds": [
457
- {
458
- "kind": "const";
459
- "value": [
460
- 112,
461
- 114,
462
- 111,
463
- 103,
464
- 114,
465
- 97,
466
- 109,
467
- 95,
468
- 97,
469
- 117,
470
- 116,
471
- 104,
472
- 111,
473
- 114,
474
- 105,
475
- 116,
476
- 121
477
- ];
478
- }
479
- ];
480
- };
481
- },
482
- {
483
- "name": "systemProgram";
484
- "address": "11111111111111111111111111111111";
485
- },
486
- {
487
- "name": "tokenProgram";
488
- },
489
- {
490
- "name": "associatedTokenProgram";
491
- "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL";
492
- },
493
- {
494
- "name": "stakeControllerProgram";
495
- "address": "4Ab1SwV6RPUN5Btnf95qvQCyNVR3iHnXjnMYaKsgimTp";
496
- },
497
- {
498
- "name": "liqsolProgram";
499
- },
500
- {
501
- "name": "payRateHistory";
502
- },
503
- {
504
- "name": "stakeProgram";
505
- "address": "Stake11111111111111111111111111111111111111";
506
- },
507
- {
508
- "name": "distributionProgram";
509
- "address": "26LF4typrWwBapujpvUPFpdfs4pBb6RwcWoBBy7Awf5j";
510
- },
511
- {
512
- "name": "liqsolMint";
513
- "writable": true;
514
- },
515
- {
516
- "name": "userAta";
517
- "writable": true;
518
- "pda": {
519
- "seeds": [
520
- {
521
- "kind": "account";
522
- "path": "user";
523
- },
524
- {
525
- "kind": "account";
526
- "path": "tokenProgram";
527
- },
528
- {
529
- "kind": "account";
530
- "path": "liqsolMint";
531
- }
532
- ];
533
- "program": {
534
- "kind": "const";
535
- "value": [
536
- 140,
537
- 151,
538
- 37,
539
- 143,
540
- 78,
541
- 36,
542
- 137,
543
- 241,
544
- 187,
545
- 61,
546
- 16,
547
- 41,
548
- 20,
549
- 142,
550
- 13,
551
- 131,
552
- 11,
553
- 90,
554
- 19,
555
- 153,
556
- 218,
557
- 255,
558
- 16,
559
- 132,
560
- 4,
561
- 142,
562
- 123,
563
- 216,
564
- 219,
565
- 233,
566
- 248,
567
- 89
568
- ];
569
- };
570
- };
571
- },
572
- {
573
- "name": "liqsolMintAuthority";
574
- },
575
- {
576
- "name": "reservePool";
577
- "writable": true;
578
- },
579
- {
580
- "name": "vault";
581
- "writable": true;
582
- },
583
- {
584
- "name": "ephemeralStake";
585
- "writable": true;
586
- },
587
- {
588
- "name": "controllerState";
589
- "writable": true;
590
- },
591
- {
592
- "name": "globalStakeInfo";
593
- "writable": true;
594
- },
595
- {
596
- "name": "bucketAuthority";
597
- "pda": {
598
- "seeds": [
599
- {
600
- "kind": "const";
601
- "value": [
602
- 108,
603
- 105,
604
- 113,
605
- 115,
606
- 111,
607
- 108,
608
- 95,
609
- 98,
610
- 117,
611
- 99,
612
- 107,
613
- 101,
614
- 116
615
- ];
616
- }
617
- ];
618
- "program": {
619
- "kind": "account";
620
- "path": "stakeControllerProgram";
621
- };
622
- };
623
- },
624
- {
625
- "name": "bucketTokenAccount";
626
- "docs": [
627
- "The bucket's associated token account"
628
- ];
629
- "writable": true;
630
- },
631
- {
632
- "name": "userRecord";
633
- "writable": true;
634
- },
635
- {
636
- "name": "distributionState";
637
- "writable": true;
638
- },
639
- {
640
- "name": "instructionsSysvar";
641
- "address": "Sysvar1nstructions1111111111111111111111111";
642
- },
643
- {
644
- "name": "clock";
645
- "address": "SysvarC1ock11111111111111111111111111111111";
646
- },
647
- {
648
- "name": "stakeHistory";
649
- "address": "SysvarStakeHistory1111111111111111111111111";
650
- },
651
- {
652
- "name": "rent";
653
- "address": "SysvarRent111111111111111111111111111111111";
654
- }
655
- ];
656
- "args": [
657
- {
658
- "name": "amount";
659
- "type": "u64";
660
- },
661
- {
662
- "name": "seed";
663
- "type": "u32";
664
- }
665
- ];
666
- }
667
- ];
668
- "errors": [
669
- {
670
- "code": 6000;
671
- "name": "depositTooSmall";
672
- "msg": "Deposit amount is below minimum required";
673
- },
674
- {
675
- "code": 6001;
676
- "name": "notInitialized";
677
- "msg": "Deposit Router not initialized";
678
- },
679
- {
680
- "code": 6002;
681
- "name": "invalidAuthority";
682
- "msg": "Invalid authority";
683
- },
684
- {
685
- "code": 6003;
686
- "name": "insufficientFunds";
687
- "msg": "Insufficient funds";
688
- },
689
- {
690
- "code": 6004;
691
- "name": "overflow";
692
- "msg": "Arithmetic overflow";
693
- },
694
- {
695
- "code": 6005;
696
- "name": "calculationFailure";
697
- "msg": "Calculation failure";
698
- },
699
- {
700
- "code": 6006;
701
- "name": "nothingToMint";
702
- "msg": "Cannot mint zero tokens";
703
- },
704
- {
705
- "code": 6007;
706
- "name": "invalidAccount";
707
- "msg": "Invalid account provided";
708
- },
709
- {
710
- "code": 6008;
711
- "name": "insufficientFundsForStake";
712
- "msg": "Insufficient funds remaining after reserving fees to proceed with staking";
713
- },
714
- {
715
- "code": 6009;
716
- "name": "unauthorizedProgram";
717
- "msg": "Unauthorized program attempting to call this instruction";
718
- }
719
- ];
445
+ declare const PROGRAM_IDS: {
446
+ readonly LIQSOL_CORE: PublicKey$1;
447
+ readonly LIQSOL_TOKEN: PublicKey$1;
448
+ readonly VALIDATOR_LEADERBOARD: PublicKey$1;
720
449
  };
450
+ declare const LIQSOL_CORE: PublicKey$1;
451
+ declare const LIQSOL_TOKEN: PublicKey$1;
452
+ declare const VALIDATOR_LEADERBOARD: PublicKey$1;
453
+ /**
454
+ * ---------------------------------------------------------------------------
455
+ * PDA SEEDS (must match on-chain programs)
456
+ * ---------------------------------------------------------------------------
457
+ *
458
+ * These strings are baked into the on-chain programs and are already used in
459
+ * your test utils. We centralize them here so all clients share them.
460
+ */
461
+ declare const PDA_SEEDS: {
462
+ readonly DEPOSIT_AUTHORITY: "deposit_authority";
463
+ readonly VAULT: "vault";
464
+ readonly RESERVE_POOL: "reserve_pool";
465
+ readonly STAKE_CONTROLLER_STATE: "stake_controller";
466
+ readonly PAYOUT_STATE: "payout-state";
467
+ readonly LIQSOL_MINT: "liqsol_mint";
468
+ readonly LIQSOL_MINT_AUTHORITY: "mint_authority";
469
+ readonly BUCKET_AUTHORITY: "liqsol_bucket";
470
+ readonly DISTRIBUTION_STATE: "distribution_state";
471
+ readonly USER_RECORD: "user_record";
472
+ readonly PAY_RATE_HISTORY: "pay_rate_history";
473
+ readonly LEADERBOARD_STATE: "leaderboard_state";
474
+ readonly VALIDATOR_RECORD: "validator";
475
+ readonly GLOBAL_STAKE_INFO: "global_stake_info";
476
+ };
477
+ /**
478
+ * Helpers for PDA derivation so clients don’t duplicate logic.
479
+ */
480
+ declare const deriveLiqsolMintPda: () => PublicKey$1;
481
+ declare const deriveLiqsolMintAuthorityPda: () => PublicKey$1;
482
+ declare const deriveDepositAuthorityPda: () => PublicKey$1;
483
+ declare const deriveVaultPda: () => PublicKey$1;
484
+ declare const deriveReservePoolPda: () => PublicKey$1;
485
+ declare const deriveStakeControllerStatePda: () => PublicKey$1;
486
+ declare const derivePayoutStatePda: () => PublicKey$1;
487
+ declare const deriveBucketAuthorityPda: () => PublicKey$1;
488
+ declare const deriveDistributionStatePda: () => PublicKey$1;
489
+ declare const deriveUserRecordPda: (user: PublicKey$1) => PublicKey$1;
490
+ declare const derivePayRateHistoryPda: () => PublicKey$1;
491
+ declare const deriveLeaderboardStatePda: () => PublicKey$1;
492
+ declare const deriveValidatorRecordPda: (voteAccount: PublicKey$1) => PublicKey$1;
493
+ /**
494
+ * Stake controller vault PDA (reserve pool SOL vault).
495
+ * This is the same as VAULT, but named more explicitly for SDK callers.
496
+ */
497
+ declare const deriveStakeControllerVaultPda: () => PublicKey$1;
498
+ /**
499
+ * Ephemeral stake account address used per-deposit.
500
+ * On-chain convention: seed = `ephemeral_<u32>` under StakeProgram.programId.
501
+ */
502
+ declare const deriveEphemeralStakeAddress: (user: PublicKey$1, seed: any) => Promise<PublicKey$1>;
503
+ /**
504
+ * ---------------------------------------------------------------------------
505
+ * ECONOMICS & MATH CONSTANTS
506
+ * ---------------------------------------------------------------------------
507
+ */
508
+ declare const PAY_RATE_SCALE_FACTOR: bigint;
509
+ declare const DEFAULT_AVERAGE_PAY_RATE: bigint;
510
+ declare const DEFAULT_PAY_RATE_LOOKBACK = 5;
511
+ declare const EPHEMERAL_RENT_EXEMPTION = 2282880;
512
+ declare const LAMPORTS_PER_SOL = 1000000000;
513
+ declare const lamportsToSol: (lamports: number | bigint) => number;
514
+ declare const solToLamports: (sol: number) => number;
515
+ /**
516
+ * ---------------------------------------------------------------------------
517
+ * CLUSTER / ENVIRONMENT CONFIG (optional but handy)
518
+ * ---------------------------------------------------------------------------
519
+ */
520
+ type SolanaCluster = 'localnet' | 'devnet' | 'mainnet';
721
521
 
722
- declare const DEPOSIT_PROGRAM_ID: PublicKey$1;
723
- declare const STAKE_CONTROLLER_PROGRAM_ID: PublicKey$1;
724
- declare const VALIDATOR_LEADERBOARD_PROGRAM_ID: PublicKey$1;
725
- declare const LIQSOL_TOKEN_PROGRAM_ID: PublicKey$1;
726
- declare const DISTRIBUTION_PROGRAM_ID: PublicKey$1;
727
- declare const YIELD_ORACLE_PROGRAM_ID: PublicKey$1;
728
- declare const MIN_SOL_TO_PARTICIPATE = 1000000000;
729
- declare const LIQSOL_MINT_ADDRESS: PublicKey$1;
730
-
731
- /** Create Anchor Program client for the Deposit program (with correct address) */
732
- declare const getDepositProgram: (provider: AnchorProvider) => Program<Deposit>;
733
- declare const deriveDepositAuthorityPDA: () => [PublicKey$1, number];
734
- declare const deriveLiqsolMintPDA: () => [PublicKey$1, number];
735
- /** ✅ FIXED: this must be derived with the LiqSOL token **program id**, not the mint address */
736
- declare const deriveLiqsolMintAuthorityPDA: () => [PublicKey$1, number];
737
- declare const deriveStakeControllerVaultPDA: () => [PublicKey$1, number];
738
- declare const deriveStakeControllerReservePoolPDA: () => [PublicKey$1, number];
739
- declare const deriveStakeControllerStatePDA: () => [PublicKey$1, number];
740
- declare const deriveGlobalStakeInfoPDA: () => [PublicKey$1, number];
741
- declare const deriveBucketAuthorityPDA: () => [PublicKey$1, number];
742
- declare const derivePayRateHistoryPDA: () => [PublicKey$1, number];
743
- declare const deriveDistributionStatePDA: () => [PublicKey$1, number];
744
- declare const deriveUserRecordPDA: (user: PublicKey$1) => [PublicKey$1, number];
745
- declare const deriveLeaderboardHeadPDA: () => [PublicKey$1, number];
746
- declare const deriveValidatorRecordPDA: (voteAccount: PublicKey$1) => [PublicKey$1, number];
747
- declare const deriveTop10CachePDA: () => [PublicKey$1, number];
748
- declare const deriveStakeControllerAuthorityPDA: () => [PublicKey$1, number];
749
- /** User’s liqSOL ATA (Token-2022) */
750
- declare const getUserLiqsolATA: (user: PublicKey$1) => PublicKey$1;
751
-
522
+ declare function getLiqsolCoreProgram(connection: Connection): Program;
523
+ interface DepositAccounts {
524
+ user: PublicKey$1;
525
+ depositAuthority: PublicKey$1;
526
+ liqsolMint: PublicKey$1;
527
+ liqsolMintAuthority: PublicKey$1;
528
+ userAta: PublicKey$1;
529
+ stakeControllerVault: PublicKey$1;
530
+ stakeControllerReservePool: PublicKey$1;
531
+ stakeControllerState: PublicKey$1;
532
+ payoutState: PublicKey$1;
533
+ bucketAuthority: PublicKey$1;
534
+ bucketTokenAccount: PublicKey$1;
535
+ distributionState: PublicKey$1;
536
+ userRecord: PublicKey$1;
537
+ payRateHistory: PublicKey$1;
538
+ ephemeralStake: PublicKey$1;
539
+ ephemeralSeed: string;
540
+ }
541
+ /**
542
+ * Build a complete DepositAccounts set for a given user, matching the
543
+ * on-chain PDAs used by the liqSOL core program.
544
+ *
545
+ * The optional `seed` lets you make deposit flows replayable/deterministic.
546
+ * If omitted, a random u32 seed is generated.
547
+ */
548
+ declare function buildDepositAccounts(connection: Connection, user: PublicKey$1): Promise<DepositAccounts>;
549
+ declare function getUserLiqSolBalance(connection: Connection, user: PublicKey$1): Promise<number>;
550
+ declare function getBucketLiqSolBalance(connection: Connection): Promise<number>;
551
+ declare function getReservePoolBalance(connection: Connection): Promise<number>;
552
+ /**
553
+ * Raw account info for the stake_controller state (Anchor decode is left
554
+ * to the caller so the SDK can stay IDL-agnostic at this layer).
555
+ */
556
+ declare function getStakeControllerStateRaw(connection: Connection): Promise<Uint8Array | null>;
557
+ /**
558
+ * Raw account info for the payout-state account.
559
+ */
560
+ declare function getPayoutStateRaw(connection: Connection): Promise<Uint8Array | null>;
561
+ /**
562
+ * Raw account info for a user's distribution user_record.
563
+ */
564
+ declare function getUserRecordRaw(connection: Connection, user: PublicKey$1): Promise<Uint8Array | null>;
565
+ declare function getAveragePayRate(connection: Connection, lookback?: number): Promise<bigint>;
752
566
  /**
753
- * DepositClient: builds, simulates, and sends deposit txns matching the latest IDL.
567
+ * On-chain fee formula:
568
+ * fee = (average_pay_rate * 4 * deposit_amount_lamports) / 10^12
569
+ */
570
+ declare function calculateExpectedFee(depositAmountLamports: BN, averagePayRate: BN): BN;
571
+ /**
572
+ * Convenience helper to preview how a deposit splits between user + bucket
573
+ * and how much goes into the reserve, assuming the simple model:
754
574
  *
575
+ * - userLiqSol = amount - fee + EPHEMERAL_RENT_EXEMPTION
576
+ * - bucketLiqSol = fee
577
+ * - reserveLamports = amount + EPHEMERAL_RENT_EXEMPTION
755
578
  */
579
+ declare function previewDepositEffects(params: {
580
+ depositAmountLamports: BN;
581
+ averagePayRate: BN;
582
+ rentExemptionLamports?: number;
583
+ }): {
584
+ feeLamports: BN;
585
+ userLiqSolLamports: BN;
586
+ bucketLiqSolLamports: BN;
587
+ reserveIncreaseLamports: BN;
588
+ };
589
+ type EpochSnapshot = {
590
+ epoch: number;
591
+ slot: number;
592
+ firstSlot: number;
593
+ slotsInEpoch: number;
594
+ slotMs: number;
595
+ };
596
+ declare function getEpochSnapshot(connection: Connection): Promise<EpochSnapshot>;
597
+ declare function msToEpochEnd(snapshot: EpochSnapshot): number;
598
+ /**
599
+ * Generic "execute around epoch boundaries" helper:
600
+ *
601
+ * - If current progress is within [early, late], run immediately.
602
+ * - If too early, sleep until `early` percentage into the epoch.
603
+ * - If too late, sleep until `early` percentage into the *next* epoch.
604
+ *
605
+ * This is generic; you can wrap any instruction builder in here (including
606
+ * deposit flows) without baking in program-specific logic.
607
+ */
608
+ declare function scheduledInstruction<T>(connection: Connection, config: ScheduleConfig, instruction: () => Promise<T>): Promise<T>;
609
+ declare function getErrorMessage(error: any): string;
610
+ declare function generateRandomDepositAmount(minSol?: number, maxSol?: number): BN;
611
+ declare function generateTestKeypair(): Keypair;
612
+ declare function airdropSol(connection: Connection, publicKey: PublicKey$1, amountSol: number): Promise<void>;
613
+ declare function waitForConfirmation(connection: Connection, signature: string): Promise<void>;
614
+ declare function sleep(ms: number): Promise<void>;
615
+ /**
616
+ * Simple helper used in tests: wait until safe zone, no-op.
617
+ */
618
+ declare function waitUntilSafeToExecuteFunction(connection: Connection, config?: ScheduleConfig): Promise<void>;
619
+ interface ScheduleConfig {
620
+ early?: number;
621
+ late?: number;
622
+ }
623
+
756
624
  declare class DepositClient {
757
625
  private provider;
758
- private programs;
626
+ private program;
759
627
  constructor(provider: AnchorProvider);
760
- /**
761
- * Build the deposit transaction (compute-budget bump + deposit Ix).
762
- * Returns the Transaction and the derived ephemeral stake pubkey.
763
- */
764
- buildDepositTx(user: PublicKey$1, amount: number): Promise<{
628
+ buildDepositTx(user: PublicKey$1, lamports: number): Promise<{
765
629
  transaction: Transaction;
766
- ephemeralStakePubkey: PublicKey$1;
767
- }>;
768
- /** Simulate a transaction (dry-run). */
769
- simulate(tx: Transaction): Promise<{
770
- err: any;
771
- unitsConsumed: number;
630
+ ephemeralStake: PublicKey$1;
772
631
  }>;
773
- /** Build + send. Returns confirmed signature. */
774
- deposit(user: PublicKey$1, amount: number, signers?: Signer$1[]): Promise<TransactionSignature>;
775
632
  }
776
633
 
634
+ /**
635
+ * Distribution client – wraps the distribution portion of the liqsol_core
636
+ * program. Responsible for:
637
+ * - Reading DistributionState + UserRecord
638
+ * - Computing mismatch candidates (tracked > actual)
639
+ * - Building a "correct then register" transaction for the caller
640
+ *
641
+ * Aligned with the on-chain `update_user` script:
642
+ * - Single `updateUser()` entrypoint that:
643
+ * * Can create userRecord if missing
644
+ * * Reconciles tracked vs actual using user, userAta, bucket, pay-rate
645
+ */
777
646
  declare class DistributionClient {
778
647
  private provider;
779
- private programs;
648
+ private program;
780
649
  constructor(provider: AnchorProvider);
781
- /** Anchor Program<Distribution> (address comes from SolanaProgramService) */
782
- private get program();
783
- /**
784
- * Fetch Distribution global state.
785
- */
786
- getDistributionState(): Promise<any>;
650
+ get connection(): _solana_web3_js.Connection;
787
651
  /**
788
- * Fetch a user’s UserRecord or null if it doesn’t exist yet.
652
+ * Fetch the global distribution state account.
789
653
  */
790
- getUserRecord(user: PublicKey$1): Promise<any | null>;
654
+ getDistributionState(): Promise<DistributionState | null>;
791
655
  /**
792
- * Read protocol-tracked balance for a user (from userRecord).
793
- * Returns (amount, decimals).
794
- * @default decimals=9
656
+ * Fetch a user's distribution userRecord (or null if missing).
795
657
  */
796
- getTrackedBalance(user: PublicKey$1): Promise<{
797
- amount: bigint;
798
- decimals: number;
799
- }>;
658
+ getUserRecord(user: PublicKey$1): Promise<UserRecord | null>;
800
659
  /**
801
- * Read *actual* liqSOL token balance (ATA) for a user.
802
- * If user has no ATA yet, returns 0.
803
- * @returns { amount, decimals, ata }
804
- */
805
- getActualBalance(user: PublicKey$1): Promise<{
806
- amount: bigint;
807
- decimals: number;
808
- ata: PublicKey$1;
809
- }>;
810
- /**
811
- * Register / Update a user’s record.
812
- * - If updating someone else, pass their pubkey as `targetUser` and let the connected wallet be `authority`.
813
- * - Optionally pass an explicit `authorityUser` if you need to override (must be the connected wallet).
814
- * Returns the tx signature.
660
+ * Helper: get actual liqSOL balances for all token holders.
661
+ *
662
+ * Returns a map: owner (base58) -> actual balance (BigInt)
815
663
  */
664
+ private getActualBalancesByOwner;
816
665
  /**
817
- * Register / Update a user’s record with the connected wallet as authority.
818
- * Keeps a single source of truth via `prepareUpdateUser()`.
666
+ * Helper: get tracked balances from all userRecord accounts,
667
+ * keyed by *actual wallet owner*, not the userRecord PDA.
668
+ *
669
+ * userRecord struct:
670
+ * - userAta: pubkey
671
+ * - trackedBalance: u64
672
+ * - claimBalance: u64
673
+ * - lastClaimTimestamp: i64
674
+ * - bump: u8
819
675
  */
820
- updateUser(targetUser: PublicKey$1): Promise<string>;
821
- /** Build-only variant (returns the IX) so you can batch. */
822
- buildUpdateUserIx(targetUser: PublicKey$1): Promise<TransactionInstruction>;
676
+ private getTrackedBalances;
823
677
  /**
824
- * Claim rewards for a user.
825
- * @returns tx signature
678
+ * Discover all mismatch candidates where tracked > actual.
679
+ *
680
+ * - actual balances are derived from token accounts for the liqSOL mint
681
+ * - tracked balances come from Distribution.userRecord
826
682
  */
827
- claimRewards(user: PublicKey$1): Promise<string>;
683
+ private deriveMismatchCandidates;
828
684
  /**
829
- * Withdraw liqSOL (amount in base units; e.g. 1e9 = 1 liqSOL).
830
- * @returns tx signature
685
+ * Canonical helper to build an `updateUser` instruction for a given user,
686
+ * matching the standalone update-user.ts script.
831
687
  */
832
- withdraw(user: PublicKey$1, amount: bigint | number): Promise<string>;
833
- /** Single prep path used by both send & build. */
834
- private prepareUpdateUser;
688
+ private buildUpdateUserIx;
835
689
  /**
836
- * Build a single transaction that:
837
- * 1) If self mismatch < 0 → just correct self (single updateUser).
838
- * 2) Else (mismatch > 0) → correct top candidates (if needed) to free “available” balance
839
- * and then register self (updateUser).
690
+ * Build the "correct & register" transaction.
840
691
  *
841
- * It refuses to build if it can’t free enough to cover the full positive untracked amount
842
- * (since updateUser has no partial-amount arg).
692
+ * - Fetches DistributionState + all userRecords + token holders
693
+ * - Computes caller's untracked amount (actual - tracked)
694
+ * - If DistributionState.availableBalance already covers that, we only
695
+ * send updateUser(caller).
696
+ * - Otherwise we select top mismatch candidates until their freed deltas
697
+ * cover the shortfall, then build updateUser(target) for each,
698
+ * followed by updateUser(caller).
699
+ *
700
+ * NOTE:
701
+ * - This no longer uses a separate updateSpecificUser; the single
702
+ * updateUser entrypoint accepts any `user` as long as authority/payer
703
+ * are valid, per your script.
843
704
  */
844
705
  buildCorrectRegisterTx(opts?: {
845
- /** optional override of computed mismatch; may be positive (register) or negative (self-correct) */
846
706
  amount?: bigint;
847
- /** optionally pass pre-fetched candidates to avoid re-reading on UI flows */
848
- preloadCandidates?: MismatchCandidate[];
849
- }): Promise<CorrectAndRegisterBuild>;
850
- /**
851
- * Fetch all distribution user records and turn them into mismatch candidates:
852
- * rows where `tracked > actual` (delta > 0). Sorted by largest delta first.
853
- *
854
- * NOTE: This reads each user’s token account (`getAccount`) to recover
855
- * the owner and actual balance — simpler and reliable for Token-2022 ATAs.
856
- */
857
- fetchMismatchCandidates(): Promise<MismatchCandidate[]>;
858
- /**
859
- * Given a required amount to free (in base units), choose the
860
- * smallest prefix of candidates (already sorted desc) that can cover it.
861
- */
862
- chooseCandidatesFor(required: bigint, candidates: MismatchCandidate[]): CorrectionPlan;
707
+ maxCandidates?: number;
708
+ }): Promise<CorrectRegisterBuildResult>;
863
709
  }
864
710
 
865
- declare class ValidatorLeaderboardClient {
711
+ /**
712
+ * Simple read client for the validator_leaderboard program.
713
+ *
714
+ * Adjust account names/fields to match your IDL (state, validatorRecord, etc).
715
+ */
716
+ declare class LeaderboardClient {
866
717
  private provider;
867
- private programs;
718
+ private program;
868
719
  constructor(provider: AnchorProvider);
869
- /** Anchor Program<ValidatorLeaderboard> via ProgramService */
870
- private get program();
871
- /** Initialize the leaderboard head account. */
872
- buildInitializeIx(authority: PublicKey$1): Promise<TransactionInstruction>;
720
+ getState(): Promise<any | null>;
721
+ getValidatorRecord(voteAccount: PublicKey$1): Promise<any | null>;
873
722
  /**
874
- * Upsert/update a validator record and (optionally) reposition it in the linked list.
875
- * Any of insertAfter/insertBefore/currentPrev/currentNext can be omitted.
723
+ * Convenience helper to fetch and sort top validators by score.
724
+ * Assumes `validatorRecord` has a numeric `score` field in the IDL.
876
725
  */
877
- buildUpdateValidatorIx(params: {
878
- registrant: PublicKey$1;
879
- voteAccount: PublicKey$1;
880
- vpp: number;
881
- insertAfter?: PublicKey$1;
882
- insertBefore?: PublicKey$1;
883
- currentPrev?: PublicKey$1;
884
- currentNext?: PublicKey$1;
885
- }): Promise<TransactionInstruction>;
886
- /** Update the Top-10 cache. Requires exactly 10 validator vote accounts. */
887
- buildUpdateTop10CacheIx(params: {
888
- authority: PublicKey$1;
889
- top10Validators: PublicKey$1[];
890
- }): Promise<TransactionInstruction>;
891
- buildInitializeTx(authority: PublicKey$1): Promise<Transaction>;
892
- buildUpdateValidatorTx(params: {
893
- registrant: PublicKey$1;
894
- voteAccount: PublicKey$1;
895
- vpp: number;
896
- insertAfter?: PublicKey$1;
897
- insertBefore?: PublicKey$1;
898
- currentPrev?: PublicKey$1;
899
- currentNext?: PublicKey$1;
900
- }): Promise<Transaction>;
901
- buildUpdateTop10CacheTx(params: {
902
- authority: PublicKey$1;
903
- top10Validators: PublicKey$1[];
904
- }): Promise<Transaction>;
905
- /** Traverse the linked-list leaderboard, returning vote accounts in order. */
906
- getLeaderboard(): Promise<PublicKey$1[]>;
907
- /** Fetch a single validator record (or null if it doesn't exist). */
908
- getValidatorRecord(voteAccount: PublicKey$1): Promise<any | null>;
726
+ getTopValidators(limit?: number): Promise<any[]>;
909
727
  }
910
728
 
911
- export { ADDRESSES, CONTRACTS, DEPOSIT_PROGRAM_ID, DISTRIBUTION_PROGRAM_ID, DepositClient, DistributionClient, ERC1155Abi, ERC20Abi, ERC721Abi, types$1 as ETH, EthereumContractService, EthereumStakingClient, LIQSOL_MINT_ADDRESS, LIQSOL_TOKEN_PROGRAM_ID, MIN_SOL_TO_PARTICIPATE, types as SOL, STAKE_CONTROLLER_PROGRAM_ID, SolanaStakingClient, Staker, VALIDATOR_LEADERBOARD_PROGRAM_ID, ValidatorLeaderboardClient, YIELD_ORACLE_PROGRAM_ID, deriveBucketAuthorityPDA, deriveDepositAuthorityPDA, deriveDistributionStatePDA, deriveGlobalStakeInfoPDA, deriveLeaderboardHeadPDA, deriveLiqsolMintAuthorityPDA, deriveLiqsolMintPDA, derivePayRateHistoryPDA, deriveStakeControllerAuthorityPDA, deriveStakeControllerReservePoolPDA, deriveStakeControllerStatePDA, deriveStakeControllerVaultPDA, deriveTop10CachePDA, deriveUserRecordPDA, deriveValidatorRecordPDA, getDepositProgram, getUserLiqsolATA, hi };
912
- export type { BalanceView, ContractConfig, ContractOptions, Contracts, IStakingClient, Portfolio, StakerConfig, TxResult };
729
+ export { ADDRESSES, CONTRACTS, DEFAULT_AVERAGE_PAY_RATE, DEFAULT_PAY_RATE_LOOKBACK, DepositClient, DistributionClient, EPHEMERAL_RENT_EXEMPTION, ERC1155Abi, ERC20Abi, ERC721Abi, types$1 as ETH, EthereumContractService, EthereumStakingClient, LAMPORTS_PER_SOL, LIQSOL_CORE, LIQSOL_TOKEN, LeaderboardClient, PAY_RATE_SCALE_FACTOR, PDA_SEEDS, PROGRAM_IDS, types as SOL, SolanaStakingClient, Staker, VALIDATOR_LEADERBOARD, airdropSol, buildDepositAccounts, calculateExpectedFee, deriveBucketAuthorityPda, deriveDepositAuthorityPda, deriveDistributionStatePda, deriveEphemeralStakeAddress, deriveLeaderboardStatePda, deriveLiqsolMintAuthorityPda, deriveLiqsolMintPda, derivePayRateHistoryPda, derivePayoutStatePda, deriveReservePoolPda, deriveStakeControllerStatePda, deriveStakeControllerVaultPda, deriveUserRecordPda, deriveValidatorRecordPda, deriveVaultPda, generateRandomDepositAmount, generateTestKeypair, getAveragePayRate, getBucketLiqSolBalance, getEpochSnapshot, getErrorMessage, getLiqsolCoreProgram, getPayoutStateRaw, getReservePoolBalance, getStakeControllerStateRaw, getUserLiqSolBalance, getUserRecordRaw, lamportsToSol, msToEpochEnd, previewDepositEffects, scheduledInstruction, sleep, solToLamports, waitForConfirmation, waitUntilSafeToExecuteFunction };
730
+ export type { BalanceView, ContractConfig, ContractOptions, Contracts, DepositAccounts, EpochSnapshot, IStakingClient, Portfolio, ScheduleConfig, SolanaCluster, StakerConfig, TxResult };