@wireio/stake 2.1.1 → 2.2.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/lib/stake.browser.js +188 -227
- package/lib/stake.browser.js.map +1 -1
- package/lib/stake.d.ts +52 -52
- package/lib/stake.js +315 -331
- package/lib/stake.js.map +1 -1
- package/lib/stake.m.js +188 -227
- package/lib/stake.m.js.map +1 -1
- package/package.json +1 -1
- package/src/networks/ethereum/clients/validator.client.ts +61 -0
- package/src/networks/ethereum/ethereum.ts +20 -0
- package/src/networks/ethereum/types.ts +9 -2
- package/src/networks/solana/clients/deposit.client.ts +2 -229
- package/src/networks/solana/clients/outpost.client.ts +4 -5
- package/src/networks/solana/clients/token.client.ts +2 -0
- package/src/networks/solana/constants.ts +3 -0
- package/src/networks/solana/solana.ts +265 -317
- package/src/networks/solana/utils.ts +1 -1
- package/src/types.ts +2 -0
package/lib/stake.browser.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SolChainID, PublicKey as PublicKey$1, KeyType, EvmChainID } from '@wireio/core';
|
|
2
|
-
import { SystemProgram, StakeProgram, SYSVAR_INSTRUCTIONS_PUBKEY, SYSVAR_CLOCK_PUBKEY, SYSVAR_STAKE_HISTORY_PUBKEY, SYSVAR_RENT_PUBKEY,
|
|
2
|
+
import { SystemProgram, StakeProgram, SYSVAR_INSTRUCTIONS_PUBKEY, SYSVAR_CLOCK_PUBKEY, SYSVAR_STAKE_HISTORY_PUBKEY, SYSVAR_RENT_PUBKEY, PublicKey, Keypair, Connection, ComputeBudgetProgram, TransactionMessage, Transaction, SendTransactionError } from '@solana/web3.js';
|
|
3
3
|
import { BN, Program, AnchorProvider } from '@coral-xyz/anchor';
|
|
4
|
-
import { getAssociatedTokenAddressSync, TOKEN_2022_PROGRAM_ID, ASSOCIATED_TOKEN_PROGRAM_ID, getAssociatedTokenAddress
|
|
4
|
+
import { getAssociatedTokenAddressSync, TOKEN_2022_PROGRAM_ID, ASSOCIATED_TOKEN_PROGRAM_ID, getAssociatedTokenAddress } from '@solana/spl-token';
|
|
5
5
|
import * as multisig from '@sqds/multisig';
|
|
6
6
|
import bs58 from 'bs58';
|
|
7
7
|
import { ethers, Contract, BigNumber } from 'ethers';
|
|
@@ -141,7 +141,7 @@ class DepositClient {
|
|
|
141
141
|
true,
|
|
142
142
|
TOKEN_2022_PROGRAM_ID
|
|
143
143
|
);
|
|
144
|
-
|
|
144
|
+
return await this.program.methods.requestWithdraw(new BN(amount.toString())).accounts({
|
|
145
145
|
user,
|
|
146
146
|
owner,
|
|
147
147
|
global,
|
|
@@ -167,69 +167,6 @@ class DepositClient {
|
|
|
167
167
|
rent: SYSVAR_RENT_PUBKEY,
|
|
168
168
|
globalConfig
|
|
169
169
|
}).instruction();
|
|
170
|
-
return new Transaction().add(ix);
|
|
171
|
-
}
|
|
172
|
-
async buildDepositIxForUser(amount, user) {
|
|
173
|
-
if (!user) {
|
|
174
|
-
throw new Error("buildDepositIxForUser: user is required");
|
|
175
|
-
}
|
|
176
|
-
if (!amount || amount <= BigInt(0)) {
|
|
177
|
-
throw new Error("buildDepositIxForUser: amount must be > 0");
|
|
178
|
-
}
|
|
179
|
-
const depositAuthority = this.pgs.deriveDepositAuthorityPda();
|
|
180
|
-
const liqsolMint = this.pgs.deriveLiqsolMintPda();
|
|
181
|
-
const liqsolMintAuthority = this.pgs.deriveLiqsolMintAuthorityPda();
|
|
182
|
-
const reservePool = this.pgs.deriveReservePoolPda();
|
|
183
|
-
const vault = this.pgs.deriveVaultPda();
|
|
184
|
-
const controllerState = this.pgs.deriveStakeControllerStatePda();
|
|
185
|
-
const payoutState = this.pgs.derivePayoutStatePda();
|
|
186
|
-
const bucketAuthority = this.pgs.deriveBucketAuthorityPda();
|
|
187
|
-
const payRateHistory = this.pgs.derivePayRateHistoryPda();
|
|
188
|
-
const globalConfig = this.pgs.deriveGlobalConfigPda();
|
|
189
|
-
const userAta = getAssociatedTokenAddressSync(
|
|
190
|
-
liqsolMint,
|
|
191
|
-
user,
|
|
192
|
-
true,
|
|
193
|
-
TOKEN_2022_PROGRAM_ID
|
|
194
|
-
);
|
|
195
|
-
const distributionState = this.pgs.deriveDistributionStatePda();
|
|
196
|
-
const userRecord = this.pgs.deriveUserRecordPda(userAta);
|
|
197
|
-
const bucketTokenAccount = getAssociatedTokenAddressSync(
|
|
198
|
-
liqsolMint,
|
|
199
|
-
bucketAuthority,
|
|
200
|
-
true,
|
|
201
|
-
TOKEN_2022_PROGRAM_ID
|
|
202
|
-
);
|
|
203
|
-
const seed = Math.floor(Math.random() * 2 ** 32);
|
|
204
|
-
const ephemeralStake = await this.pgs.deriveEphemeralStakeAddress(user, seed);
|
|
205
|
-
const ix = await this.program.methods.deposit(new BN(amount.toString()), seed).accounts({
|
|
206
|
-
user,
|
|
207
|
-
depositAuthority,
|
|
208
|
-
systemProgram: SystemProgram.programId,
|
|
209
|
-
tokenProgram: TOKEN_2022_PROGRAM_ID,
|
|
210
|
-
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
211
|
-
liqsolProgram: this.pgs.PROGRAM_IDS.LIQSOL_TOKEN,
|
|
212
|
-
stakeProgram: StakeProgram.programId,
|
|
213
|
-
liqsolMint,
|
|
214
|
-
userAta,
|
|
215
|
-
liqsolMintAuthority,
|
|
216
|
-
reservePool,
|
|
217
|
-
vault,
|
|
218
|
-
ephemeralStake,
|
|
219
|
-
controllerState,
|
|
220
|
-
payoutState,
|
|
221
|
-
bucketAuthority,
|
|
222
|
-
bucketTokenAccount,
|
|
223
|
-
userRecord,
|
|
224
|
-
distributionState,
|
|
225
|
-
payRateHistory,
|
|
226
|
-
instructionsSysvar: SYSVAR_INSTRUCTIONS_PUBKEY,
|
|
227
|
-
clock: SYSVAR_CLOCK_PUBKEY,
|
|
228
|
-
stakeHistory: SYSVAR_STAKE_HISTORY_PUBKEY,
|
|
229
|
-
rent: SYSVAR_RENT_PUBKEY,
|
|
230
|
-
globalConfig
|
|
231
|
-
}).instruction();
|
|
232
|
-
return { ix, seed, userAta, ephemeralStake };
|
|
233
170
|
}
|
|
234
171
|
}
|
|
235
172
|
|
|
@@ -14659,13 +14596,15 @@ const MAINNET_PROGRAM_IDS = {
|
|
|
14659
14596
|
LIQSOL_CORE: new PublicKey(liqsolCoreMainnetJson.address),
|
|
14660
14597
|
LIQSOL_TOKEN: new PublicKey(liqsolTokenMainnetJson.address),
|
|
14661
14598
|
VALIDATOR_LEADERBOARD: new PublicKey(validatorLeaderboardMainnetJson.address),
|
|
14662
|
-
TRANSFER_HOOK: new PublicKey(mainnetTransferHookIDL.address)
|
|
14599
|
+
TRANSFER_HOOK: new PublicKey(mainnetTransferHookIDL.address),
|
|
14600
|
+
ALT_LOOKUP_TABLE: new PublicKey("AQXTHwkdNBEiXeQuVA5uCoxvzgYUmudRxthQY4vWKCPS")
|
|
14663
14601
|
};
|
|
14664
14602
|
const DEVNET_PROGRAM_IDS = {
|
|
14665
14603
|
LIQSOL_CORE: new PublicKey(liqsolCoreDevnetJson.address),
|
|
14666
14604
|
LIQSOL_TOKEN: new PublicKey(liqsolTokenDevnetJson.address),
|
|
14667
14605
|
VALIDATOR_LEADERBOARD: new PublicKey(validatorLeaderboardDevnetJson.address),
|
|
14668
|
-
TRANSFER_HOOK: new PublicKey(devnetTransferHookIDL.address)
|
|
14606
|
+
TRANSFER_HOOK: new PublicKey(devnetTransferHookIDL.address),
|
|
14607
|
+
ALT_LOOKUP_TABLE: new PublicKey("3MbupRDxUqPtJzoLLmjEYV3dXJdh1jojQrpDEQUqv7xb")
|
|
14669
14608
|
};
|
|
14670
14609
|
const PROGRAM_IDS_BY_CHAIN = {
|
|
14671
14610
|
[SolChainID.Mainnet]: MAINNET_PROGRAM_IDS,
|
|
@@ -14887,7 +14826,7 @@ async function buildOutpostAccounts(connection, user, pgs) {
|
|
|
14887
14826
|
const userAta = await getAssociatedTokenAddress(
|
|
14888
14827
|
liqsolMint,
|
|
14889
14828
|
user,
|
|
14890
|
-
|
|
14829
|
+
true,
|
|
14891
14830
|
TOKEN_2022_PROGRAM_ID
|
|
14892
14831
|
);
|
|
14893
14832
|
const bucketUserRecord = pgs.deriveUserRecordPda(bucketTokenAccount);
|
|
@@ -15269,14 +15208,13 @@ class OutpostClient {
|
|
|
15269
15208
|
throw err;
|
|
15270
15209
|
}
|
|
15271
15210
|
}
|
|
15272
|
-
async buildStakeIx(amountLamports, user) {
|
|
15273
|
-
|
|
15274
|
-
if (!userPk) {
|
|
15211
|
+
async buildStakeIx(amountLamports, user = this.wallet.publicKey) {
|
|
15212
|
+
if (!user) {
|
|
15275
15213
|
throw new Error("OutpostClient.buildStakeIx: wallet not connected");
|
|
15276
15214
|
}
|
|
15277
|
-
const a = await this.buildAccounts(
|
|
15215
|
+
const a = await this.buildAccounts(user);
|
|
15278
15216
|
return this.program.methods.synd(new BN(amountLamports.toString())).accounts({
|
|
15279
|
-
user
|
|
15217
|
+
user,
|
|
15280
15218
|
liqsolMint: a.liqsolMint,
|
|
15281
15219
|
globalState: a.globalState,
|
|
15282
15220
|
distributionState: a.distributionState,
|
|
@@ -15393,6 +15331,7 @@ class TokenClient {
|
|
|
15393
15331
|
);
|
|
15394
15332
|
}
|
|
15395
15333
|
async buildPurchaseIx(amountLamports, user = this.wallet.publicKey) {
|
|
15334
|
+
console.log("build purchase for", user.toBase58());
|
|
15396
15335
|
const a = await this.getAccounts(user);
|
|
15397
15336
|
const extraAccountMetaList = this.pgs.deriveExtraAccountMetaListPda(a.liqsolMint);
|
|
15398
15337
|
const liqsolCoreProgram = this.pgs.PROGRAM_IDS.LIQSOL_CORE;
|
|
@@ -15812,71 +15751,13 @@ const _SolanaStakingClient = class _SolanaStakingClient {
|
|
|
15812
15751
|
const config = this.config.extras?.squadsX;
|
|
15813
15752
|
return config ?? null;
|
|
15814
15753
|
}
|
|
15815
|
-
async createVaultLiqsolAtaOneShot(params) {
|
|
15816
|
-
const { connection, payer, vaultPda } = params;
|
|
15817
|
-
const liqsolMint = this.program.deriveLiqsolMintPda();
|
|
15818
|
-
const vaultAta = getAssociatedTokenAddressSync(
|
|
15819
|
-
liqsolMint,
|
|
15820
|
-
vaultPda,
|
|
15821
|
-
true,
|
|
15822
|
-
TOKEN_2022_PROGRAM_ID,
|
|
15823
|
-
ASSOCIATED_TOKEN_PROGRAM_ID
|
|
15824
|
-
);
|
|
15825
|
-
const info = await connection.getAccountInfo(vaultAta, "confirmed");
|
|
15826
|
-
if (info) return null;
|
|
15827
|
-
const ix = createAssociatedTokenAccountInstruction(
|
|
15828
|
-
payer,
|
|
15829
|
-
vaultAta,
|
|
15830
|
-
vaultPda,
|
|
15831
|
-
liqsolMint,
|
|
15832
|
-
TOKEN_2022_PROGRAM_ID,
|
|
15833
|
-
ASSOCIATED_TOKEN_PROGRAM_ID
|
|
15834
|
-
);
|
|
15835
|
-
const tx = new Transaction().add(ix);
|
|
15836
|
-
return { tx, vaultAta };
|
|
15837
|
-
}
|
|
15838
|
-
async prepSquadsIxs(ix) {
|
|
15839
|
-
if (!this.squadsX) throw new Error("Attempting to wrap Squads instruction without SquadsX config");
|
|
15840
|
-
const multisigPda = this.squadsMultisigPDA;
|
|
15841
|
-
const vaultPda = this.squadsVaultPDA;
|
|
15842
|
-
const vaultIndex = this.squadsX?.vaultIndex ?? 0;
|
|
15843
|
-
const creator = this.solPubKey;
|
|
15844
|
-
const ms = await multisig.accounts.Multisig.fromAccountAddress(this.connection, multisigPda);
|
|
15845
|
-
const current = BigInt(ms.transactionIndex?.toString() ?? 0);
|
|
15846
|
-
const transactionIndex = current + BigInt(1);
|
|
15847
|
-
const { blockhash } = await this.connection.getLatestBlockhash("confirmed");
|
|
15848
|
-
const transactionMessage = new TransactionMessage({
|
|
15849
|
-
payerKey: vaultPda,
|
|
15850
|
-
recentBlockhash: blockhash,
|
|
15851
|
-
instructions: [ix]
|
|
15852
|
-
});
|
|
15853
|
-
const createVaultTxIx = await multisig.instructions.vaultTransactionCreate({
|
|
15854
|
-
multisigPda,
|
|
15855
|
-
transactionIndex,
|
|
15856
|
-
creator,
|
|
15857
|
-
vaultIndex,
|
|
15858
|
-
transactionMessage,
|
|
15859
|
-
ephemeralSigners: 0
|
|
15860
|
-
});
|
|
15861
|
-
const createProposalIx = await multisig.instructions.proposalCreate({
|
|
15862
|
-
multisigPda,
|
|
15863
|
-
transactionIndex,
|
|
15864
|
-
creator
|
|
15865
|
-
});
|
|
15866
|
-
return [createVaultTxIx, createProposalIx];
|
|
15867
|
-
}
|
|
15868
15754
|
async deposit(amountLamports) {
|
|
15869
15755
|
this.ensureUser();
|
|
15870
|
-
if (amountLamports <= BigInt(0))
|
|
15756
|
+
if (amountLamports <= BigInt(0))
|
|
15871
15757
|
throw new Error("Deposit amount must be greater than zero.");
|
|
15872
|
-
}
|
|
15873
15758
|
try {
|
|
15874
|
-
const
|
|
15875
|
-
|
|
15876
|
-
const tx = new Transaction().add(ix);
|
|
15877
|
-
const prepared = await this.prepareTx(tx);
|
|
15878
|
-
const signed = await this.signTransaction(prepared.tx);
|
|
15879
|
-
return this.sendAndConfirmHttp(signed, prepared);
|
|
15759
|
+
const ix = await this.depositClient.buildDepositTx(amountLamports, this.squadsVaultPDA);
|
|
15760
|
+
return !!this.squadsX ? await this.sendSquadsIxs(ix) : await this.buildAndSendIx(ix);
|
|
15880
15761
|
} catch (err) {
|
|
15881
15762
|
console.log(`Failed to deposit Solana: ${err}`);
|
|
15882
15763
|
throw err;
|
|
@@ -15884,16 +15765,11 @@ const _SolanaStakingClient = class _SolanaStakingClient {
|
|
|
15884
15765
|
}
|
|
15885
15766
|
async withdraw(amountLamports) {
|
|
15886
15767
|
this.ensureUser();
|
|
15887
|
-
if (amountLamports <= BigInt(0))
|
|
15768
|
+
if (amountLamports <= BigInt(0))
|
|
15888
15769
|
throw new Error("Withdraw amount must be greater than zero.");
|
|
15889
|
-
}
|
|
15890
15770
|
try {
|
|
15891
|
-
const
|
|
15892
|
-
|
|
15893
|
-
const tx = new Transaction().add(cuIx, ix);
|
|
15894
|
-
const prepared = await this.prepareTx(tx);
|
|
15895
|
-
const signed = await this.signTransaction(prepared.tx);
|
|
15896
|
-
return this.sendAndConfirmHttp(signed, prepared);
|
|
15771
|
+
const ix = await this.depositClient.buildWithdrawTx(amountLamports, this.squadsVaultPDA);
|
|
15772
|
+
return !!this.squadsX ? await this.sendSquadsIxs(ix) : await this.buildAndSendIx(ix);
|
|
15897
15773
|
} catch (err) {
|
|
15898
15774
|
console.log(`Failed to withdraw Solana: ${err}`);
|
|
15899
15775
|
throw err;
|
|
@@ -15901,17 +15777,11 @@ const _SolanaStakingClient = class _SolanaStakingClient {
|
|
|
15901
15777
|
}
|
|
15902
15778
|
async stake(amountLamports) {
|
|
15903
15779
|
this.ensureUser();
|
|
15904
|
-
if (!amountLamports || amountLamports <= BigInt(0))
|
|
15780
|
+
if (!amountLamports || amountLamports <= BigInt(0))
|
|
15905
15781
|
throw new Error("Stake amount must be greater than zero.");
|
|
15906
|
-
}
|
|
15907
15782
|
try {
|
|
15908
|
-
const
|
|
15909
|
-
|
|
15910
|
-
const ix = await this.outpostClient.buildStakeIx(amountLamports, user);
|
|
15911
|
-
const tx = new Transaction().add(cuIx, ix);
|
|
15912
|
-
const prepared = await this.prepareTx(tx);
|
|
15913
|
-
const signed = await this.signTransaction(prepared.tx);
|
|
15914
|
-
return this.sendAndConfirmHttp(signed, prepared);
|
|
15783
|
+
const ix = await this.outpostClient.buildStakeIx(amountLamports, this.squadsVaultPDA);
|
|
15784
|
+
return !!this.squadsX ? await this.sendSquadsIxs(ix) : await this.buildAndSendIx(ix);
|
|
15915
15785
|
} catch (err) {
|
|
15916
15786
|
console.log(`Failed to stake Solana: ${err}`);
|
|
15917
15787
|
throw err;
|
|
@@ -15919,17 +15789,11 @@ const _SolanaStakingClient = class _SolanaStakingClient {
|
|
|
15919
15789
|
}
|
|
15920
15790
|
async unstake(amountLamports) {
|
|
15921
15791
|
this.ensureUser();
|
|
15922
|
-
if (!amountLamports || amountLamports <= BigInt(0))
|
|
15792
|
+
if (!amountLamports || amountLamports <= BigInt(0))
|
|
15923
15793
|
throw new Error("Unstake amount must be greater than zero.");
|
|
15924
|
-
}
|
|
15925
15794
|
try {
|
|
15926
|
-
const
|
|
15927
|
-
|
|
15928
|
-
const ix = await this.outpostClient.buildUnstakeIx(amountLamports, user);
|
|
15929
|
-
const tx = new Transaction().add(cuIx, ix);
|
|
15930
|
-
const prepared = await this.prepareTx(tx);
|
|
15931
|
-
const signed = await this.signTransaction(prepared.tx);
|
|
15932
|
-
return this.sendAndConfirmHttp(signed, prepared);
|
|
15795
|
+
const ix = await this.outpostClient.buildUnstakeIx(amountLamports, this.squadsVaultPDA);
|
|
15796
|
+
return !!this.squadsX ? await this.sendSquadsIxs(ix) : await this.buildAndSendIx(ix);
|
|
15933
15797
|
} catch (err) {
|
|
15934
15798
|
console.log(`Failed to unstake Solana: ${err}`);
|
|
15935
15799
|
throw err;
|
|
@@ -15937,24 +15801,17 @@ const _SolanaStakingClient = class _SolanaStakingClient {
|
|
|
15937
15801
|
}
|
|
15938
15802
|
async buy(amountLamports) {
|
|
15939
15803
|
this.ensureUser();
|
|
15940
|
-
if (!amountLamports || amountLamports <= BigInt(0))
|
|
15804
|
+
if (!amountLamports || amountLamports <= BigInt(0))
|
|
15941
15805
|
throw new Error("liqSOL pretoken purchase requires a positive amount.");
|
|
15942
|
-
}
|
|
15943
15806
|
try {
|
|
15944
|
-
const
|
|
15945
|
-
|
|
15946
|
-
const ix = await this.tokenClient.buildPurchaseIx(amountLamports, user);
|
|
15947
|
-
const tx = new Transaction().add(cuIx, ix);
|
|
15948
|
-
const prepared = await this.prepareTx(tx);
|
|
15949
|
-
const signed = await this.signTransaction(prepared.tx);
|
|
15950
|
-
return this.sendAndConfirmHttp(signed, prepared);
|
|
15807
|
+
const ix = await this.tokenClient.buildPurchaseIx(amountLamports, this.squadsVaultPDA);
|
|
15808
|
+
return !!this.squadsX ? await this.sendSquadsIxs(ix) : await this.buildAndSendIx(ix);
|
|
15951
15809
|
} catch (err) {
|
|
15952
15810
|
console.log(`Failed to buy liqSOL pretokens: ${err}`);
|
|
15953
15811
|
throw err;
|
|
15954
15812
|
}
|
|
15955
15813
|
}
|
|
15956
15814
|
async getPortfolio() {
|
|
15957
|
-
if (!this.pubKey) throw new Error("User pubKey is undefined");
|
|
15958
15815
|
try {
|
|
15959
15816
|
const user = !!this.squadsX ? this.squadsVaultPDA : this.solPubKey;
|
|
15960
15817
|
const reservePoolPDA = this.program.deriveReservePoolPda();
|
|
@@ -16046,16 +15903,115 @@ const _SolanaStakingClient = class _SolanaStakingClient {
|
|
|
16046
15903
|
return this.distributionClient.getUserRecord(this.solPubKey);
|
|
16047
15904
|
}
|
|
16048
15905
|
get squadsMultisigPDA() {
|
|
16049
|
-
if (!this.squadsX) return
|
|
15906
|
+
if (!this.squadsX) return void 0;
|
|
16050
15907
|
return new PublicKey(this.squadsX.multisigPDA);
|
|
16051
15908
|
}
|
|
16052
15909
|
get squadsVaultPDA() {
|
|
16053
|
-
if (!this.squadsX || !this.squadsMultisigPDA) return
|
|
15910
|
+
if (!this.squadsX || !this.squadsMultisigPDA) return void 0;
|
|
16054
15911
|
const multisigPda = this.squadsMultisigPDA;
|
|
16055
15912
|
const index = this.squadsX.vaultIndex ?? 0;
|
|
16056
15913
|
const pda = multisig.getVaultPda({ multisigPda, index });
|
|
16057
15914
|
return pda[0];
|
|
16058
15915
|
}
|
|
15916
|
+
async sendSquadsIxs(ix) {
|
|
15917
|
+
if (!this.squadsX) throw new Error("Attempting to wrap Squads instruction without SquadsX config");
|
|
15918
|
+
const multisigPda = this.squadsMultisigPDA;
|
|
15919
|
+
const vaultPda = this.squadsVaultPDA;
|
|
15920
|
+
const vaultIndex = this.squadsX?.vaultIndex ?? 0;
|
|
15921
|
+
const creator = this.solPubKey;
|
|
15922
|
+
const ms = await multisig.accounts.Multisig.fromAccountAddress(this.connection, multisigPda);
|
|
15923
|
+
const current = BigInt(ms.transactionIndex?.toString() ?? 0);
|
|
15924
|
+
const transactionIndex = current + BigInt(1);
|
|
15925
|
+
const altAddress = this.program.PROGRAM_IDS.ALT_LOOKUP_TABLE;
|
|
15926
|
+
const altAccount = await this.connection.getAddressLookupTable(altAddress);
|
|
15927
|
+
if (!altAccount.value) throw new Error("ALT not found on-chain or not yet active.");
|
|
15928
|
+
const lookupTable = altAccount.value;
|
|
15929
|
+
const computeLimitIx = ComputeBudgetProgram.setComputeUnitLimit({ units: 4e5 });
|
|
15930
|
+
const computePriceIx = ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 2e3 });
|
|
15931
|
+
const { blockhash } = await this.connection.getLatestBlockhash("confirmed");
|
|
15932
|
+
const transactionMessage = new TransactionMessage({
|
|
15933
|
+
payerKey: vaultPda,
|
|
15934
|
+
recentBlockhash: blockhash,
|
|
15935
|
+
instructions: [computeLimitIx, computePriceIx, ix]
|
|
15936
|
+
});
|
|
15937
|
+
const createVaultTxIx = await multisig.instructions.vaultTransactionCreate({
|
|
15938
|
+
multisigPda,
|
|
15939
|
+
transactionIndex,
|
|
15940
|
+
creator,
|
|
15941
|
+
vaultIndex,
|
|
15942
|
+
transactionMessage,
|
|
15943
|
+
ephemeralSigners: 0,
|
|
15944
|
+
addressLookupTableAccounts: [lookupTable]
|
|
15945
|
+
});
|
|
15946
|
+
const vaultTransactionCreate = await this.buildAndSendIx(createVaultTxIx);
|
|
15947
|
+
console.log("SQUADSX: vaultTransactionCreate", vaultTransactionCreate);
|
|
15948
|
+
const createProposalIx = await multisig.instructions.proposalCreate({
|
|
15949
|
+
multisigPda,
|
|
15950
|
+
transactionIndex,
|
|
15951
|
+
creator
|
|
15952
|
+
});
|
|
15953
|
+
const proposalCreate = await this.buildAndSendIx(createProposalIx);
|
|
15954
|
+
console.log("SQUADSX: proposalCreate", proposalCreate);
|
|
15955
|
+
return proposalCreate;
|
|
15956
|
+
}
|
|
15957
|
+
async buildAndSendIx(ix) {
|
|
15958
|
+
const cuIx = ComputeBudgetProgram.setComputeUnitLimit({ units: 4e5 });
|
|
15959
|
+
const ixs = Array.isArray(ix) ? ix : [ix];
|
|
15960
|
+
const tx = new Transaction().add(cuIx, ...ixs);
|
|
15961
|
+
const prepared = await this.prepareTx(tx);
|
|
15962
|
+
const signed = await this.signTransaction(prepared.tx);
|
|
15963
|
+
return this.sendAndConfirmHttp(signed, prepared);
|
|
15964
|
+
}
|
|
15965
|
+
async sendAndConfirmHttp(signed, _ctx) {
|
|
15966
|
+
this.ensureUser();
|
|
15967
|
+
const rawTx = signed.serialize();
|
|
15968
|
+
try {
|
|
15969
|
+
const signature = await this.connection.sendRawTransaction(rawTx, {
|
|
15970
|
+
skipPreflight: false,
|
|
15971
|
+
preflightCommitment: commitment,
|
|
15972
|
+
maxRetries: 3
|
|
15973
|
+
});
|
|
15974
|
+
return signature;
|
|
15975
|
+
} catch (e) {
|
|
15976
|
+
const msg = e?.message ?? "";
|
|
15977
|
+
const isSendTxError = e instanceof SendTransactionError || e?.name === "SendTransactionError";
|
|
15978
|
+
if (isSendTxError && msg.includes("already been processed")) {
|
|
15979
|
+
console.warn(
|
|
15980
|
+
'sendRawTransaction reports "already been processed"; treating as success without further confirmation.'
|
|
15981
|
+
);
|
|
15982
|
+
const legacy = signed;
|
|
15983
|
+
const first = legacy.signatures?.[0]?.signature;
|
|
15984
|
+
if (first) {
|
|
15985
|
+
return bs58.encode(first);
|
|
15986
|
+
}
|
|
15987
|
+
return "already-processed";
|
|
15988
|
+
}
|
|
15989
|
+
throw e;
|
|
15990
|
+
}
|
|
15991
|
+
}
|
|
15992
|
+
async signTransaction(tx) {
|
|
15993
|
+
this.ensureUser();
|
|
15994
|
+
return this.anchor.wallet.signTransaction(tx);
|
|
15995
|
+
}
|
|
15996
|
+
async sendTransaction(signed) {
|
|
15997
|
+
this.ensureUser();
|
|
15998
|
+
return this.anchor.sendAndConfirm(signed);
|
|
15999
|
+
}
|
|
16000
|
+
async prepareTx(tx) {
|
|
16001
|
+
const { blockhash, lastValidBlockHeight } = await this.connection.getLatestBlockhash("confirmed");
|
|
16002
|
+
tx.recentBlockhash = blockhash;
|
|
16003
|
+
tx.feePayer = this.feePayer;
|
|
16004
|
+
return { tx, blockhash, lastValidBlockHeight };
|
|
16005
|
+
}
|
|
16006
|
+
ensureUser() {
|
|
16007
|
+
if (!this.pubKey) throw new Error("User pubKey is undefined");
|
|
16008
|
+
const wallet = this.anchor?.wallet;
|
|
16009
|
+
const pk = wallet?.publicKey;
|
|
16010
|
+
if (!pk) throw new Error("Wallet not connected");
|
|
16011
|
+
if (typeof wallet.signTransaction !== "function") {
|
|
16012
|
+
throw new Error("Wallet does not support signTransaction");
|
|
16013
|
+
}
|
|
16014
|
+
}
|
|
16059
16015
|
async getTrancheSnapshot(chainID) {
|
|
16060
16016
|
try {
|
|
16061
16017
|
const [globalState, trancheState] = await Promise.all([
|
|
@@ -16097,10 +16053,24 @@ const _SolanaStakingClient = class _SolanaStakingClient {
|
|
|
16097
16053
|
return Number(DEFAULT_AVERAGE_PAY_RATE) / Number(PAY_RATE_SCALE_FACTOR);
|
|
16098
16054
|
}
|
|
16099
16055
|
const currentIndex = Number(payRateHistory.currentIndex);
|
|
16100
|
-
const
|
|
16101
|
-
|
|
16102
|
-
|
|
16103
|
-
|
|
16056
|
+
const processedCount = Math.min(totalEntriesAdded, maxEntries);
|
|
16057
|
+
let sum = BigInt(0);
|
|
16058
|
+
let validCount = 0;
|
|
16059
|
+
let idx = (currentIndex - 1 + maxEntries) % maxEntries;
|
|
16060
|
+
for (let i = 0; i < processedCount; i++) {
|
|
16061
|
+
const entry = payRateHistory.entries[idx];
|
|
16062
|
+
const scaledRate = BigInt(entry.scaledRate.toString());
|
|
16063
|
+
if (scaledRate > BigInt(0)) {
|
|
16064
|
+
sum += scaledRate;
|
|
16065
|
+
validCount++;
|
|
16066
|
+
}
|
|
16067
|
+
idx = (idx - 1 + maxEntries) % maxEntries;
|
|
16068
|
+
}
|
|
16069
|
+
if (validCount === 0) {
|
|
16070
|
+
return Number(DEFAULT_AVERAGE_PAY_RATE) / Number(PAY_RATE_SCALE_FACTOR);
|
|
16071
|
+
}
|
|
16072
|
+
const average = Number(sum / BigInt(validCount));
|
|
16073
|
+
return average / Number(PAY_RATE_SCALE_FACTOR);
|
|
16104
16074
|
}
|
|
16105
16075
|
async getEpochsPerYearFromCluster() {
|
|
16106
16076
|
const now = Date.now();
|
|
@@ -16235,56 +16205,6 @@ const _SolanaStakingClient = class _SolanaStakingClient {
|
|
|
16235
16205
|
};
|
|
16236
16206
|
return singleTxFeeLamports;
|
|
16237
16207
|
}
|
|
16238
|
-
async sendAndConfirmHttp(signed, _ctx) {
|
|
16239
|
-
this.ensureUser();
|
|
16240
|
-
const rawTx = signed.serialize();
|
|
16241
|
-
try {
|
|
16242
|
-
const signature = await this.connection.sendRawTransaction(rawTx, {
|
|
16243
|
-
skipPreflight: false,
|
|
16244
|
-
preflightCommitment: commitment,
|
|
16245
|
-
maxRetries: 3
|
|
16246
|
-
});
|
|
16247
|
-
return signature;
|
|
16248
|
-
} catch (e) {
|
|
16249
|
-
const msg = e?.message ?? "";
|
|
16250
|
-
const isSendTxError = e instanceof SendTransactionError || e?.name === "SendTransactionError";
|
|
16251
|
-
if (isSendTxError && msg.includes("already been processed")) {
|
|
16252
|
-
console.warn(
|
|
16253
|
-
'sendRawTransaction reports "already been processed"; treating as success without further confirmation.'
|
|
16254
|
-
);
|
|
16255
|
-
const legacy = signed;
|
|
16256
|
-
const first = legacy.signatures?.[0]?.signature;
|
|
16257
|
-
if (first) {
|
|
16258
|
-
return bs58.encode(first);
|
|
16259
|
-
}
|
|
16260
|
-
return "already-processed";
|
|
16261
|
-
}
|
|
16262
|
-
throw e;
|
|
16263
|
-
}
|
|
16264
|
-
}
|
|
16265
|
-
async signTransaction(tx) {
|
|
16266
|
-
this.ensureUser();
|
|
16267
|
-
return this.anchor.wallet.signTransaction(tx);
|
|
16268
|
-
}
|
|
16269
|
-
async sendTransaction(signed) {
|
|
16270
|
-
this.ensureUser();
|
|
16271
|
-
return this.anchor.sendAndConfirm(signed);
|
|
16272
|
-
}
|
|
16273
|
-
async prepareTx(tx) {
|
|
16274
|
-
const { blockhash, lastValidBlockHeight } = await this.connection.getLatestBlockhash("confirmed");
|
|
16275
|
-
tx.recentBlockhash = blockhash;
|
|
16276
|
-
tx.feePayer = this.feePayer;
|
|
16277
|
-
return { tx, blockhash, lastValidBlockHeight };
|
|
16278
|
-
}
|
|
16279
|
-
ensureUser() {
|
|
16280
|
-
if (!this.pubKey) throw new Error("User pubKey is undefined");
|
|
16281
|
-
const wallet = this.anchor?.wallet;
|
|
16282
|
-
const pk = wallet?.publicKey;
|
|
16283
|
-
if (!pk) throw new Error("Wallet not connected");
|
|
16284
|
-
if (typeof wallet.signTransaction !== "function") {
|
|
16285
|
-
throw new Error("Wallet does not support signTransaction");
|
|
16286
|
-
}
|
|
16287
|
-
}
|
|
16288
16208
|
};
|
|
16289
16209
|
_SolanaStakingClient.EPOCHS_PER_YEAR_TTL_MS = 10 * 60 * 1e3;
|
|
16290
16210
|
_SolanaStakingClient.FEE_CACHE_TTL_MS = 6e4;
|
|
@@ -41446,6 +41366,41 @@ class ReceiptClient {
|
|
|
41446
41366
|
}
|
|
41447
41367
|
}
|
|
41448
41368
|
|
|
41369
|
+
class ValidatorClient {
|
|
41370
|
+
get contract() {
|
|
41371
|
+
return this.contractService.contract;
|
|
41372
|
+
}
|
|
41373
|
+
constructor(contract) {
|
|
41374
|
+
this.contractService = contract;
|
|
41375
|
+
}
|
|
41376
|
+
async validatorDepositAndLockBond() {
|
|
41377
|
+
const amountWei = ethers.utils.parseEther("32");
|
|
41378
|
+
try {
|
|
41379
|
+
await this.contract.DepositManager.callStatic.validatorDepositAndLockBond({ value: amountWei });
|
|
41380
|
+
} catch (err) {
|
|
41381
|
+
let errorObj = formatContractErrors(err);
|
|
41382
|
+
throw new Error(errorObj.name ?? errorObj.raw);
|
|
41383
|
+
}
|
|
41384
|
+
const tx = await this.contract.DepositManager.validatorDepositAndLockBond({ value: amountWei });
|
|
41385
|
+
const receipt = await tx.wait(1);
|
|
41386
|
+
let staked;
|
|
41387
|
+
const ev = receipt.events?.find((e) => e.event === "Staked");
|
|
41388
|
+
if (ev && ev.args) {
|
|
41389
|
+
const { sender, amount, shares } = ev.args;
|
|
41390
|
+
staked = {
|
|
41391
|
+
sender,
|
|
41392
|
+
amount: BigNumber.from(amount),
|
|
41393
|
+
shares: BigNumber.from(shares)
|
|
41394
|
+
};
|
|
41395
|
+
}
|
|
41396
|
+
return {
|
|
41397
|
+
txHash: tx.hash,
|
|
41398
|
+
receipt,
|
|
41399
|
+
staked
|
|
41400
|
+
};
|
|
41401
|
+
}
|
|
41402
|
+
}
|
|
41403
|
+
|
|
41449
41404
|
const INITIAL_TRANCHE_SUPPLY = 35e3;
|
|
41450
41405
|
class EthereumStakingClient {
|
|
41451
41406
|
constructor(config) {
|
|
@@ -41468,6 +41423,7 @@ class EthereumStakingClient {
|
|
|
41468
41423
|
this.stakeClient = new StakeClient(this.contractService);
|
|
41469
41424
|
this.oppClient = new OPPClient(this.contractService);
|
|
41470
41425
|
this.receiptClient = new ReceiptClient(this.contractService);
|
|
41426
|
+
this.validatorClient = new ValidatorClient(this.contractService);
|
|
41471
41427
|
} catch (error) {
|
|
41472
41428
|
throw error;
|
|
41473
41429
|
}
|
|
@@ -41524,6 +41480,11 @@ class EthereumStakingClient {
|
|
|
41524
41480
|
let result = await this.pretokenClient.purchasePretokensWithLiqETH(amount, buyer);
|
|
41525
41481
|
return result && result.txHash ? result.txHash : "Error - no resulting txHash";
|
|
41526
41482
|
}
|
|
41483
|
+
async validatorDeposit() {
|
|
41484
|
+
this.ensureUser();
|
|
41485
|
+
let result = await this.validatorClient.validatorDepositAndLockBond();
|
|
41486
|
+
return result && result.txHash ? result.txHash : "Error - no resulting txHash";
|
|
41487
|
+
}
|
|
41527
41488
|
async getPortfolio() {
|
|
41528
41489
|
try {
|
|
41529
41490
|
if (!this.signer) return Promise.resolve(null);
|