@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.
- package/README.md +57 -0
- package/lib/stake.browser.js +11836 -4103
- package/lib/stake.browser.js.map +1 -1
- package/lib/stake.d.ts +374 -556
- package/lib/stake.js +12089 -4303
- package/lib/stake.js.map +1 -1
- package/lib/stake.m.js +11836 -4103
- package/lib/stake.m.js.map +1 -1
- package/package.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/DepositManager.sol/DepositManager.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/DepositManager.sol/DepositManager.json +1153 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IAccounting.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IAccounting.json +172 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IDepositContract.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IDepositContract.json +39 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IDepositManager.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IDepositManager.json +64 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/ILiqEthBurn.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/ILiqEthBurn.json +24 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/ILiqEthMint.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/ILiqEthMint.json +35 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IRewardsERC20.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IRewardsERC20.json +213 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IStakingModule.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IStakingModule.json +138 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IValidatorBalanceVerifier.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IValidatorBalanceVerifier.json +70 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IWithdrawalRecord.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IWithdrawalRecord.json +64 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/LiqEthCommon.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/LiqEthCommon.json +10 -0
- package/src/assets/ethereum/ABI/liqEth/RewardsERC20.sol/RewardsERC20.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/RewardsERC20.sol/RewardsERC20.json +749 -0
- package/src/assets/ethereum/ABI/liqEth/RewardsERC20Pausable.sol/RewardsERC20Pausable.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/RewardsERC20Pausable.sol/RewardsERC20Pausable.json +812 -0
- package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/BeaconRoots.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/BeaconRoots.json +10 -0
- package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/SSZ.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/SSZ.json +10 -0
- package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/ValidatorBalanceVerifier.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/ValidatorBalanceVerifier.json +225 -0
- package/src/assets/ethereum/ABI/liqEth/Yield.sol/BeaconRoots.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/Yield.sol/BeaconRoots.json +10 -0
- package/src/assets/ethereum/ABI/liqEth/Yield.sol/SSZ.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/Yield.sol/SSZ.json +10 -0
- package/src/assets/ethereum/ABI/liqEth/Yield.sol/YieldOracle.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/Yield.sol/YieldOracle.json +813 -0
- package/src/assets/ethereum/ABI/liqEth/accounting.sol/Accounting.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/accounting.sol/Accounting.json +651 -0
- package/src/assets/ethereum/ABI/liqEth/liqEth.sol/LiqEthToken.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/liqEth.sol/LiqEthToken.json +1110 -0
- package/src/assets/ethereum/ABI/liqEth/liqEthBurn.sol/LiqEthBurn.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/liqEthBurn.sol/LiqEthBurn.json +391 -0
- package/src/assets/ethereum/ABI/liqEth/liqEthMint.sol/LiqEthMint.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/liqEthMint.sol/LiqEthMint.json +402 -0
- package/src/assets/ethereum/ABI/liqEth/stakingModule.sol/StakingModule.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/stakingModule.sol/StakingModule.json +1225 -0
- package/src/assets/ethereum/ABI/liqEth/withdrawalQueue.sol/WithdrawalQueue.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/withdrawalQueue.sol/WithdrawalQueue.json +927 -0
- package/src/assets/ethereum/ABI/liqEth/withdrawalVault.sol/Uint64BE.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/withdrawalVault.sol/Uint64BE.json +10 -0
- package/src/assets/ethereum/ABI/liqEth/withdrawalVault.sol/WithdrawalVault.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/withdrawalVault.sol/WithdrawalVault.json +447 -0
- package/src/assets/solana/idl/liqsol_core.json +4239 -0
- package/src/assets/solana/idl/liqsol_token.json +183 -0
- package/src/assets/solana/idl/validator_leaderboard.json +270 -265
- package/src/assets/solana/types/liqsol_core.ts +4245 -0
- package/src/assets/solana/types/liqsol_token.ts +189 -0
- package/src/assets/solana/types/validator_leaderboard.ts +270 -265
- package/src/index.ts +1 -3
- package/src/networks/ethereum/contract.ts +101 -36
- package/src/networks/ethereum/ethereum.ts +141 -45
- package/src/networks/ethereum/types.ts +30 -2
- package/src/networks/solana/clients/deposit.client.ts +71 -109
- package/src/networks/solana/clients/distribution.client.ts +256 -383
- package/src/networks/solana/clients/leaderboard.client.ts +38 -133
- package/src/networks/solana/constants.ts +214 -130
- package/src/networks/solana/program.ts +25 -38
- package/src/networks/solana/solana.ts +120 -105
- package/src/networks/solana/types.ts +37 -47
- package/src/networks/solana/utils.ts +551 -0
- package/src/scripts/tsconfig.json +17 -0
- package/src/staker/staker.ts +10 -6
- package/src/staker/types.ts +14 -9
- package/src/assets/solana/idl/deposit.json +0 -296
- package/src/assets/solana/idl/distribution.json +0 -768
- package/src/assets/solana/idl/liq_sol_token.json +0 -298
- package/src/assets/solana/idl/mint_helper.json +0 -110
- package/src/assets/solana/idl/read_tracked_balance.json +0 -140
- package/src/assets/solana/idl/stake_controller.json +0 -2149
- package/src/assets/solana/idl/treasury.json +0 -110
- package/src/assets/solana/idl/validator_registry.json +0 -487
- package/src/assets/solana/idl/yield_oracle.json +0 -32
- package/src/assets/solana/types/deposit.ts +0 -302
- package/src/assets/solana/types/distribution.ts +0 -774
- package/src/assets/solana/types/liq_sol_token.ts +0 -304
- package/src/assets/solana/types/mint_helper.ts +0 -116
- package/src/assets/solana/types/read_tracked_balance.ts +0 -146
- package/src/assets/solana/types/stake_controller.ts +0 -2155
- package/src/assets/solana/types/stake_registry.ts +0 -441
- package/src/assets/solana/types/treasury.ts +0 -116
- package/src/assets/solana/types/validator_registry.ts +0 -493
- package/src/assets/solana/types/yield_oracle.ts +0 -38
- 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 {
|
|
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 {
|
|
17
|
-
|
|
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
|
-
|
|
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)
|
|
40
|
-
|
|
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(
|
|
52
|
+
throw new Error("Passed-in pubKey doesn't match adapter.publicKey");
|
|
47
53
|
}
|
|
48
54
|
|
|
49
|
-
|
|
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
|
-
|
|
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
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
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()
|
|
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
|
|
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
|
|
175
|
-
delta: c.delta
|
|
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
|
|
237
|
+
return this.anchor.wallet.signTransaction(tx);
|
|
225
238
|
}
|
|
226
239
|
|
|
227
240
|
async sendTransaction(signed: SolanaTransaction): Promise<TransactionSignature> {
|
|
228
|
-
return
|
|
241
|
+
return this.anchor.sendAndConfirm(signed);
|
|
229
242
|
}
|
|
230
243
|
|
|
231
|
-
async prepareTx(
|
|
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
|
-
|
|
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
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
-
|
|
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
|
-
|
|
32
|
-
|
|
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
|
-
|
|
41
|
-
|
|
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
|
+
}
|