@wireio/stake 0.9.0 → 0.9.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 +341 -32
- package/lib/stake.browser.js.map +1 -1
- package/lib/stake.d.ts +93 -10
- package/lib/stake.js +386 -30
- package/lib/stake.js.map +1 -1
- package/lib/stake.m.js +341 -32
- package/lib/stake.m.js.map +1 -1
- package/package.json +4 -3
- package/src/networks/ethereum/clients/convert.client.ts +29 -1
- package/src/networks/ethereum/clients/receipt.client.ts +81 -3
- package/src/networks/ethereum/clients/stake.client.ts +1 -0
- package/src/networks/ethereum/ethereum.ts +33 -11
- package/src/networks/ethereum/types.ts +15 -0
- package/src/networks/solana/clients/deposit.client.ts +260 -9
- package/src/networks/solana/clients/distribution.client.ts +1 -1
- package/src/networks/solana/clients/outpost.client.ts +1 -1
- package/src/networks/solana/solana.ts +184 -26
- package/src/networks/solana/types.ts +4 -4
- package/src/staker.ts +2 -2
- package/src/types.ts +8 -0
package/lib/stake.browser.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { PublicKey as PublicKey$1, KeyType, SolChainID, EvmChainID } from '@wireio/core';
|
|
2
|
-
import { PublicKey, StakeProgram, SystemProgram, SYSVAR_INSTRUCTIONS_PUBKEY, SYSVAR_CLOCK_PUBKEY, SYSVAR_STAKE_HISTORY_PUBKEY, SYSVAR_RENT_PUBKEY, Transaction, Keypair, Connection, ComputeBudgetProgram } from '@solana/web3.js';
|
|
2
|
+
import { PublicKey, StakeProgram, SystemProgram, SYSVAR_INSTRUCTIONS_PUBKEY, SYSVAR_CLOCK_PUBKEY, SYSVAR_STAKE_HISTORY_PUBKEY, SYSVAR_RENT_PUBKEY, TransactionMessage, Transaction, Keypair, Connection, ComputeBudgetProgram } from '@solana/web3.js';
|
|
3
3
|
import { Program, BN, AnchorProvider } from '@coral-xyz/anchor';
|
|
4
|
-
import { getAssociatedTokenAddressSync, TOKEN_2022_PROGRAM_ID, ASSOCIATED_TOKEN_PROGRAM_ID, getAssociatedTokenAddress } from '@solana/spl-token';
|
|
4
|
+
import { getAssociatedTokenAddressSync, TOKEN_2022_PROGRAM_ID, ASSOCIATED_TOKEN_PROGRAM_ID, getAssociatedTokenAddress, createAssociatedTokenAccountInstruction } from '@solana/spl-token';
|
|
5
|
+
import * as multisig from '@sqds/multisig';
|
|
5
6
|
import { ethers, Contract, BigNumber } from 'ethers';
|
|
6
7
|
|
|
7
8
|
var address$3 = "5nBtmutQLrRKBUxNfHJPDjiW5u8id6QM9Hhjg1D1g1XH";
|
|
@@ -7440,6 +7441,9 @@ class DepositClient {
|
|
|
7440
7441
|
const svc = new SolanaProgramService(provider);
|
|
7441
7442
|
this.program = svc.getProgram("liqsolCore");
|
|
7442
7443
|
}
|
|
7444
|
+
get connection() {
|
|
7445
|
+
return this.provider.connection;
|
|
7446
|
+
}
|
|
7443
7447
|
get wallet() {
|
|
7444
7448
|
return this.provider.wallet;
|
|
7445
7449
|
}
|
|
@@ -7467,7 +7471,7 @@ class DepositClient {
|
|
|
7467
7471
|
const userAta = getAssociatedTokenAddressSync(
|
|
7468
7472
|
liqsolMint,
|
|
7469
7473
|
user,
|
|
7470
|
-
|
|
7474
|
+
true,
|
|
7471
7475
|
TOKEN_2022_PROGRAM_ID
|
|
7472
7476
|
);
|
|
7473
7477
|
const distributionState = deriveDistributionStatePda();
|
|
@@ -7480,7 +7484,7 @@ class DepositClient {
|
|
|
7480
7484
|
);
|
|
7481
7485
|
const seed = Math.floor(Math.random() * 2 ** 32);
|
|
7482
7486
|
const ephemeralStake = await deriveEphemeralStakeAddress(user, seed);
|
|
7483
|
-
|
|
7487
|
+
return await this.program.methods.deposit(new BN(amount.toString()), seed).accounts({
|
|
7484
7488
|
user,
|
|
7485
7489
|
depositAuthority,
|
|
7486
7490
|
systemProgram: SystemProgram.programId,
|
|
@@ -7507,7 +7511,58 @@ class DepositClient {
|
|
|
7507
7511
|
rent: SYSVAR_RENT_PUBKEY,
|
|
7508
7512
|
globalConfig
|
|
7509
7513
|
}).instruction();
|
|
7510
|
-
|
|
7514
|
+
}
|
|
7515
|
+
async buildSquadsDepositProposalTx(params) {
|
|
7516
|
+
const { connection, multisigPda, amountLamports, wallet } = params;
|
|
7517
|
+
const vaultIndex = params.vaultIndex ?? 0;
|
|
7518
|
+
if (!wallet?.publicKey) throw new Error("wallet.publicKey missing");
|
|
7519
|
+
if (!amountLamports || amountLamports <= BigInt(0)) throw new Error("amountLamports must be > 0");
|
|
7520
|
+
const [vaultPda] = multisig.getVaultPda({ multisigPda, index: vaultIndex });
|
|
7521
|
+
const depositBuilt = await this.buildDepositIxForUser(amountLamports, vaultPda);
|
|
7522
|
+
const ms = await multisig.accounts.Multisig.fromAccountAddress(connection, multisigPda);
|
|
7523
|
+
const current = BigInt(ms.transactionIndex?.toString?.() ?? 0);
|
|
7524
|
+
const transactionIndex = current + BigInt(1);
|
|
7525
|
+
const { blockhash } = await connection.getLatestBlockhash("confirmed");
|
|
7526
|
+
const message = new TransactionMessage({
|
|
7527
|
+
payerKey: vaultPda,
|
|
7528
|
+
recentBlockhash: blockhash,
|
|
7529
|
+
instructions: [depositBuilt.ix]
|
|
7530
|
+
});
|
|
7531
|
+
const createVaultTxIx = await multisig.instructions.vaultTransactionCreate({
|
|
7532
|
+
multisigPda,
|
|
7533
|
+
transactionIndex,
|
|
7534
|
+
creator: wallet.publicKey,
|
|
7535
|
+
vaultIndex,
|
|
7536
|
+
ephemeralSigners: 0,
|
|
7537
|
+
transactionMessage: message
|
|
7538
|
+
});
|
|
7539
|
+
console.log("createVaultTxIx", createVaultTxIx);
|
|
7540
|
+
const tx = new Transaction().add(createVaultTxIx);
|
|
7541
|
+
return { tx, transactionIndex, vaultPda };
|
|
7542
|
+
}
|
|
7543
|
+
async buildSquadsDepositProposalTx2(params) {
|
|
7544
|
+
const { connection, multisigPda, amountLamports, wallet } = params;
|
|
7545
|
+
const vaultIndex = params.vaultIndex ?? 0;
|
|
7546
|
+
if (!wallet?.publicKey) throw new Error("wallet.publicKey missing");
|
|
7547
|
+
if (!amountLamports || amountLamports <= BigInt(0)) throw new Error("amountLamports must be > 0");
|
|
7548
|
+
const [vaultPda] = multisig.getVaultPda({ multisigPda, index: vaultIndex });
|
|
7549
|
+
const depositBuilt = await this.buildDepositIxForUser(amountLamports, vaultPda);
|
|
7550
|
+
const ms = await multisig.accounts.Multisig.fromAccountAddress(connection, multisigPda);
|
|
7551
|
+
const current = BigInt(ms.transactionIndex?.toString?.() ?? 0);
|
|
7552
|
+
const transactionIndex = current + BigInt(1);
|
|
7553
|
+
const { blockhash } = await connection.getLatestBlockhash("confirmed");
|
|
7554
|
+
new TransactionMessage({
|
|
7555
|
+
payerKey: vaultPda,
|
|
7556
|
+
recentBlockhash: blockhash,
|
|
7557
|
+
instructions: [depositBuilt.ix]
|
|
7558
|
+
});
|
|
7559
|
+
const createProposalIx = await multisig.instructions.proposalCreate({
|
|
7560
|
+
multisigPda,
|
|
7561
|
+
transactionIndex,
|
|
7562
|
+
creator: wallet.publicKey
|
|
7563
|
+
});
|
|
7564
|
+
const tx = new Transaction().add(createProposalIx);
|
|
7565
|
+
return { tx, transactionIndex, vaultPda };
|
|
7511
7566
|
}
|
|
7512
7567
|
async buildWithdrawTx(amount, user = this.wallet.publicKey) {
|
|
7513
7568
|
if (!user) {
|
|
@@ -7524,7 +7579,7 @@ class DepositClient {
|
|
|
7524
7579
|
const userAta = getAssociatedTokenAddressSync(
|
|
7525
7580
|
liqsolMint,
|
|
7526
7581
|
user,
|
|
7527
|
-
|
|
7582
|
+
true,
|
|
7528
7583
|
TOKEN_2022_PROGRAM_ID
|
|
7529
7584
|
);
|
|
7530
7585
|
const userRecord = deriveUserRecordPda(userAta);
|
|
@@ -7557,7 +7612,7 @@ class DepositClient {
|
|
|
7557
7612
|
const nftAta = getAssociatedTokenAddressSync(
|
|
7558
7613
|
nftMint,
|
|
7559
7614
|
owner,
|
|
7560
|
-
|
|
7615
|
+
true,
|
|
7561
7616
|
TOKEN_2022_PROGRAM_ID
|
|
7562
7617
|
);
|
|
7563
7618
|
const bucketAuthority = deriveBucketAuthorityPda();
|
|
@@ -7595,6 +7650,68 @@ class DepositClient {
|
|
|
7595
7650
|
}).instruction();
|
|
7596
7651
|
return new Transaction().add(ix);
|
|
7597
7652
|
}
|
|
7653
|
+
async buildDepositIxForUser(amount, user) {
|
|
7654
|
+
if (!user) {
|
|
7655
|
+
throw new Error("buildDepositIxForUser: user is required");
|
|
7656
|
+
}
|
|
7657
|
+
if (!amount || amount <= BigInt(0)) {
|
|
7658
|
+
throw new Error("buildDepositIxForUser: amount must be > 0");
|
|
7659
|
+
}
|
|
7660
|
+
const depositAuthority = deriveDepositAuthorityPda();
|
|
7661
|
+
const liqsolMint = deriveLiqsolMintPda();
|
|
7662
|
+
const liqsolMintAuthority = deriveLiqsolMintAuthorityPda();
|
|
7663
|
+
const reservePool = deriveReservePoolPda();
|
|
7664
|
+
const vault = deriveVaultPda();
|
|
7665
|
+
const controllerState = deriveStakeControllerStatePda();
|
|
7666
|
+
const payoutState = derivePayoutStatePda();
|
|
7667
|
+
const bucketAuthority = deriveBucketAuthorityPda();
|
|
7668
|
+
const payRateHistory = derivePayRateHistoryPda();
|
|
7669
|
+
const globalConfig = deriveGlobalConfigPda();
|
|
7670
|
+
const userAta = getAssociatedTokenAddressSync(
|
|
7671
|
+
liqsolMint,
|
|
7672
|
+
user,
|
|
7673
|
+
true,
|
|
7674
|
+
TOKEN_2022_PROGRAM_ID
|
|
7675
|
+
);
|
|
7676
|
+
const distributionState = deriveDistributionStatePda();
|
|
7677
|
+
const userRecord = deriveUserRecordPda(userAta);
|
|
7678
|
+
const bucketTokenAccount = getAssociatedTokenAddressSync(
|
|
7679
|
+
liqsolMint,
|
|
7680
|
+
bucketAuthority,
|
|
7681
|
+
true,
|
|
7682
|
+
TOKEN_2022_PROGRAM_ID
|
|
7683
|
+
);
|
|
7684
|
+
const seed = Math.floor(Math.random() * 2 ** 32);
|
|
7685
|
+
const ephemeralStake = await deriveEphemeralStakeAddress(user, seed);
|
|
7686
|
+
const ix = await this.program.methods.deposit(new BN(amount.toString()), seed).accounts({
|
|
7687
|
+
user,
|
|
7688
|
+
depositAuthority,
|
|
7689
|
+
systemProgram: SystemProgram.programId,
|
|
7690
|
+
tokenProgram: TOKEN_2022_PROGRAM_ID,
|
|
7691
|
+
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
7692
|
+
liqsolProgram: PROGRAM_IDS.LIQSOL_TOKEN,
|
|
7693
|
+
stakeProgram: StakeProgram.programId,
|
|
7694
|
+
liqsolMint,
|
|
7695
|
+
userAta,
|
|
7696
|
+
liqsolMintAuthority,
|
|
7697
|
+
reservePool,
|
|
7698
|
+
vault,
|
|
7699
|
+
ephemeralStake,
|
|
7700
|
+
controllerState,
|
|
7701
|
+
payoutState,
|
|
7702
|
+
bucketAuthority,
|
|
7703
|
+
bucketTokenAccount,
|
|
7704
|
+
userRecord,
|
|
7705
|
+
distributionState,
|
|
7706
|
+
payRateHistory,
|
|
7707
|
+
instructionsSysvar: SYSVAR_INSTRUCTIONS_PUBKEY,
|
|
7708
|
+
clock: SYSVAR_CLOCK_PUBKEY,
|
|
7709
|
+
stakeHistory: SYSVAR_STAKE_HISTORY_PUBKEY,
|
|
7710
|
+
rent: SYSVAR_RENT_PUBKEY,
|
|
7711
|
+
globalConfig
|
|
7712
|
+
}).instruction();
|
|
7713
|
+
return { ix, seed, userAta, ephemeralStake };
|
|
7714
|
+
}
|
|
7598
7715
|
}
|
|
7599
7716
|
|
|
7600
7717
|
const INDEX_SCALE = BigInt(1e12);
|
|
@@ -8083,7 +8200,7 @@ class DistributionClient {
|
|
|
8083
8200
|
const ata = getAssociatedTokenAddressSync(
|
|
8084
8201
|
liqsolMint,
|
|
8085
8202
|
ownerOrAta,
|
|
8086
|
-
|
|
8203
|
+
true,
|
|
8087
8204
|
TOKEN_2022_PROGRAM_ID
|
|
8088
8205
|
);
|
|
8089
8206
|
const pdaFromWallet = deriveUserRecordPda(ata);
|
|
@@ -8362,7 +8479,7 @@ class OutpostClient {
|
|
|
8362
8479
|
};
|
|
8363
8480
|
}
|
|
8364
8481
|
static tokensToShares(amount, currentIndex) {
|
|
8365
|
-
const numerator = amount.mul(INDEX_SCALE$1);
|
|
8482
|
+
const numerator = amount.mul(new BN(INDEX_SCALE$1));
|
|
8366
8483
|
const shares = numerator.div(currentIndex);
|
|
8367
8484
|
const remainder = numerator.mod(currentIndex);
|
|
8368
8485
|
return remainder.eqn(0) ? shares : shares.addn(1);
|
|
@@ -8561,6 +8678,69 @@ const _SolanaStakingClient = class _SolanaStakingClient {
|
|
|
8561
8678
|
get network() {
|
|
8562
8679
|
return this.config.network;
|
|
8563
8680
|
}
|
|
8681
|
+
get feePayer() {
|
|
8682
|
+
if (this.signer) return this.signer;
|
|
8683
|
+
if (this.anchor.wallet.publicKey) return this.anchor.wallet.publicKey;
|
|
8684
|
+
throw new Error("No signing authority available");
|
|
8685
|
+
}
|
|
8686
|
+
get squadsX() {
|
|
8687
|
+
const config = this.config.extras?.squadsX;
|
|
8688
|
+
return config ?? null;
|
|
8689
|
+
}
|
|
8690
|
+
async createVaultLiqsolAtaOneShot(params) {
|
|
8691
|
+
const { connection, payer, vaultPda } = params;
|
|
8692
|
+
const liqsolMint = deriveLiqsolMintPda();
|
|
8693
|
+
const vaultAta = getAssociatedTokenAddressSync(
|
|
8694
|
+
liqsolMint,
|
|
8695
|
+
vaultPda,
|
|
8696
|
+
true,
|
|
8697
|
+
TOKEN_2022_PROGRAM_ID,
|
|
8698
|
+
ASSOCIATED_TOKEN_PROGRAM_ID
|
|
8699
|
+
);
|
|
8700
|
+
const info = await connection.getAccountInfo(vaultAta, "confirmed");
|
|
8701
|
+
console.log("info?", info);
|
|
8702
|
+
if (info) return null;
|
|
8703
|
+
const ix = createAssociatedTokenAccountInstruction(
|
|
8704
|
+
payer,
|
|
8705
|
+
vaultAta,
|
|
8706
|
+
vaultPda,
|
|
8707
|
+
liqsolMint,
|
|
8708
|
+
TOKEN_2022_PROGRAM_ID,
|
|
8709
|
+
ASSOCIATED_TOKEN_PROGRAM_ID
|
|
8710
|
+
);
|
|
8711
|
+
const tx = new Transaction().add(ix);
|
|
8712
|
+
return { tx, vaultAta };
|
|
8713
|
+
}
|
|
8714
|
+
async prepSquadsIxs(ix) {
|
|
8715
|
+
if (!this.squadsX) throw new Error("Attempting to wrap Squads instruction without SquadsX config");
|
|
8716
|
+
const multisigPda = this.squadsMultisigPDA;
|
|
8717
|
+
const vaultPda = this.squadsVaultPDA;
|
|
8718
|
+
const vaultIndex = this.squadsX?.vaultIndex ?? 0;
|
|
8719
|
+
const creator = this.solPubKey;
|
|
8720
|
+
const ms = await multisig.accounts.Multisig.fromAccountAddress(this.connection, multisigPda);
|
|
8721
|
+
const current = BigInt(ms.transactionIndex?.toString() ?? 0);
|
|
8722
|
+
const transactionIndex = current + BigInt(1);
|
|
8723
|
+
const { blockhash } = await this.connection.getLatestBlockhash("confirmed");
|
|
8724
|
+
const transactionMessage = new TransactionMessage({
|
|
8725
|
+
payerKey: vaultPda,
|
|
8726
|
+
recentBlockhash: blockhash,
|
|
8727
|
+
instructions: [ix]
|
|
8728
|
+
});
|
|
8729
|
+
const createVaultTxIx = await multisig.instructions.vaultTransactionCreate({
|
|
8730
|
+
multisigPda,
|
|
8731
|
+
transactionIndex,
|
|
8732
|
+
creator,
|
|
8733
|
+
vaultIndex,
|
|
8734
|
+
transactionMessage,
|
|
8735
|
+
ephemeralSigners: 0
|
|
8736
|
+
});
|
|
8737
|
+
const createProposalIx = await multisig.instructions.proposalCreate({
|
|
8738
|
+
multisigPda,
|
|
8739
|
+
transactionIndex,
|
|
8740
|
+
creator
|
|
8741
|
+
});
|
|
8742
|
+
return [createVaultTxIx, createProposalIx];
|
|
8743
|
+
}
|
|
8564
8744
|
async deposit(amountLamports) {
|
|
8565
8745
|
this.ensureUser();
|
|
8566
8746
|
if (amountLamports <= BigInt(0)) {
|
|
@@ -8568,11 +8748,40 @@ const _SolanaStakingClient = class _SolanaStakingClient {
|
|
|
8568
8748
|
}
|
|
8569
8749
|
try {
|
|
8570
8750
|
const cuIx = ComputeBudgetProgram.setComputeUnitLimit({ units: 4e5 });
|
|
8571
|
-
|
|
8572
|
-
|
|
8573
|
-
|
|
8574
|
-
|
|
8575
|
-
|
|
8751
|
+
if (!!this.squadsX) {
|
|
8752
|
+
const createVaultTx = await this.createVaultLiqsolAtaOneShot({
|
|
8753
|
+
connection: this.connection,
|
|
8754
|
+
payer: this.solPubKey,
|
|
8755
|
+
vaultPda: this.squadsVaultPDA
|
|
8756
|
+
});
|
|
8757
|
+
if (createVaultTx !== null) {
|
|
8758
|
+
console.log("need to create vault ata first...");
|
|
8759
|
+
const tx0 = new Transaction().add(createVaultTx.tx);
|
|
8760
|
+
const prepared0 = await this.prepareTx(tx0);
|
|
8761
|
+
const signed0 = await this.signTransaction(prepared0.tx);
|
|
8762
|
+
const sent0 = await this.sendAndConfirmHttp(signed0, prepared0);
|
|
8763
|
+
console.log("create Vault ATA", sent0);
|
|
8764
|
+
}
|
|
8765
|
+
const ix = await this.depositClient.buildDepositTx(amountLamports, this.squadsVaultPDA);
|
|
8766
|
+
const squadIxs = await this.prepSquadsIxs(ix);
|
|
8767
|
+
const tx1 = new Transaction().add(cuIx, squadIxs[0]);
|
|
8768
|
+
const prepared1 = await this.prepareTx(tx1);
|
|
8769
|
+
const signed1 = await this.signTransaction(prepared1.tx);
|
|
8770
|
+
const sent1 = await this.sendAndConfirmHttp(signed1, prepared1);
|
|
8771
|
+
console.log("SENT 1", sent1);
|
|
8772
|
+
const tx2 = new Transaction().add(cuIx, squadIxs[1]);
|
|
8773
|
+
const prepared2 = await this.prepareTx(tx2);
|
|
8774
|
+
const signed2 = await this.signTransaction(prepared2.tx);
|
|
8775
|
+
const sent2 = await this.sendAndConfirmHttp(signed2, prepared2);
|
|
8776
|
+
console.log("SENT 2", sent2);
|
|
8777
|
+
return sent2;
|
|
8778
|
+
} else {
|
|
8779
|
+
const ix = await this.depositClient.buildDepositTx(amountLamports);
|
|
8780
|
+
const tx = new Transaction().add(ix);
|
|
8781
|
+
const prepared = await this.prepareTx(tx);
|
|
8782
|
+
const signed = await this.signTransaction(prepared.tx);
|
|
8783
|
+
return this.sendAndConfirmHttp(signed, prepared);
|
|
8784
|
+
}
|
|
8576
8785
|
} catch (err) {
|
|
8577
8786
|
throw new Error(`Failed to deposit Solana: ${err}`);
|
|
8578
8787
|
}
|
|
@@ -8647,14 +8856,15 @@ const _SolanaStakingClient = class _SolanaStakingClient {
|
|
|
8647
8856
|
async getPortfolio() {
|
|
8648
8857
|
if (!this.pubKey) throw new Error("User pubKey is undefined");
|
|
8649
8858
|
try {
|
|
8650
|
-
const user = this.solPubKey;
|
|
8859
|
+
const user = !!this.squadsX ? this.squadsVaultPDA : this.solPubKey;
|
|
8860
|
+
console.log("get portfolio for user", user.toBase58());
|
|
8651
8861
|
const reservePoolPDA = deriveReservePoolPda();
|
|
8652
8862
|
const vaultPDA = deriveVaultPda();
|
|
8653
8863
|
const liqsolMint = deriveLiqsolMintPda();
|
|
8654
8864
|
const userLiqsolAta = getAssociatedTokenAddressSync(
|
|
8655
8865
|
liqsolMint,
|
|
8656
8866
|
user,
|
|
8657
|
-
|
|
8867
|
+
true,
|
|
8658
8868
|
TOKEN_2022_PROGRAM_ID,
|
|
8659
8869
|
ASSOCIATED_TOKEN_PROGRAM_ID
|
|
8660
8870
|
);
|
|
@@ -8735,6 +8945,17 @@ const _SolanaStakingClient = class _SolanaStakingClient {
|
|
|
8735
8945
|
if (!this.pubKey) throw new Error("User pubKey is undefined");
|
|
8736
8946
|
return this.distributionClient.getUserRecord(this.solPubKey);
|
|
8737
8947
|
}
|
|
8948
|
+
get squadsMultisigPDA() {
|
|
8949
|
+
if (!this.squadsX) return null;
|
|
8950
|
+
return new PublicKey(this.squadsX.multisigPDA);
|
|
8951
|
+
}
|
|
8952
|
+
get squadsVaultPDA() {
|
|
8953
|
+
if (!this.squadsX || !this.squadsMultisigPDA) return null;
|
|
8954
|
+
const multisigPda = this.squadsMultisigPDA;
|
|
8955
|
+
const index = this.squadsX.vaultIndex ?? 0;
|
|
8956
|
+
const pda = multisig.getVaultPda({ multisigPda, index });
|
|
8957
|
+
return pda[0];
|
|
8958
|
+
}
|
|
8738
8959
|
async getTrancheSnapshot(options) {
|
|
8739
8960
|
try {
|
|
8740
8961
|
const {
|
|
@@ -8841,8 +9062,7 @@ const _SolanaStakingClient = class _SolanaStakingClient {
|
|
|
8841
9062
|
}
|
|
8842
9063
|
async getDepositBuffer(options) {
|
|
8843
9064
|
this.ensureUser();
|
|
8844
|
-
const
|
|
8845
|
-
const balanceLamports = options?.balanceOverrideLamports ?? BigInt(await this.connection.getBalance(payer, commitment));
|
|
9065
|
+
const balanceLamports = options?.balanceOverrideLamports ?? BigInt(await this.connection.getBalance(this.feePayer, commitment));
|
|
8846
9066
|
if (balanceLamports <= BigInt(0)) {
|
|
8847
9067
|
return BigInt(0);
|
|
8848
9068
|
}
|
|
@@ -8898,7 +9118,7 @@ const _SolanaStakingClient = class _SolanaStakingClient {
|
|
|
8898
9118
|
if (this.cachedTxFee && now - this.cachedTxFee.fetchedAt < _SolanaStakingClient.FEE_CACHE_TTL_MS) {
|
|
8899
9119
|
return this.cachedTxFee.value;
|
|
8900
9120
|
}
|
|
8901
|
-
const payer = this.
|
|
9121
|
+
const payer = this.feePayer;
|
|
8902
9122
|
const dummyIx = SystemProgram.transfer({
|
|
8903
9123
|
fromPubkey: payer,
|
|
8904
9124
|
toPubkey: payer,
|
|
@@ -8953,17 +9173,16 @@ const _SolanaStakingClient = class _SolanaStakingClient {
|
|
|
8953
9173
|
async prepareTx(tx) {
|
|
8954
9174
|
const { blockhash, lastValidBlockHeight } = await this.connection.getLatestBlockhash("confirmed");
|
|
8955
9175
|
tx.recentBlockhash = blockhash;
|
|
8956
|
-
tx.feePayer = this.
|
|
9176
|
+
tx.feePayer = this.feePayer;
|
|
8957
9177
|
return { tx, blockhash, lastValidBlockHeight };
|
|
8958
9178
|
}
|
|
8959
9179
|
ensureUser() {
|
|
8960
|
-
if (!this.pubKey
|
|
8961
|
-
|
|
8962
|
-
|
|
8963
|
-
if (
|
|
8964
|
-
|
|
8965
|
-
|
|
8966
|
-
);
|
|
9180
|
+
if (!this.pubKey) throw new Error("User pubKey is undefined");
|
|
9181
|
+
const wallet = this.anchor?.wallet;
|
|
9182
|
+
const pk = wallet?.publicKey;
|
|
9183
|
+
if (!pk) throw new Error("Wallet not connected");
|
|
9184
|
+
if (typeof wallet.signTransaction !== "function") {
|
|
9185
|
+
throw new Error("Wallet does not support signTransaction");
|
|
8967
9186
|
}
|
|
8968
9187
|
}
|
|
8969
9188
|
};
|
|
@@ -34902,6 +35121,30 @@ class ConvertClient {
|
|
|
34902
35121
|
event
|
|
34903
35122
|
};
|
|
34904
35123
|
}
|
|
35124
|
+
async claimWithdraw(tokenId) {
|
|
35125
|
+
let tx, receipt;
|
|
35126
|
+
try {
|
|
35127
|
+
tx = await this.contract.DepositManager.claim(tokenId);
|
|
35128
|
+
receipt = await tx.wait(1);
|
|
35129
|
+
} catch (err) {
|
|
35130
|
+
let errorObj = formatContractErrors(err);
|
|
35131
|
+
throw new Error(errorObj.name ?? errorObj.raw);
|
|
35132
|
+
}
|
|
35133
|
+
let event;
|
|
35134
|
+
const ev = receipt.events?.find((e) => e.event === "Claimed");
|
|
35135
|
+
if (ev && ev.args) {
|
|
35136
|
+
const { sender, ethAmount } = ev.args;
|
|
35137
|
+
event = {
|
|
35138
|
+
sender,
|
|
35139
|
+
ethAmount: BigNumber.from(ethAmount)
|
|
35140
|
+
};
|
|
35141
|
+
}
|
|
35142
|
+
return {
|
|
35143
|
+
txHash: tx.hash,
|
|
35144
|
+
receipt,
|
|
35145
|
+
event
|
|
35146
|
+
};
|
|
35147
|
+
}
|
|
34905
35148
|
}
|
|
34906
35149
|
|
|
34907
35150
|
class StakeClient {
|
|
@@ -34922,12 +35165,13 @@ class StakeClient {
|
|
|
34922
35165
|
async performStake(amountWei, signerAddress) {
|
|
34923
35166
|
const depositor = this.contract.Depositor.address;
|
|
34924
35167
|
const liqRead = this.contract.LiqEthToken;
|
|
34925
|
-
await liqRead.balanceOf(signerAddress);
|
|
35168
|
+
const bal = await liqRead.balanceOf(signerAddress);
|
|
34926
35169
|
const allowance = await liqRead.allowance(signerAddress, depositor);
|
|
34927
35170
|
const paused = await this.contract.Depositor.paused();
|
|
34928
35171
|
if (paused) {
|
|
34929
35172
|
throw new Error("Error - Depositor is in a paused state");
|
|
34930
35173
|
}
|
|
35174
|
+
if (bal.lt(amountWei)) throw new Error("Insufficient LiqETH balance");
|
|
34931
35175
|
if (allowance.lt(amountWei)) {
|
|
34932
35176
|
const liqWrite = this.contractService.getWrite("LiqEthToken");
|
|
34933
35177
|
console.warn(`allowance insufficient (${allowance.toString()} < ${amountWei.toString()}); sending approve(${depositor}, ${amountWei.toString()})`);
|
|
@@ -35372,7 +35616,7 @@ class ReceiptClient {
|
|
|
35372
35616
|
}
|
|
35373
35617
|
async fetchPreLaunchReceipts(address, type) {
|
|
35374
35618
|
const receiptContract = this.contract.ReceiptNFT;
|
|
35375
|
-
const tokenIds = await this.
|
|
35619
|
+
const tokenIds = await this.getOwnedReceiptNFTsFor(address);
|
|
35376
35620
|
const results = [];
|
|
35377
35621
|
for (const idBN of tokenIds) {
|
|
35378
35622
|
try {
|
|
@@ -35405,7 +35649,7 @@ class ReceiptClient {
|
|
|
35405
35649
|
}
|
|
35406
35650
|
return results;
|
|
35407
35651
|
}
|
|
35408
|
-
async
|
|
35652
|
+
async getOwnedReceiptNFTsFor(owner, fromBlock = 0, toBlock = "latest") {
|
|
35409
35653
|
const receiptContract = this.contract.ReceiptNFT;
|
|
35410
35654
|
const toLogs = await receiptContract.queryFilter(
|
|
35411
35655
|
receiptContract.filters.Transfer(null, owner),
|
|
@@ -35430,6 +35674,56 @@ class ReceiptClient {
|
|
|
35430
35674
|
}
|
|
35431
35675
|
return Array.from(owned).map((id) => BigNumber.from(id));
|
|
35432
35676
|
}
|
|
35677
|
+
async fetchWithdrawReceipts(address) {
|
|
35678
|
+
const tokenIds = await this.getOwnedWithdrawReceiptsFor(address);
|
|
35679
|
+
const results = [];
|
|
35680
|
+
for (const idBN of tokenIds) {
|
|
35681
|
+
try {
|
|
35682
|
+
const receiptData = await this.contract.WithdrawalQueue.info(idBN);
|
|
35683
|
+
results.push({
|
|
35684
|
+
tokenId: idBN.toBigInt(),
|
|
35685
|
+
receipt: {
|
|
35686
|
+
ethAmount: receiptData.ethAmount,
|
|
35687
|
+
ethBalance: {
|
|
35688
|
+
amount: receiptData.ethAmount.toBigInt(),
|
|
35689
|
+
decimals: 18,
|
|
35690
|
+
symbol: "ETH"
|
|
35691
|
+
},
|
|
35692
|
+
readyAt: new Date(Number(receiptData.readyAt.toString()) * 1e3).valueOf()
|
|
35693
|
+
}
|
|
35694
|
+
});
|
|
35695
|
+
} catch (err) {
|
|
35696
|
+
console.warn(`Failed to load receipt for tokenId=${idBN.toString()}`, err);
|
|
35697
|
+
continue;
|
|
35698
|
+
}
|
|
35699
|
+
}
|
|
35700
|
+
return results;
|
|
35701
|
+
}
|
|
35702
|
+
async getOwnedWithdrawReceiptsFor(owner, fromBlock = 0, toBlock = "latest") {
|
|
35703
|
+
const contract = this.contract.WithdrawalQueue;
|
|
35704
|
+
const toLogs = await contract.queryFilter(
|
|
35705
|
+
contract.filters.Transfer(null, owner),
|
|
35706
|
+
fromBlock,
|
|
35707
|
+
toBlock
|
|
35708
|
+
);
|
|
35709
|
+
const fromLogs = await contract.queryFilter(
|
|
35710
|
+
contract.filters.Transfer(owner, null),
|
|
35711
|
+
fromBlock,
|
|
35712
|
+
toBlock
|
|
35713
|
+
);
|
|
35714
|
+
const owned = new Set();
|
|
35715
|
+
for (const e of toLogs) {
|
|
35716
|
+
const tokenId = e.args?.tokenId;
|
|
35717
|
+
if (!tokenId) continue;
|
|
35718
|
+
owned.add(tokenId.toString());
|
|
35719
|
+
}
|
|
35720
|
+
for (const e of fromLogs) {
|
|
35721
|
+
const tokenId = e.args?.tokenId;
|
|
35722
|
+
if (!tokenId) continue;
|
|
35723
|
+
owned.delete(tokenId.toString());
|
|
35724
|
+
}
|
|
35725
|
+
return Array.from(owned).map((id) => BigNumber.from(id));
|
|
35726
|
+
}
|
|
35433
35727
|
}
|
|
35434
35728
|
|
|
35435
35729
|
const INITIAL_TRANCHE_SUPPLY = 35e3;
|
|
@@ -35476,6 +35770,17 @@ class EthereumStakingClient {
|
|
|
35476
35770
|
const result = await this.convertClient.performWithdraw(address, amountWei);
|
|
35477
35771
|
return result.txHash;
|
|
35478
35772
|
}
|
|
35773
|
+
async loadPendingWithdraws() {
|
|
35774
|
+
this.ensureUser();
|
|
35775
|
+
const address = await this.signer.getAddress();
|
|
35776
|
+
return await this.receiptClient.fetchWithdrawReceipts(address);
|
|
35777
|
+
}
|
|
35778
|
+
async claimWithdraw(tokenId) {
|
|
35779
|
+
this.ensureUser();
|
|
35780
|
+
const tokenIdBigNum = BigNumber.from(tokenId);
|
|
35781
|
+
const result = await this.convertClient.claimWithdraw(tokenIdBigNum);
|
|
35782
|
+
return result.txHash;
|
|
35783
|
+
}
|
|
35479
35784
|
async stake(amount) {
|
|
35480
35785
|
this.ensureUser();
|
|
35481
35786
|
const walletAddress = await this.signer.getAddress();
|
|
@@ -35535,6 +35840,12 @@ class EthereumStakingClient {
|
|
|
35535
35840
|
}
|
|
35536
35841
|
let estimatedClaim = BigInt(0);
|
|
35537
35842
|
let estimatedYield = BigInt(0);
|
|
35843
|
+
if (userShares > BigInt(0) && currentIndex > BigInt(0)) {
|
|
35844
|
+
estimatedClaim = userShares * currentIndex / indexScale;
|
|
35845
|
+
if (estimatedClaim > stakeBalanceBN.toBigInt()) {
|
|
35846
|
+
estimatedYield = estimatedClaim - stakeBalanceBN.toBigInt();
|
|
35847
|
+
}
|
|
35848
|
+
}
|
|
35538
35849
|
const portfolio = {
|
|
35539
35850
|
native: {
|
|
35540
35851
|
amount: nativeBalance.toBigInt(),
|
|
@@ -35692,11 +36003,9 @@ class Staker {
|
|
|
35692
36003
|
if (!Array.isArray(config)) config = [config];
|
|
35693
36004
|
config.forEach((cfg) => {
|
|
35694
36005
|
switch (cfg.network.chainId) {
|
|
35695
|
-
case SolChainID.Mainnet:
|
|
35696
36006
|
case SolChainID.Devnet:
|
|
35697
36007
|
this.clients.set(cfg.network.chainId, new SolanaStakingClient(cfg));
|
|
35698
36008
|
break;
|
|
35699
|
-
case EvmChainID.Ethereum:
|
|
35700
36009
|
case EvmChainID.Hoodi:
|
|
35701
36010
|
this.clients.set(cfg.network.chainId, new EthereumStakingClient(cfg));
|
|
35702
36011
|
break;
|