@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
@@ -1,20 +1,27 @@
1
1
  import {
2
- Connection,
3
- PublicKey as SolPubKey,
4
- TransactionSignature,
5
2
  Commitment,
3
+ Connection,
6
4
  ConnectionConfig,
5
+ PublicKey as SolPubKey,
7
6
  Transaction,
7
+ TransactionSignature,
8
8
  } from '@solana/web3.js';
9
9
  import { AnchorProvider } from '@coral-xyz/anchor';
10
10
  import { BaseSignerWalletAdapter } from '@solana/wallet-adapter-base';
11
- import { IStakingClient, Portfolio, StakerConfig } from '../../staker/types';
11
+ import { getAssociatedTokenAddressSync, TOKEN_2022_PROGRAM_ID } from '@solana/spl-token';
12
+
12
13
  import { ChainID, ExternalNetwork, KeyType, PublicKey } from '@wireio/core';
14
+ import { IStakingClient, Portfolio, StakerConfig } from '../../staker/types';
15
+
13
16
  import { DepositClient } from './clients/deposit.client';
14
- import { deriveStakeControllerReservePoolPDA, deriveStakeControllerVaultPDA, getUserLiqsolATA } from './constants';
15
17
  import { DistributionClient } from './clients/distribution.client';
16
- import { SolanaTransaction } from './types';
17
- // import { ValidatorLeaderboardClient } from './clients/leaderboard.client';
18
+ import {
19
+ deriveLiqsolMintPda,
20
+ deriveReservePoolPda,
21
+ deriveVaultPda,
22
+ } from './constants';
23
+ import { SolanaTransaction, UserRecord } from './types';
24
+ import { LeaderboardClient } from './clients/leaderboard.client';
18
25
 
19
26
  const commitment: Commitment = 'confirmed';
20
27
 
@@ -25,29 +32,27 @@ export class SolanaStakingClient implements IStakingClient {
25
32
 
26
33
  private depositClient: DepositClient;
27
34
  private distributionClient: DistributionClient;
28
- // private leaderboardClient: ValidatorLeaderboardClient;
29
-
30
- get solPubKey(): SolPubKey {
31
- return new SolPubKey(this.pubKey.data.array);
32
- }
35
+ private leaderboardClient: LeaderboardClient;
33
36
 
37
+ get solPubKey(): SolPubKey { return new SolPubKey(this.pubKey.data.array); }
34
38
  get network() { return this.config.network; }
35
39
 
36
40
  constructor(private config: StakerConfig) {
37
- // 1) unwrap & validate wallet adapter
38
41
  const adapter = config.provider as BaseSignerWalletAdapter;
39
- if (!adapter.publicKey) throw new Error('Solana wallet adapter not connected');
40
- if (!config.network.rpcUrls.length) throw new Error('No RPC URLs provided');
42
+ if (!adapter.publicKey) {
43
+ throw new Error('Solana wallet adapter not connected');
44
+ }
45
+ if (!config.network.rpcUrls.length) {
46
+ throw new Error('No RPC URLs provided');
47
+ }
41
48
 
42
- // 2) sanity‐check wire ↔ solana pubkey
43
49
  const publicKey = adapter.publicKey;
44
50
  const wirePub = new PublicKey(KeyType.ED, publicKey.toBytes());
45
51
  if (!wirePub.equals(config.pubKey)) {
46
- throw new Error('Passed-in pubKey doesn\'t match adapter.publicKey');
52
+ throw new Error("Passed-in pubKey doesn't match adapter.publicKey");
47
53
  }
48
54
 
49
- // build connection config
50
- let opts: ConnectionConfig = { commitment }
55
+ const opts: ConnectionConfig = { commitment };
51
56
  if (config.network.rpcUrls.length > 1 && config.network.rpcUrls[1].startsWith('ws')) {
52
57
  opts.wsEndpoint = config.network.rpcUrls[1];
53
58
  }
@@ -67,10 +72,9 @@ export class SolanaStakingClient implements IStakingClient {
67
72
 
68
73
  this.anchor = new AnchorProvider(this.connection, anchorWallet, { commitment });
69
74
 
70
- // 4) staking clients
71
75
  this.depositClient = new DepositClient(this.anchor);
72
76
  this.distributionClient = new DistributionClient(this.anchor);
73
- // this.leaderboardClient = new ValidatorLeaderboardClient(this.anchor);
77
+ this.leaderboardClient = new LeaderboardClient(this.anchor);
74
78
  }
75
79
 
76
80
  /**
@@ -80,67 +84,96 @@ export class SolanaStakingClient implements IStakingClient {
80
84
  * tracked = liqSOL tracked balance (from Distribution.userRecord)
81
85
  */
82
86
  async getPortfolio(): Promise<Portfolio> {
83
- const user = this.solPubKey;
84
-
85
- // Handy PDAs & ATA
86
- const [reservePoolPDA] = deriveStakeControllerReservePoolPDA();
87
- const [vaultPDA] = deriveStakeControllerVaultPDA();
88
- const userLiqsolAta = getUserLiqsolATA(user);
89
-
90
- // Pull balances in parallel; ATA may not exist yet
91
- const [nativeLamports, actualBalResp, userRecord] = await Promise.all([
92
- this.connection.getBalance(user),
93
- this.connection.getTokenAccountBalance(userLiqsolAta).catch(() => null),
94
- this.distributionClient.getUserRecord(user).catch(() => null),
95
- ]);
96
-
97
- // Actual (LiqSOL) balance + decimals (fallback to 9 if ATA missing)
98
- const actualAmountStr = actualBalResp?.value?.amount ?? '0';
99
- const actualDecimals = actualBalResp?.value?.decimals ?? 9;
100
-
101
- // Tracked (from userRecord in Distribution program)
102
- const trackedAmountStr = userRecord?.trackedBalance
103
- ? (userRecord.trackedBalance as any).toString()
104
- : '0';
105
- const trackedDecimals = actualDecimals; // same mint as liqSOL
106
-
107
- // Assemble the portfolio
108
- const portfolio: Portfolio = {
109
- native: {
110
- symbol: 'SOL',
111
- decimals: 9,
112
- amount: BigInt(nativeLamports),
113
- },
114
- actual: {
115
- symbol: 'LiqSOL',
116
- decimals: actualDecimals,
117
- amount: BigInt(actualAmountStr),
118
- },
119
- tracked: {
120
- symbol: 'LiqSOL',
121
- decimals: trackedDecimals,
122
- amount: BigInt(trackedAmountStr),
123
- },
124
- extras: {
125
- userLiqsolAta: userLiqsolAta.toBase58(),
126
- reservePoolPDA: reservePoolPDA.toBase58(),
127
- vaultPDA: vaultPDA.toBase58(),
128
- },
129
- };
130
-
131
- // console.log('>> PORTFOLIO SET', this.network.name, this.portfolio);
132
- return portfolio;
87
+ try {
88
+ const user = this.solPubKey;
89
+ const reservePoolPDA = deriveReservePoolPda();
90
+ const vaultPDA = deriveVaultPda();
91
+ const liqsolMint = deriveLiqsolMintPda();
92
+ const userLiqsolAta = getAssociatedTokenAddressSync(
93
+ liqsolMint,
94
+ user,
95
+ false,
96
+ TOKEN_2022_PROGRAM_ID,
97
+ );
98
+
99
+ // Fetch balances and user record in parallel
100
+ const [nativeLamports, actualBalResp, userRecord] = await Promise.all([
101
+ this.connection.getBalance(user),
102
+ this.connection.getTokenAccountBalance(userLiqsolAta).catch(() => null),
103
+ this.distributionClient.getUserRecord(user).catch(() => null),
104
+ ]);
105
+
106
+ const actualAmountStr = actualBalResp?.value?.amount ?? '0';
107
+ const actualDecimals = actualBalResp?.value?.decimals ?? 9;
108
+
109
+ const trackedAmountStr = userRecord?.trackedBalance ? userRecord.trackedBalance.toString() : '0';
110
+ const trackedDecimals = actualDecimals;
111
+
112
+ const nativeSymbol = 'SOL';
113
+ const liqSymbol = 'LiqSOL';
114
+
115
+ const portfolio: Portfolio = {
116
+ native: {
117
+ amount: BigInt(nativeLamports),
118
+ symbol: nativeSymbol,
119
+ decimals: 9,
120
+ },
121
+ liq: {
122
+ amount: BigInt(actualAmountStr),
123
+ symbol: liqSymbol,
124
+ decimals: actualDecimals,
125
+ },
126
+ staked: { // TODO: fetch staked balance from outpost
127
+ amount: BigInt(0),
128
+ symbol: liqSymbol,
129
+ decimals: actualDecimals,
130
+ },
131
+ tracked: { // SOL ONLY
132
+ amount: BigInt(trackedAmountStr),
133
+ symbol: liqSymbol,
134
+ decimals: trackedDecimals,
135
+ },
136
+ extras: {
137
+ userLiqsolAta: userLiqsolAta.toBase58(),
138
+ reservePoolPDA: reservePoolPDA.toBase58(),
139
+ vaultPDA: vaultPDA.toBase58(),
140
+ },
141
+ chainID: this.network.chainId
142
+ };
143
+
144
+ // console.log('SOL PORTFOLIO', portfolio);
145
+ return portfolio;
146
+ }
147
+ catch (error) {
148
+ console.log('Error in getPortfolio:', error);
149
+ throw error;
150
+ }
133
151
  }
152
+
134
153
  /**
135
154
  * Optional: fetch your Distribution program user record
136
155
  * (often contains per-user deposit/claim state).
156
+ * @returns UserRecord or null
137
157
  */
138
- async getUserRecord(): Promise<any | null> {
158
+ async getUserRecord() {
139
159
  return this.distributionClient.getUserRecord(this.solPubKey);
140
160
  }
141
161
 
142
162
  getProtocolFee() {
163
+ // TODO: wire to pay-rate math once we finalize protocol fee API
164
+ }
143
165
 
166
+ /**
167
+ * Deposit funds into the staking pool.
168
+ * @param lamports The amount to deposit (in lamports).
169
+ * @returns The transaction signature.
170
+ */
171
+ async deposit(lamports: number): Promise<string> {
172
+ const { transaction } = await this.depositClient.buildDepositTx(this.solPubKey, lamports);
173
+ const { tx, blockhash, lastValidBlockHeight } = await this.prepareTx(transaction);
174
+ const signed = await this.signTransaction(tx);
175
+ const result = await this.sendAndConfirmHttp(signed, { blockhash, lastValidBlockHeight });
176
+ return result.signature;
144
177
  }
145
178
 
146
179
  /**
@@ -151,29 +184,24 @@ export class SolanaStakingClient implements IStakingClient {
151
184
  * @param amount Optional: register a smaller amount than your full untracked balance.
152
185
  * @returns signature string
153
186
  */
154
- async register(amount?: bigint): Promise<string> {
187
+ async correctBalance(amount?: bigint): Promise<string> {
155
188
  try {
156
- console.log('Building CorrectAndRegister transaction with amount:', amount);
157
-
158
- // Build the transaction using the Distribution client (self = this.solPubKey)
159
189
  const build = await this.distributionClient.buildCorrectRegisterTx({ amount });
160
- if (!build.canSucceed || !build.transaction)
190
+ if (!build.canSucceed || !build.transaction) {
161
191
  throw new Error(build.reason ?? 'Unable to build Correct&Register transaction');
162
-
163
- console.log('buildCorrectRegisterTx:', build);
192
+ }
164
193
 
165
194
  const { tx, blockhash, lastValidBlockHeight } = await this.prepareTx(build.transaction);
166
195
  const signed = await this.signTransaction(tx);
167
196
  const result = await this.sendAndConfirmHttp(signed, { blockhash, lastValidBlockHeight });
168
197
 
169
- // Optionally refresh portfolio after success (non-blocking)
170
198
  console.log('Registered:', {
171
199
  needToRegister: build.needToRegister,
172
200
  freed: build.plan.willFree,
173
- corrected: build.plan.selected.map(c => ({
174
- owner: c.owner.toBase58(),
175
- delta: c.delta.toString(),
176
- }))
201
+ corrected: build.plan.selected.map((c) => ({
202
+ owner: c.owner?.toBase58(),
203
+ delta: c.delta?.toString(),
204
+ })),
177
205
  });
178
206
 
179
207
  return result.signature;
@@ -183,34 +211,19 @@ export class SolanaStakingClient implements IStakingClient {
183
211
  }
184
212
  }
185
213
 
186
- /**
187
- * Deposit funds into the staking pool.
188
- * @param lamports The amount to deposit (in lamports).
189
- * @returns The transaction signature.
190
- */
191
- async deposit(lamports: number): Promise<string> {
192
- const { transaction } = await this.depositClient.buildDepositTx(this.solPubKey, lamports);
193
- const { tx, blockhash, lastValidBlockHeight } = await this.prepareTx(transaction);
194
- const signed = await this.signTransaction(tx);
195
- const result = await this.sendAndConfirmHttp(signed, { blockhash, lastValidBlockHeight });
196
- return result.signature;
197
- }
198
-
199
214
  private async sendAndConfirmHttp(
200
215
  signed: SolanaTransaction,
201
- ctx: { blockhash: string; lastValidBlockHeight: number }
216
+ ctx: { blockhash: string; lastValidBlockHeight: number },
202
217
  ): Promise<TxResult> {
203
- // sendRawTransaction is HTTP
204
218
  const signature = await this.connection.sendRawTransaction(signed.serialize(), {
205
219
  skipPreflight: false,
206
220
  preflightCommitment: commitment,
207
221
  maxRetries: 3,
208
222
  });
209
223
 
210
- // Poll confirmation using blockhash/lastValidBlockHeight
211
224
  const conf = await this.connection.confirmTransaction(
212
225
  { signature, blockhash: ctx.blockhash, lastValidBlockHeight: ctx.lastValidBlockHeight },
213
- commitment
226
+ commitment,
214
227
  );
215
228
 
216
229
  const ok = !conf.value.err;
@@ -221,14 +234,16 @@ export class SolanaStakingClient implements IStakingClient {
221
234
  }
222
235
 
223
236
  async signTransaction(tx: SolanaTransaction): Promise<SolanaTransaction> {
224
- return await this.anchor.wallet.signTransaction(tx);
237
+ return this.anchor.wallet.signTransaction(tx);
225
238
  }
226
239
 
227
240
  async sendTransaction(signed: SolanaTransaction): Promise<TransactionSignature> {
228
- return await this.anchor.sendAndConfirm(signed);
241
+ return this.anchor.sendAndConfirm(signed);
229
242
  }
230
243
 
231
- async prepareTx(tx: Transaction): Promise<{ tx: Transaction; blockhash: string; lastValidBlockHeight: number }> {
244
+ async prepareTx(
245
+ tx: Transaction,
246
+ ): Promise<{ tx: Transaction; blockhash: string; lastValidBlockHeight: number }> {
232
247
  const { blockhash, lastValidBlockHeight } = await this.connection.getLatestBlockhash('confirmed');
233
248
  tx.recentBlockhash = blockhash;
234
249
  tx.feePayer = this.solPubKey;
@@ -241,4 +256,4 @@ export interface TxResult {
241
256
  signature: string;
242
257
  slot: number;
243
258
  confirmed: boolean;
244
- };
259
+ }
@@ -1,57 +1,47 @@
1
- import { PublicKey, Transaction, VersionedTransaction } from "@solana/web3.js";
1
+ import { PublicKey, StakeActivationData, TokenAmount, Transaction, VersionedTransaction } from "@solana/web3.js";
2
2
 
3
3
  export type SolanaTransaction = Transaction | VersionedTransaction
4
4
 
5
- /** Raw mismatch row (per user with a userRecord) */
6
- export type MismatchCandidate = {
7
- /** Wallet that owns the ATA (decoded from token account) */
8
- owner: PublicKey;
9
- /** user_record PDA */
10
- userRecordPda: PublicKey;
11
- /** user’s ATA for liqSOL */
5
+ export type UserRecord = {
12
6
  userAta: PublicKey;
13
- /** protocol tracked balance (u64) */
14
- tracked: bigint;
15
- /** actual on-chain token balance (u64) */
16
- actual: bigint;
17
- /** tracked - actual (positive means “freeable”) */
18
- delta: bigint;
7
+ trackedBalance: bigint; // What we think they have (for reward calculations)
8
+ claimBalance: bigint; // Accumulated unclaimed rewards
9
+ lastClaimTimestamp: bigint; // When they last claimed (unix timestamp)
10
+ bump: number;
11
+ }
12
+
13
+ export type DistributionState = {
14
+ liqsolMint: PublicKey;
15
+ availableBalance: bigint;
16
+ totalTrackedBalance: bigint;
17
+ bump: number;
18
+ }
19
+
20
+ export type ParsedAccountInfo = {
21
+ extensions: Array<{ extension: string }>;
22
+ isNative: boolean;
23
+ mint: string;
24
+ owner: string;
25
+ state: string;
26
+ tokenAmount: TokenAmount
19
27
  };
28
+ export interface MismatchCandidate {
29
+ owner: PublicKey;
30
+ actual: bigint;
31
+ tracked: bigint;
32
+ delta: bigint; // tracked - actual
33
+ }
20
34
 
21
- /** Output when choosing candidates to free liquidity */
22
- export type CorrectionPlan = {
23
- /** selected candidates sorted by delta desc */
24
- selected: MismatchCandidate[];
25
- /** total delta we’ll free by correcting selected */
26
- willFree: bigint;
27
- /** how much still missing after selection (0 if we can meet the target) */
35
+ export interface CorrectRegisterPlan {
28
36
  deficit: bigint;
29
- };
37
+ willFree: bigint;
38
+ selected: MismatchCandidate[];
39
+ }
30
40
 
31
- /** What the builder returns to your caller/UI */
32
- export type CorrectAndRegisterBuild = {
33
- /** The ready-to-send transaction (if buildable) */
34
- transaction?: Transaction;
35
- /** True if the tx can succeed with current state */
41
+ export interface CorrectRegisterBuildResult {
42
+ needToRegister: boolean;
36
43
  canSucceed: boolean;
37
- /** Explanation if not buildable */
38
44
  reason?: string;
39
-
40
- /** Current liqSOL mint; useful for UI */
41
- liqsolMint: PublicKey;
42
- /** Amount you need to register (actual - tracked if positive) */
43
- needToRegister: bigint;
44
- /** Distribution “availableBalance” before this action */
45
- availableBefore: bigint;
46
-
47
- /** Candidates we scanned (already sorted by delta desc) */
48
- candidates: MismatchCandidate[];
49
- /** Subset we’d correct (maybe empty) */
50
- plan: CorrectionPlan;
51
-
52
- /** Convenience for caller */
53
- accounts: {
54
- selfUserRecordPda: PublicKey;
55
- selfUserAta: PublicKey;
56
- };
57
- };
45
+ transaction?: Transaction;
46
+ plan: CorrectRegisterPlan;
47
+ }