@wireio/stake 0.4.2 → 0.5.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.
Files changed (133) hide show
  1. package/lib/stake.browser.js +18509 -11887
  2. package/lib/stake.browser.js.map +1 -1
  3. package/lib/stake.d.ts +899 -140
  4. package/lib/stake.js +18524 -11890
  5. package/lib/stake.js.map +1 -1
  6. package/lib/stake.m.js +18509 -11887
  7. package/lib/stake.m.js.map +1 -1
  8. package/package.json +2 -2
  9. package/src/assets/ethereum/ABI/common/Base58.sol/Base58.dbg.json +4 -0
  10. package/src/assets/ethereum/ABI/common/Base58.sol/Base58.json +164 -0
  11. package/src/assets/ethereum/ABI/common/OpenZepArtifacts.sol/__Dummy_OZ_UUPS__.dbg.json +4 -0
  12. package/src/assets/ethereum/ABI/common/OpenZepArtifacts.sol/__Dummy_OZ_UUPS__.json +76 -0
  13. package/src/assets/ethereum/ABI/common/RestrictedCallers.sol/RestrictedCallers.dbg.json +4 -0
  14. package/src/assets/ethereum/ABI/common/RestrictedCallers.sol/RestrictedCallers.json +10 -0
  15. package/src/assets/ethereum/ABI/common/iodata.sol/iodata.dbg.json +4 -0
  16. package/src/assets/ethereum/ABI/common/iodata.sol/iodata.json +618 -0
  17. package/src/assets/ethereum/ABI/common/iodata_util.sol/iodata_util.dbg.json +4 -0
  18. package/src/assets/ethereum/ABI/common/iodata_util.sol/iodata_util.json +40 -0
  19. package/src/assets/ethereum/ABI/common/sysio_data.sol/sysio_data.dbg.json +4 -0
  20. package/src/assets/ethereum/ABI/common/sysio_data.sol/sysio_data.json +10 -0
  21. package/src/assets/ethereum/ABI/common/sysio_errors.sol/sysio_errors.dbg.json +4 -0
  22. package/src/assets/ethereum/ABI/common/sysio_errors.sol/sysio_errors.json +10 -0
  23. package/src/assets/ethereum/ABI/common/sysio_merkle.sol/sysio_merkle.dbg.json +4 -0
  24. package/src/assets/ethereum/ABI/common/sysio_merkle.sol/sysio_merkle.json +233 -0
  25. package/src/assets/ethereum/ABI/common/sysio_name.sol/sysio_name.dbg.json +4 -0
  26. package/src/assets/ethereum/ABI/common/sysio_name.sol/sysio_name.json +49 -0
  27. package/src/assets/ethereum/ABI/common/sysio_pubkey.sol/sysio_pubkey.dbg.json +4 -0
  28. package/src/assets/ethereum/ABI/common/sysio_pubkey.sol/sysio_pubkey.json +64 -0
  29. package/src/assets/ethereum/ABI/common/sysio_read.sol/sysio_read.dbg.json +4 -0
  30. package/src/assets/ethereum/ABI/common/sysio_read.sol/sysio_read.json +1458 -0
  31. package/src/assets/ethereum/ABI/common/sysio_tester.sol/SysioTester.dbg.json +4 -0
  32. package/src/assets/ethereum/ABI/common/sysio_tester.sol/SysioTester.json +1532 -0
  33. package/src/assets/ethereum/ABI/common/sysio_verify.sol/sysio_verify.dbg.json +4 -0
  34. package/src/assets/ethereum/ABI/common/sysio_verify.sol/sysio_verify.json +1525 -0
  35. package/src/assets/ethereum/ABI/common/sysio_write.sol/sysio_write.dbg.json +4 -0
  36. package/src/assets/ethereum/ABI/common/sysio_write.sol/sysio_write.json +1076 -0
  37. package/src/assets/ethereum/ABI/liqEth/BeaconState.sol/BeaconState.dbg.json +1 -1
  38. package/src/assets/ethereum/ABI/liqEth/DepositManager.sol/DepositManager.dbg.json +1 -1
  39. package/src/assets/ethereum/ABI/liqEth/DepositManager.sol/DepositManager.json +28 -2
  40. package/src/assets/ethereum/ABI/liqEth/LiqEthAuthority.sol/LiqEthAuthority.dbg.json +1 -1
  41. package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IAccounting.dbg.json +1 -1
  42. package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IDepositContract.dbg.json +1 -1
  43. package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IDepositManager.dbg.json +1 -1
  44. package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/ILiqEthUpgradeable.dbg.json +1 -1
  45. package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IRewardsERC20.dbg.json +1 -1
  46. package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IRewardsERC20Pausable.dbg.json +1 -1
  47. package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IStakingModule.dbg.json +1 -1
  48. package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IValidatorBalanceVerifier.dbg.json +1 -1
  49. package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IWithdrawalRecord.dbg.json +1 -1
  50. package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/LiqEthCommon.dbg.json +1 -1
  51. package/src/assets/ethereum/ABI/liqEth/LiqEthManaged.sol/LiqEthManaged.dbg.json +1 -1
  52. package/src/assets/ethereum/ABI/liqEth/RewardsERC20.sol/RewardsERC20Upgradeable.dbg.json +1 -1
  53. package/src/assets/ethereum/ABI/liqEth/RewardsERC20Pausable.sol/RewardsERC20PausableUpgradeable.dbg.json +1 -1
  54. package/src/assets/ethereum/ABI/liqEth/Yield.sol/YieldOracle.dbg.json +1 -1
  55. package/src/assets/ethereum/ABI/liqEth/Yield.sol/YieldOracle.json +2 -2
  56. package/src/assets/ethereum/ABI/liqEth/accounting.sol/Accounting.dbg.json +1 -1
  57. package/src/assets/ethereum/ABI/liqEth/accounting.sol/Accounting.json +2 -15
  58. package/src/assets/ethereum/ABI/liqEth/liqEth.sol/LiqEthToken.dbg.json +1 -1
  59. package/src/assets/ethereum/ABI/liqEth/stakingModule.sol/StakingModule.dbg.json +1 -1
  60. package/src/assets/ethereum/ABI/liqEth/stakingModule.sol/StakingModule.json +6 -25
  61. package/src/assets/ethereum/ABI/liqEth/withdrawalQueue.sol/WithdrawalQueue.dbg.json +1 -1
  62. package/src/assets/ethereum/ABI/liqEth/withdrawalVault.sol/Uint64BE.dbg.json +1 -1
  63. package/src/assets/ethereum/ABI/liqEth/withdrawalVault.sol/Uint64BE.json +2 -2
  64. package/src/assets/ethereum/ABI/liqEth/withdrawalVault.sol/WithdrawalVault.dbg.json +1 -1
  65. package/src/assets/ethereum/ABI/liqEth/withdrawalVault.sol/WithdrawalVault.json +6 -25
  66. package/src/assets/ethereum/ABI/outpost/BAR.sol/BAR.dbg.json +1 -1
  67. package/src/assets/ethereum/ABI/outpost/Depositor.sol/Depositor.dbg.json +1 -1
  68. package/src/assets/ethereum/ABI/outpost/Depositor.sol/Depositor.json +26 -26
  69. package/src/assets/ethereum/ABI/outpost/EthUsdPriceConsumer.sol/AggregatorV3Interface.dbg.json +1 -1
  70. package/src/assets/ethereum/ABI/outpost/EthUsdPriceConsumer.sol/EthUsdPriceConsumer.dbg.json +1 -1
  71. package/src/assets/ethereum/ABI/outpost/OPP.sol/OPP.dbg.json +1 -1
  72. package/src/assets/ethereum/ABI/outpost/OPPCommon.sol/IOPP.dbg.json +1 -1
  73. package/src/assets/ethereum/ABI/outpost/OPPCommon.sol/IOPPEndpoint.dbg.json +1 -1
  74. package/src/assets/ethereum/ABI/outpost/OPPCommon.sol/IOPPInbound.dbg.json +1 -1
  75. package/src/assets/ethereum/ABI/outpost/OPPCommon.sol/IOPPReceiver.dbg.json +1 -1
  76. package/src/assets/ethereum/ABI/outpost/OPPCommon.sol/IOPPSender.dbg.json +1 -1
  77. package/src/assets/ethereum/ABI/outpost/OPPCommon.sol/OPPCommon.dbg.json +1 -1
  78. package/src/assets/ethereum/ABI/outpost/OPPEndpoint.sol/OPPEndpoint.dbg.json +1 -1
  79. package/src/assets/ethereum/ABI/outpost/OPPEndpointManaged.sol/OPPEndpointManaged.dbg.json +1 -1
  80. package/src/assets/ethereum/ABI/outpost/OPPEndpointOwnable.sol/OPPEndpointOwnable.dbg.json +1 -1
  81. package/src/assets/ethereum/ABI/outpost/OPPErrors.sol/OPPErrors.dbg.json +1 -1
  82. package/src/assets/ethereum/ABI/outpost/OPPInbound.sol/OPPInbound.dbg.json +1 -1
  83. package/src/assets/ethereum/ABI/outpost/OPPReceiver.sol/OPPReceiver.dbg.json +1 -1
  84. package/src/assets/ethereum/ABI/outpost/OPPSender.sol/OPPSender.dbg.json +1 -1
  85. package/src/assets/ethereum/ABI/outpost/OutpostErrors.sol/OutpostErrors.dbg.json +1 -1
  86. package/src/assets/ethereum/ABI/outpost/OutpostManaged.sol/OutpostManaged.dbg.json +1 -1
  87. package/src/assets/ethereum/ABI/outpost/OutpostManager.sol/OutpostManager.dbg.json +1 -1
  88. package/src/assets/ethereum/ABI/outpost/OutpostManagerAuthority.sol/OutpostManagerAuthority.dbg.json +1 -1
  89. package/src/assets/ethereum/ABI/outpost/OutpostManagerCommon.sol/IOutpostManager.dbg.json +1 -1
  90. package/src/assets/ethereum/ABI/outpost/OutpostManagerCommon.sol/IOutpostUpgradeable.dbg.json +1 -1
  91. package/src/assets/ethereum/ABI/outpost/OutpostManagerCommon.sol/OutpostManagerCommon.dbg.json +1 -1
  92. package/src/assets/ethereum/ABI/outpost/OutpostOwnable.sol/OutpostOwnable.dbg.json +1 -1
  93. package/src/assets/ethereum/ABI/outpost/Pool.sol/Pool.dbg.json +1 -1
  94. package/src/assets/ethereum/ABI/outpost/Pool.sol/Pool.json +2 -2
  95. package/src/assets/ethereum/ABI/outpost/Pretoken.sol/Pretoken.dbg.json +1 -1
  96. package/src/assets/ethereum/ABI/outpost/Pretoken.sol/Pretoken.json +9 -9
  97. package/src/assets/ethereum/ABI/outpost/ReceiptNFT.sol/ReceiptNFT.dbg.json +1 -1
  98. package/src/assets/ethereum/ABI/outpost/interfaces/IPretoken.sol/IPretoken.dbg.json +1 -1
  99. package/src/assets/ethereum/ABI/outpost/interfaces/IWarrant.sol/IWarrant.dbg.json +1 -1
  100. package/src/assets/ethereum/ABI/outpost/token/ERC721EthEquivalentVotesUpgradeable.sol/ERC721EthEquivalentVotesUpgradeable.dbg.json +1 -1
  101. package/src/assets/ethereum/ABI/outpost/token/IERC721EthEquivalent.sol/IERC721EthEquivalent.dbg.json +1 -1
  102. package/src/assets/solana/idl/liqsol_core.json +760 -150
  103. package/src/assets/solana/idl/liqsol_token.json +1 -1
  104. package/src/assets/solana/idl/transfer_hook.json +6 -1
  105. package/src/assets/solana/idl/validator_leaderboard.json +4 -1
  106. package/src/assets/solana/types/liqsol_core.ts +760 -150
  107. package/src/assets/solana/types/liqsol_token.ts +1 -1
  108. package/src/assets/solana/types/transfer_hook.ts +6 -1
  109. package/src/assets/solana/types/validator_leaderboard.ts +4 -1
  110. package/src/networks/ethereum/clients/convert.client.ts +2 -2
  111. package/src/networks/ethereum/clients/pretoken.client.ts +6 -4
  112. package/src/networks/ethereum/clients/stake.client.ts +2 -2
  113. package/src/networks/ethereum/contract.ts +102 -49
  114. package/src/networks/ethereum/ethereum.ts +117 -58
  115. package/src/networks/ethereum/types.ts +26 -17
  116. package/src/networks/ethereum/utils.ts +8 -8
  117. package/src/networks/solana/clients/deposit.client.ts +5 -4
  118. package/src/networks/solana/clients/distribution.client.ts +36 -1
  119. package/src/networks/solana/constants.ts +14 -0
  120. package/src/networks/solana/solana.ts +148 -17
  121. package/src/networks/solana/types.ts +129 -0
  122. package/src/types.ts +21 -11
  123. package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/BeaconRoots.dbg.json +0 -4
  124. package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/BeaconRoots.json +0 -10
  125. package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/SSZ.dbg.json +0 -4
  126. package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/SSZ.json +0 -10
  127. package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/SSZExtras.dbg.json +0 -4
  128. package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/SSZExtras.json +0 -10
  129. package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/SSZVec48.dbg.json +0 -4
  130. package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/SSZVec48.json +0 -10
  131. package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/ValidatorBalanceVerifier.dbg.json +0 -4
  132. package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/ValidatorBalanceVerifier.json +0 -291
  133. package/src/assets/ethereum/ABI/outpost/Aggregator.sol/Aggregator.json +0 -82
@@ -157,7 +157,7 @@ export function buildEthereumTrancheLadder(options: {
157
157
  currentTrancheSupply: bigint;
158
158
  currentPriceUsd: bigint;
159
159
  supplyGrowthBps: number;
160
- priceGrowthBps: number;
160
+ priceIncrementUsd: number;
161
161
  windowBefore?: number;
162
162
  windowAfter?: number;
163
163
  }): TrancheLadderItem[] {
@@ -167,7 +167,7 @@ export function buildEthereumTrancheLadder(options: {
167
167
  currentTrancheSupply,
168
168
  currentPriceUsd,
169
169
  supplyGrowthBps,
170
- priceGrowthBps,
170
+ priceIncrementUsd,
171
171
  windowBefore = 5,
172
172
  windowAfter = 5,
173
173
  } = options;
@@ -190,7 +190,7 @@ export function buildEthereumTrancheLadder(options: {
190
190
  const prevCap = capacity.get(id - 1)!;
191
191
  const prevPrice = price.get(id - 1)!;
192
192
  capacity.set(id, growOnce(prevCap, supplyGrowthBps));
193
- price.set(id, growOnce(prevPrice, priceGrowthBps));
193
+ price.set(id, growOnce(prevPrice, priceIncrementUsd));
194
194
  }
195
195
 
196
196
  // Backward (past tranches)
@@ -198,7 +198,7 @@ export function buildEthereumTrancheLadder(options: {
198
198
  const nextCap = capacity.get(id + 1)!;
199
199
  const nextPrice = price.get(id + 1)!;
200
200
  capacity.set(id, shrinkOnce(nextCap, supplyGrowthBps));
201
- price.set(id, shrinkOnce(nextPrice, priceGrowthBps));
201
+ price.set(id, shrinkOnce(nextPrice, priceIncrementUsd));
202
202
  }
203
203
 
204
204
  const ladder: TrancheLadderItem[] = [];
@@ -240,7 +240,7 @@ export async function buildEthereumTrancheSnapshot(options: {
240
240
  totalTrancheSupply;
241
241
  initialTrancheSupply;
242
242
  supplyGrowthBps;
243
- priceGrowthBps;
243
+ priceIncrementUsd;
244
244
  minPriceUsd;
245
245
  maxPriceUsd;
246
246
 
@@ -264,7 +264,7 @@ export async function buildEthereumTrancheSnapshot(options: {
264
264
  totalTrancheSupply,
265
265
  initialTrancheSupply,
266
266
  supplyGrowthBps,
267
- priceGrowthBps,
267
+ priceIncrementUsd,
268
268
  minPriceUsd,
269
269
  maxPriceUsd,
270
270
  } = options;
@@ -284,7 +284,7 @@ export async function buildEthereumTrancheSnapshot(options: {
284
284
  currentTrancheSupply,
285
285
  currentPriceUsd,
286
286
  supplyGrowthBps,
287
- priceGrowthBps,
287
+ priceIncrementUsd,
288
288
  windowBefore: ladderWindowBefore,
289
289
  windowAfter: ladderWindowAfter,
290
290
  });
@@ -297,7 +297,7 @@ export async function buildEthereumTrancheSnapshot(options: {
297
297
  currentTranche,
298
298
  currentPriceUsd,
299
299
  supplyGrowthBps,
300
- priceGrowthBps,
300
+ priceIncrementUsd,
301
301
  currentTrancheSupply,
302
302
  initialTrancheSupply,
303
303
  totalPretokensSold: totalTrancheSupply,
@@ -40,6 +40,7 @@ import {
40
40
  deriveWithdrawMintMetadataPda,
41
41
  deriveWithdrawNftMintPda,
42
42
  deriveLiqReceiptDataPda,
43
+ deriveGlobalConfigPda,
43
44
  } from '../constants';
44
45
  import { WalletLike } from '../types';
45
46
 
@@ -86,6 +87,7 @@ export class DepositClient {
86
87
  const payoutState = derivePayoutStatePda();
87
88
  const bucketAuthority = deriveBucketAuthorityPda();
88
89
  const payRateHistory = derivePayRateHistoryPda();
90
+ const globalConfig = deriveGlobalConfigPda();
89
91
 
90
92
  // -------------------------------------------------------------
91
93
  // Token-2022 ATAs
@@ -129,27 +131,24 @@ export class DepositClient {
129
131
  associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
130
132
  liqsolProgram: PROGRAM_IDS.LIQSOL_TOKEN,
131
133
  stakeProgram: StakeProgram.programId,
132
-
133
134
  liqsolMint,
134
135
  userAta,
135
136
  liqsolMintAuthority,
136
137
  reservePool,
137
138
  vault,
138
139
  ephemeralStake,
139
-
140
140
  controllerState,
141
141
  payoutState,
142
142
  bucketAuthority,
143
143
  bucketTokenAccount,
144
-
145
144
  userRecord,
146
145
  distributionState,
147
146
  payRateHistory,
148
-
149
147
  instructionsSysvar: SYSVAR_INSTRUCTIONS_PUBKEY,
150
148
  clock: SYSVAR_CLOCK_PUBKEY,
151
149
  stakeHistory: SYSVAR_STAKE_HISTORY_PUBKEY,
152
150
  rent: SYSVAR_RENT_PUBKEY,
151
+ globalConfig
153
152
  })
154
153
  .instruction();
155
154
 
@@ -203,6 +202,7 @@ export class DepositClient {
203
202
  const stakeAllocationState = deriveStakeAllocationStatePda();
204
203
  const stakeMetrics = deriveStakeMetricsPda();
205
204
  const maintenanceLedger = deriveMaintenanceLedgerPda();
205
+ const globalConfig = deriveGlobalConfigPda();
206
206
 
207
207
  // -------------------------------------------------------------
208
208
  // Need nextReceiptId from withdraw global state
@@ -265,6 +265,7 @@ export class DepositClient {
265
265
  associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
266
266
  systemProgram: SystemProgram.programId,
267
267
  rent: SYSVAR_RENT_PUBKEY,
268
+ globalConfig
268
269
  })
269
270
  .instruction();
270
271
 
@@ -5,10 +5,12 @@ import { SolanaProgramService } from '../program';
5
5
  import type { LiqsolCore } from '../../../assets/solana/types/liqsol_core';
6
6
  import {
7
7
  deriveDistributionStatePda,
8
+ deriveGlobalConfigPda,
8
9
  deriveLiqsolMintPda,
10
+ derivePayRateHistoryPda,
9
11
  deriveUserRecordPda,
10
12
  } from '../constants';
11
- import type { DistributionState, DistributionUserRecord } from '../types';
13
+ import type { DistributionState, DistributionUserRecord, GlobalConfig, PayRateHistory } from '../types';
12
14
  import { getAssociatedTokenAddressSync, TOKEN_2022_PROGRAM_ID } from '@solana/spl-token';
13
15
 
14
16
  /**
@@ -55,6 +57,39 @@ export class DistributionClient {
55
57
  }
56
58
  }
57
59
 
60
+
61
+ /**
62
+ * Fetch the global payRateHistory account (circular buffer of scaled pay rates).
63
+ *
64
+ * IDL account name: "payRateHistory"
65
+ */
66
+ async getPayRateHistory(): Promise<PayRateHistory | null> {
67
+ const pda = derivePayRateHistoryPda();
68
+ try {
69
+ // Anchor types map directly onto our PayRateHistory TS type
70
+ return (await this.program.account.payRateHistory.fetch(
71
+ pda,
72
+ )) as PayRateHistory;
73
+ } catch {
74
+ return null;
75
+ }
76
+ }
77
+
78
+ /**
79
+ * Fetch the globalConfig account (contains depositFeeMultiplier, etc).
80
+ *
81
+ * IDL account name: "globalConfig"
82
+ */
83
+ async getGlobalConfig(): Promise<GlobalConfig | null> {
84
+ const pda = deriveGlobalConfigPda();
85
+ try {
86
+ return (await this.program.account.globalConfig.fetch(
87
+ pda,
88
+ ));
89
+ } catch {
90
+ return null;
91
+ }
92
+ }
58
93
  /**
59
94
  * Fetch a user's distribution userRecord (or null if missing).
60
95
  *
@@ -36,6 +36,9 @@ export const {
36
36
  */
37
37
 
38
38
  export const PDA_SEEDS = {
39
+ // GLOBAL CONFIG
40
+ GLOBAL_CONFIG: 'global_config',
41
+
39
42
  // liqsol_core: deposit / stake controller
40
43
  DEPOSIT_AUTHORITY: 'deposit_authority',
41
44
  VAULT: 'vault',
@@ -86,8 +89,19 @@ export const PDA_SEEDS = {
86
89
  MINT_METADATA: 'mint_metadata',
87
90
  LIQ_RECEIPT_DATA: 'liq_receipt_data',
88
91
  WITHDRAW_MINT: 'mint',
92
+
93
+
94
+
89
95
  } as const;
90
96
 
97
+ // Global Config PDA
98
+ export const deriveGlobalConfigPda = () =>
99
+ PublicKey.findProgramAddressSync(
100
+ [Buffer.from(PDA_SEEDS.GLOBAL_CONFIG)],
101
+ LIQSOL_CORE,
102
+ )[0];
103
+
104
+
91
105
  /**
92
106
  * ---------------------------------------------------------------------------
93
107
  * CORE / DISTRIBUTION / DEPOSIT PDAS
@@ -7,7 +7,7 @@ import {
7
7
  Transaction,
8
8
  TransactionSignature,
9
9
  } from '@solana/web3.js';
10
- import { AnchorProvider } from '@coral-xyz/anchor';
10
+ import { AnchorProvider, BN } from '@coral-xyz/anchor';
11
11
  import { BaseSignerWalletAdapter } from '@solana/wallet-adapter-base';
12
12
  import {
13
13
  ASSOCIATED_TOKEN_PROGRAM_ID,
@@ -44,7 +44,7 @@ import {
44
44
  } from './constants';
45
45
 
46
46
  import { buildSolanaTrancheSnapshot } from './utils';
47
- import { SolanaTransaction } from './types';
47
+ import { PayRateEntry, SolanaTransaction } from './types';
48
48
 
49
49
  const commitment: Commitment = 'confirmed';
50
50
 
@@ -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
 
@@ -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
 
@@ -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
- // - estimatedYieldLiqsol: max(0, estimatedClaim - stakedLiqsol)
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 estimatedClaimLiqsol = BigInt(0);
396
- let estimatedYieldLiqsol = BigInt(0);
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
- estimatedClaimLiqsol = (userShares * currentIndex) / INDEX_SCALE;
406
+ estimatedClaim = (userShares * currentIndex) / INDEX_SCALE;
401
407
 
402
- if (estimatedClaimLiqsol > stakedLiqsol) {
403
- estimatedYieldLiqsol = estimatedClaimLiqsol - stakedLiqsol;
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
- estimatedClaimLiqsol,
439
- estimatedYieldLiqsol,
444
+ estimatedClaim,
445
+ estimatedYield,
440
446
  },
441
447
  extras: {
442
448
  userLiqsolAta: userLiqsolAta.toBase58(),
@@ -462,7 +468,7 @@ export class SolanaStakingClient implements IStakingClient {
462
468
  return this.distributionClient.getUserRecord(this.solPubKey);
463
469
  }
464
470
 
465
-
471
+
466
472
  // ---------------------------------------------------------------------
467
473
  // READ-ONLY Public Methods
468
474
  // ---------------------------------------------------------------------
@@ -473,10 +479,127 @@ export class SolanaStakingClient implements IStakingClient {
473
479
  return Promise.resolve(0);
474
480
  }
475
481
 
476
- // Protocol fee charged for deposit from Native to LIQ
477
- getDepositFee(amount: bigint): Promise<bigint> {
478
- // TODO
479
- return Promise.resolve(BigInt(0));
482
+ // ---------------------------------------------
483
+ // Deposit fee calculation (SOL -> liqSOL)
484
+ // ---------------------------------------------
485
+
486
+ /**
487
+ * Estimate the protocol deposit fee in lamports for a given SOL amount,
488
+ * based on recent pay rates and globalConfig.depositFeeMultiplier.
489
+ *
490
+ * - amountLamports: deposit notional in lamports
491
+ * - windowSize: how many recent payRate entries to average (default 5)
492
+ *
493
+ * Returns 0n if payRateHistory or globalConfig is missing, or if
494
+ * there are no valid pay-rate entries yet.
495
+ */
496
+ async getDepositFee(
497
+ amountLamports: bigint,
498
+ windowSize = 5,
499
+ ): Promise<bigint> {
500
+ if (amountLamports <= BigInt(0)) {
501
+ return BigInt(0);
502
+ }
503
+
504
+ const [history, globalConfig] = await Promise.all([
505
+ this.distributionClient.getPayRateHistory(),
506
+ this.distributionClient.getGlobalConfig(),
507
+ ]);
508
+
509
+ if (!history || !globalConfig) {
510
+ return BigInt(0);
511
+ }
512
+
513
+ const entries = history.entries ?? [];
514
+ if (!entries.length) {
515
+ return BigInt(0);
516
+ }
517
+
518
+ const maxEntries =
519
+ typeof history.maxEntries === 'number'
520
+ ? history.maxEntries
521
+ : entries.length;
522
+
523
+ const totalEntriesAdded = new BN(
524
+ history.totalEntriesAdded.toString(),
525
+ );
526
+
527
+ const COUNT = Math.max(1, Math.min(windowSize, maxEntries, entries.length));
528
+
529
+ // ---------------------------------------------
530
+ // Walk the circular buffer from "most recent"
531
+ // back through COUNT entries, using the same
532
+ // logic as your coworker script.
533
+ // ---------------------------------------------
534
+
535
+ let avgPayRate = new BN(0);
536
+
537
+ if (COUNT > 0) {
538
+ let idx: number;
539
+
540
+ if (totalEntriesAdded.isZero()) {
541
+ // "Not wrapped yet" case
542
+ idx = 0;
543
+ } else if (history.currentIndex === 0) {
544
+ idx = maxEntries - 1;
545
+ } else {
546
+ idx = history.currentIndex - 1;
547
+ }
548
+
549
+ let sum = new BN(0);
550
+ let valid = 0;
551
+ const zero = new BN(0);
552
+
553
+ for (let i = 0; i < COUNT; i++) {
554
+ const entry: PayRateEntry | undefined = entries[idx];
555
+ if (entry) {
556
+ const rate = new BN(entry.scaledRate.toString());
557
+ if (rate.gt(zero)) {
558
+ sum = sum.add(rate);
559
+ valid += 1;
560
+ }
561
+ }
562
+
563
+ // Same wrap logic as the coworker’s script:
564
+ if (totalEntriesAdded.isZero()) {
565
+ // simple forward iteration if never wrapped
566
+ idx = (idx + 1) % maxEntries;
567
+ } else {
568
+ // walk backwards through the ring buffer
569
+ idx = idx === 0 ? maxEntries - 1 : idx - 1;
570
+ }
571
+ }
572
+
573
+ if (valid > 0) {
574
+ avgPayRate = this.ceilDiv(sum, new BN(valid));
575
+ }
576
+ }
577
+
578
+ // If no valid pay-rate entries, no fee
579
+ if (avgPayRate.isZero()) {
580
+ return BigInt(0);
581
+ }
582
+
583
+ // depositFeeMultiplier may be BN or number depending on your type
584
+ const rawMultiplier: any = (globalConfig as any).depositFeeMultiplier;
585
+ const multiplier = new BN(
586
+ rawMultiplier?.toString?.() ?? rawMultiplier ?? 0,
587
+ );
588
+ if (multiplier.isZero()) {
589
+ return BigInt(0);
590
+ }
591
+
592
+ const amountBn = new BN(amountLamports.toString());
593
+
594
+ // 10^12 scale (matches scaledRate / index scale)
595
+ const SCALE = new BN('1000000000000');
596
+
597
+ const feeBn = this.ceilDiv(
598
+ avgPayRate.mul(multiplier).mul(amountBn),
599
+ SCALE,
600
+ );
601
+
602
+ return BigInt(feeBn.toString());
480
603
  }
481
604
 
482
605
  /**
@@ -616,4 +739,12 @@ export class SolanaStakingClient implements IStakingClient {
616
739
  );
617
740
  }
618
741
  }
742
+
743
+ private ceilDiv(n: BN, d: BN): BN {
744
+ if (d.isZero()) {
745
+ throw new Error('Division by zero in ceilDiv');
746
+ }
747
+ return n.add(d.subn(1)).div(d);
748
+ }
749
+
619
750
  }
@@ -271,6 +271,135 @@ export type GlobalState = {
271
271
  bump: number;
272
272
  };
273
273
 
274
+
275
+ /**
276
+ * IDL: `globalConfig`
277
+ *
278
+ * Zero-copy global config PDA.
279
+ * Authority is taken from StakeControllerState, not stored here.
280
+ */
281
+ export type GlobalConfig = {
282
+ /** PDA bump */
283
+ bump: number;
284
+
285
+ /** 7-byte padding (unused) */
286
+ padding: number[]; // u8[7]
287
+
288
+ /** Minimum SOL amount a user can deposit (lamports, u64) */
289
+ minUserDeposit: BN;
290
+
291
+ /** Minimum SOL amount for an unstake/withdrawal request (lamports, u64) */
292
+ minUnstakeRequest: BN;
293
+
294
+ /** Minimum stake delta to trigger a stake rebalance order (lamports, u64) */
295
+ minRebalanceStakeDelta: BN;
296
+
297
+ /** Minimum unstake delta to trigger an unstake rebalance order (lamports, u64) */
298
+ minRebalanceUnstakeDelta: BN;
299
+
300
+ /** Minimum transient stake to include in effective stake calculations (lamports, u64) */
301
+ transientThreshold: BN;
302
+
303
+ /**
304
+ * Minimum slots that must have elapsed in the epoch before late epoch operations can execute (u64)
305
+ */
306
+ minLateEpochSlotGate: BN;
307
+
308
+ /** Reserved u64[2] */
309
+ reservedU64: BN[];
310
+
311
+ /**
312
+ * Epochs a validator must wait in the graveyard before it is booted.
313
+ * This begins after the last recorded state change (u16)
314
+ */
315
+ cooldownEpochs: number;
316
+
317
+ /**
318
+ * Multiplier for deposit fee calculation (u16).
319
+ * Typically: avg_pay_rate * expected_warmup_epochs
320
+ */
321
+ depositFeeMultiplier: number;
322
+
323
+ /**
324
+ * Minimum VPP score required to enter the active validator set,
325
+ * fallback when the validator set is very small (u16)
326
+ */
327
+ minVppEntry: number;
328
+
329
+ /**
330
+ * VPP score threshold below which a validator is removed from active set,
331
+ * fallback threshold (u16)
332
+ */
333
+ minVppExit: number;
334
+
335
+ /**
336
+ * Max validators for "tiny" network band (uses fixed VPP thresholds) (u16)
337
+ */
338
+ tinyNetworkThreshold: number;
339
+
340
+ /**
341
+ * Max validators for "small" network band (uses percentile-based selection) (u16)
342
+ */
343
+ smallNetworkThreshold: number;
344
+
345
+ /**
346
+ * Max validators for "medium" network band (uses percentile-based selection) (u16)
347
+ */
348
+ mediumNetworkThreshold: number;
349
+
350
+ /**
351
+ * Fixed rank threshold to enter active set in large networks (0-indexed, u16)
352
+ */
353
+ largeNetworkEntryRank: number;
354
+
355
+ /**
356
+ * Fixed rank threshold to exit active set in large networks (0-indexed, u16)
357
+ */
358
+ largeNetworkExitRank: number;
359
+
360
+ /** Reserved u16[3] */
361
+ reservedU16: number[];
362
+
363
+ /**
364
+ * Percentile rank required to enter active set in small networks (u8)
365
+ */
366
+ smallNetworkEntryPercent: number;
367
+
368
+ /**
369
+ * Percentile rank below which validators exit in small networks (u8)
370
+ */
371
+ smallNetworkExitPercent: number;
372
+
373
+ /**
374
+ * Percentile rank required to enter active set in medium networks (u8)
375
+ */
376
+ mediumNetworkEntryPercent: number;
377
+
378
+ /**
379
+ * Percentile rank below which validators exit in medium networks (u8)
380
+ */
381
+ mediumNetworkExitPercent: number;
382
+
383
+ /** Reserved u8[2] */
384
+ reservedU8: number[];
385
+
386
+ /**
387
+ * Feature flags (u16 bitfield):
388
+ * Bit 0: DepositsEnabled
389
+ * Bit 1: WithdrawalsEnabled
390
+ * Bit 2: ClaimWithdrawalsEnabled
391
+ * Bit 3: ProcessStakeOrdersEnabled
392
+ * Bit 4: ProcessUnstakeOrdersEnabled
393
+ * Bit 5: ProcessPayCycleEnabled
394
+ * Bit 6: RebalancingEnabled
395
+ * Bits 7–15: Reserved
396
+ */
397
+ featureFlags: number;
398
+
399
+ /** Reserved flags (u16[1]) */
400
+ reservedFlags: number[];
401
+ };
402
+
274
403
  /**
275
404
  * ============================================================
276
405
  * Outpost / Pretoken Accounts
package/src/types.ts CHANGED
@@ -26,7 +26,11 @@ export interface IStakingClient {
26
26
  // Estimated total APY for staking yeild
27
27
  getSystemAPY(): Promise<number>;
28
28
 
29
- // Protocol fee charged for deposit from Native to LIQ
29
+ /**
30
+ * Protocol fee charged for deposit from Native to LIQ
31
+ * in Solana: amount in lamports
32
+ * in Ethereum: amount in wei
33
+ */
30
34
  getDepositFee(amount: bigint): Promise<bigint>;
31
35
 
32
36
  /**
@@ -41,6 +45,12 @@ export interface IStakingClient {
41
45
  windowBefore?: number;
42
46
  windowAfter?: number;
43
47
  }): Promise<TrancheSnapshot | null>;
48
+
49
+ // Estimated total APY for staking yeild
50
+ getSystemAPY(): Promise<number>;
51
+
52
+ // Protocol fee charged for deposit from Native to LIQ
53
+ getDepositFee(amount: bigint): Promise<bigint>;
44
54
  }
45
55
 
46
56
  /**
@@ -112,9 +122,9 @@ export interface BalanceView {
112
122
  }
113
123
 
114
124
  /**
115
- * SOL / Outpost yield view.
125
+ * Outpost yield view.
116
126
  *
117
- * All amounts are integers in base units (lamports for liqSOL).
127
+ * All amounts are integers in base units (lamports for liqSOL, wei for liqETH).
118
128
  *
119
129
  * Math matches capital-staking:
120
130
  * INDEX_SCALE = 1e12
@@ -141,20 +151,20 @@ export interface YieldView {
141
151
  userShares: bigint;
142
152
 
143
153
  /**
144
- * Total liqSOL (lamports) the user could claim right now if they fully
154
+ * Total liq (wei/lamports) the user could claim right now if they fully
145
155
  * unwound their stake:
146
- * estimatedClaimLiqsol = userShares * currentIndex / indexScale
156
+ * estimatedClaim = userShares * currentIndex / indexScale
147
157
  */
148
- estimatedClaimLiqsol: bigint;
158
+ estimatedClaim?: bigint;
149
159
 
150
160
  /**
151
- * Portion of estimatedClaimLiqsol that is “yield” above principal:
152
- * estimatedYieldLiqsol = max(0, estimatedClaimLiqsol - stakedLiqsol)
161
+ * Portion of estimatedClaim that is “yield” above principal:
162
+ * estimatedYield = max(0, estimatedClaim - staked)
153
163
  *
154
- * NOTE: stakedLiqsol principal itself is surfaced separately as
164
+ * NOTE: staked principal itself is surfaced separately as
155
165
  * Portfolio.staked.amount.
156
166
  */
157
- estimatedYieldLiqsol: bigint;
167
+ estimatedYield?: bigint;
158
168
  }
159
169
 
160
170
  export interface TrancheLadderItem {
@@ -204,7 +214,7 @@ export interface TrancheSnapshot {
204
214
  /** Tranche curve config (per-chain) */
205
215
  // TODO make a constant?
206
216
  supplyGrowthBps: number; // e.g. 100 = +1% per tranche
207
- priceGrowthBps: number; // e.g. 200 = +2% per tranche
217
+ priceIncrementUsd: number; // e.g. 200 = +2% per tranche
208
218
 
209
219
  totalPretokensSold: bigint; // total pretokens sold across all tranches (1e8 scale)
210
220
 
@@ -1,4 +0,0 @@
1
- {
2
- "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/b5e46b2b97b85c57c7cd2a26cf972153.json"
4
- }
@@ -1,10 +0,0 @@
1
- {
2
- "_format": "hh-sol-artifact-1",
3
- "contractName": "BeaconRoots",
4
- "sourceName": "contracts/liqEth/ValidatorBalanceVerifier.sol",
5
- "abi": [],
6
- "bytecode": "0x60808060405234601757603a9081601d823930815050f35b600080fdfe600080fdfea26469706673582212205929e6d47abd57360b3b4a693fd02ffc914ee421946709f79543eb45d9d83cf464736f6c63430008190033",
7
- "deployedBytecode": "0x600080fdfea26469706673582212205929e6d47abd57360b3b4a693fd02ffc914ee421946709f79543eb45d9d83cf464736f6c63430008190033",
8
- "linkReferences": {},
9
- "deployedLinkReferences": {}
10
- }
@@ -1,4 +0,0 @@
1
- {
2
- "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/b5e46b2b97b85c57c7cd2a26cf972153.json"
4
- }