@wireio/stake 2.2.1 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +185 -243
- package/lib/stake.browser.js +343 -202
- package/lib/stake.browser.js.map +1 -1
- package/lib/stake.d.ts +104 -23
- package/lib/stake.js +511 -331
- package/lib/stake.js.map +1 -1
- package/lib/stake.m.js +343 -202
- package/lib/stake.m.js.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +2 -2
- package/src/networks/ethereum/clients/receipt.client.ts +54 -69
- package/src/networks/ethereum/clients/validator.client.ts +61 -0
- package/src/networks/ethereum/ethereum.ts +21 -1
- package/src/networks/ethereum/types.ts +21 -17
- package/src/networks/solana/clients/convert.client.ts +339 -0
- package/src/networks/solana/solana.ts +35 -6
- package/src/networks/solana/types.ts +22 -0
- package/src/networks/solana/utils.ts +8 -1
- package/src/types.ts +40 -2
- package/src/networks/solana/clients/deposit.client.ts +0 -291
package/lib/stake.browser.js
CHANGED
|
@@ -1,175 +1,11 @@
|
|
|
1
1
|
import { SolChainID, PublicKey as PublicKey$1, KeyType, EvmChainID } from '@wireio/core';
|
|
2
|
-
import {
|
|
2
|
+
import { PublicKey, StakeProgram, Keypair, SystemProgram, SYSVAR_INSTRUCTIONS_PUBKEY, SYSVAR_CLOCK_PUBKEY, SYSVAR_STAKE_HISTORY_PUBKEY, SYSVAR_RENT_PUBKEY, Connection, ComputeBudgetProgram, TransactionMessage, Transaction, SendTransactionError } from '@solana/web3.js';
|
|
3
3
|
import { BN, Program, AnchorProvider } from '@coral-xyz/anchor';
|
|
4
|
-
import {
|
|
4
|
+
import { getAssociatedTokenAddress, TOKEN_2022_PROGRAM_ID, getAssociatedTokenAddressSync, ASSOCIATED_TOKEN_PROGRAM_ID } 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';
|
|
8
8
|
|
|
9
|
-
class DepositClient {
|
|
10
|
-
constructor(provider, pgs) {
|
|
11
|
-
this.provider = provider;
|
|
12
|
-
this.pgs = pgs;
|
|
13
|
-
this.program = pgs.getProgram("liqsolCore");
|
|
14
|
-
}
|
|
15
|
-
get connection() {
|
|
16
|
-
return this.provider.connection;
|
|
17
|
-
}
|
|
18
|
-
get wallet() {
|
|
19
|
-
return this.provider.wallet;
|
|
20
|
-
}
|
|
21
|
-
async buildDepositTx(amount, user = this.wallet.publicKey) {
|
|
22
|
-
if (!user) {
|
|
23
|
-
throw new Error(
|
|
24
|
-
"DepositClient.buildDepositTx: wallet not connected"
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
if (!amount || amount <= BigInt(0)) {
|
|
28
|
-
throw new Error(
|
|
29
|
-
"DepositClient.buildDepositTx: amount must be greater than zero."
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
const depositAuthority = this.pgs.deriveDepositAuthorityPda();
|
|
33
|
-
const liqsolMint = this.pgs.deriveLiqsolMintPda();
|
|
34
|
-
const liqsolMintAuthority = this.pgs.deriveLiqsolMintAuthorityPda();
|
|
35
|
-
const reservePool = this.pgs.deriveReservePoolPda();
|
|
36
|
-
const vault = this.pgs.deriveVaultPda();
|
|
37
|
-
const controllerState = this.pgs.deriveStakeControllerStatePda();
|
|
38
|
-
const payoutState = this.pgs.derivePayoutStatePda();
|
|
39
|
-
const bucketAuthority = this.pgs.deriveBucketAuthorityPda();
|
|
40
|
-
const payRateHistory = this.pgs.derivePayRateHistoryPda();
|
|
41
|
-
const globalConfig = this.pgs.deriveGlobalConfigPda();
|
|
42
|
-
const userAta = getAssociatedTokenAddressSync(
|
|
43
|
-
liqsolMint,
|
|
44
|
-
user,
|
|
45
|
-
true,
|
|
46
|
-
TOKEN_2022_PROGRAM_ID
|
|
47
|
-
);
|
|
48
|
-
const distributionState = this.pgs.deriveDistributionStatePda();
|
|
49
|
-
const userRecord = this.pgs.deriveUserRecordPda(userAta);
|
|
50
|
-
const bucketTokenAccount = getAssociatedTokenAddressSync(
|
|
51
|
-
liqsolMint,
|
|
52
|
-
bucketAuthority,
|
|
53
|
-
true,
|
|
54
|
-
TOKEN_2022_PROGRAM_ID
|
|
55
|
-
);
|
|
56
|
-
const seed = Math.floor(Math.random() * 2 ** 32);
|
|
57
|
-
const ephemeralStake = await this.pgs.deriveEphemeralStakeAddress(user, seed);
|
|
58
|
-
return await this.program.methods.deposit(new BN(amount.toString()), seed).accounts({
|
|
59
|
-
user,
|
|
60
|
-
depositAuthority,
|
|
61
|
-
systemProgram: SystemProgram.programId,
|
|
62
|
-
tokenProgram: TOKEN_2022_PROGRAM_ID,
|
|
63
|
-
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
64
|
-
liqsolProgram: this.pgs.PROGRAM_IDS.LIQSOL_TOKEN,
|
|
65
|
-
stakeProgram: StakeProgram.programId,
|
|
66
|
-
liqsolMint,
|
|
67
|
-
userAta,
|
|
68
|
-
liqsolMintAuthority,
|
|
69
|
-
reservePool,
|
|
70
|
-
vault,
|
|
71
|
-
ephemeralStake,
|
|
72
|
-
controllerState,
|
|
73
|
-
payoutState,
|
|
74
|
-
bucketAuthority,
|
|
75
|
-
bucketTokenAccount,
|
|
76
|
-
userRecord,
|
|
77
|
-
distributionState,
|
|
78
|
-
payRateHistory,
|
|
79
|
-
instructionsSysvar: SYSVAR_INSTRUCTIONS_PUBKEY,
|
|
80
|
-
clock: SYSVAR_CLOCK_PUBKEY,
|
|
81
|
-
stakeHistory: SYSVAR_STAKE_HISTORY_PUBKEY,
|
|
82
|
-
rent: SYSVAR_RENT_PUBKEY,
|
|
83
|
-
globalConfig
|
|
84
|
-
}).instruction();
|
|
85
|
-
}
|
|
86
|
-
async buildWithdrawTx(amount, user = this.wallet.publicKey) {
|
|
87
|
-
if (!user) {
|
|
88
|
-
throw new Error(
|
|
89
|
-
"DepositClient.buildWithdrawTx: wallet not connected"
|
|
90
|
-
);
|
|
91
|
-
}
|
|
92
|
-
if (!amount || amount <= BigInt(0)) {
|
|
93
|
-
throw new Error(
|
|
94
|
-
"DepositClient.buildWithdrawTx: amount must be greater than zero."
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
const liqsolMint = this.pgs.deriveLiqsolMintPda();
|
|
98
|
-
const userAta = getAssociatedTokenAddressSync(
|
|
99
|
-
liqsolMint,
|
|
100
|
-
user,
|
|
101
|
-
true,
|
|
102
|
-
TOKEN_2022_PROGRAM_ID
|
|
103
|
-
);
|
|
104
|
-
const userRecord = this.pgs.deriveUserRecordPda(userAta);
|
|
105
|
-
const distributionState = this.pgs.deriveDistributionStatePda();
|
|
106
|
-
const global = this.pgs.deriveWithdrawGlobalPda();
|
|
107
|
-
const reservePool = this.pgs.deriveReservePoolPda();
|
|
108
|
-
const stakeAllocationState = this.pgs.deriveStakeAllocationStatePda();
|
|
109
|
-
const stakeMetrics = this.pgs.deriveStakeMetricsPda();
|
|
110
|
-
const maintenanceLedger = this.pgs.deriveMaintenanceLedgerPda();
|
|
111
|
-
const globalConfig = this.pgs.deriveGlobalConfigPda();
|
|
112
|
-
const globalAcct = await this.program.account.global.fetch(global);
|
|
113
|
-
const rawId = globalAcct.nextReceiptId;
|
|
114
|
-
let receiptId;
|
|
115
|
-
if (typeof rawId === "bigint") {
|
|
116
|
-
receiptId = rawId;
|
|
117
|
-
} else if (rawId != null && typeof rawId === "object" && "toString" in rawId) {
|
|
118
|
-
receiptId = BigInt(rawId.toString());
|
|
119
|
-
} else if (typeof rawId === "number") {
|
|
120
|
-
receiptId = BigInt(rawId);
|
|
121
|
-
} else {
|
|
122
|
-
throw new Error(
|
|
123
|
-
`DepositClient.buildWithdrawTx: unexpected nextReceiptId type (${typeof rawId})`
|
|
124
|
-
);
|
|
125
|
-
}
|
|
126
|
-
const mintAuthority = this.pgs.deriveWithdrawMintAuthorityPda();
|
|
127
|
-
const metadata = this.pgs.deriveWithdrawMintMetadataPda();
|
|
128
|
-
const nftMint = this.pgs.deriveWithdrawNftMintPda(receiptId);
|
|
129
|
-
const receiptData = this.pgs.deriveLiqReceiptDataPda(nftMint);
|
|
130
|
-
const owner = user;
|
|
131
|
-
const nftAta = getAssociatedTokenAddressSync(
|
|
132
|
-
nftMint,
|
|
133
|
-
owner,
|
|
134
|
-
true,
|
|
135
|
-
TOKEN_2022_PROGRAM_ID
|
|
136
|
-
);
|
|
137
|
-
const bucketAuthority = this.pgs.deriveBucketAuthorityPda();
|
|
138
|
-
const bucketTokenAccount = getAssociatedTokenAddressSync(
|
|
139
|
-
liqsolMint,
|
|
140
|
-
bucketAuthority,
|
|
141
|
-
true,
|
|
142
|
-
TOKEN_2022_PROGRAM_ID
|
|
143
|
-
);
|
|
144
|
-
return await this.program.methods.requestWithdraw(new BN(amount.toString())).accounts({
|
|
145
|
-
user,
|
|
146
|
-
owner,
|
|
147
|
-
global,
|
|
148
|
-
liqsolMint,
|
|
149
|
-
userAta,
|
|
150
|
-
userRecord,
|
|
151
|
-
reservePool,
|
|
152
|
-
stakeAllocationState,
|
|
153
|
-
stakeMetrics,
|
|
154
|
-
maintenanceLedger,
|
|
155
|
-
clock: SYSVAR_CLOCK_PUBKEY,
|
|
156
|
-
mintAuthority,
|
|
157
|
-
receiptData,
|
|
158
|
-
metadata,
|
|
159
|
-
nftMint,
|
|
160
|
-
nftAta,
|
|
161
|
-
distributionState,
|
|
162
|
-
bucketTokenAccount,
|
|
163
|
-
tokenProgram: TOKEN_2022_PROGRAM_ID,
|
|
164
|
-
tokenInterface: TOKEN_2022_PROGRAM_ID,
|
|
165
|
-
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
166
|
-
systemProgram: SystemProgram.programId,
|
|
167
|
-
rent: SYSVAR_RENT_PUBKEY,
|
|
168
|
-
globalConfig
|
|
169
|
-
}).instruction();
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
9
|
var address$7 = "5nBtmutQLrRKBUxNfHJPDjiW5u8id6QM9Hhjg1D1g1XH";
|
|
174
10
|
var metadata$7 = {
|
|
175
11
|
name: "liqsol_core",
|
|
@@ -14958,6 +14794,251 @@ function ceilDiv(n, d) {
|
|
|
14958
14794
|
}
|
|
14959
14795
|
return n.add(d.subn(1)).div(d);
|
|
14960
14796
|
}
|
|
14797
|
+
function normalizeToBigInt(x) {
|
|
14798
|
+
if (typeof x === "bigint") return x;
|
|
14799
|
+
if (x != null && typeof x === "object" && "toString" in x) return BigInt(x.toString());
|
|
14800
|
+
if (typeof x === "number") return BigInt(x);
|
|
14801
|
+
throw new Error(`normalizeToBigInt: unsupported type ${typeof x}`);
|
|
14802
|
+
}
|
|
14803
|
+
|
|
14804
|
+
let ConvertClient$1 = class ConvertClient {
|
|
14805
|
+
constructor(provider, pgs) {
|
|
14806
|
+
this.provider = provider;
|
|
14807
|
+
this.pgs = pgs;
|
|
14808
|
+
this.program = pgs.getProgram("liqsolCore");
|
|
14809
|
+
}
|
|
14810
|
+
get connection() {
|
|
14811
|
+
return this.provider.connection;
|
|
14812
|
+
}
|
|
14813
|
+
get wallet() {
|
|
14814
|
+
return this.provider.wallet;
|
|
14815
|
+
}
|
|
14816
|
+
async buildDepositTx(amount, user = this.wallet.publicKey) {
|
|
14817
|
+
if (!user) throw new Error("ConvertClient.buildDepositTx: wallet not connected");
|
|
14818
|
+
if (!amount || amount <= BigInt(0))
|
|
14819
|
+
throw new Error("ConvertClient.buildDepositTx: amount must be greater than zero.");
|
|
14820
|
+
const depositAuthority = this.pgs.deriveDepositAuthorityPda();
|
|
14821
|
+
const liqsolMint = this.pgs.deriveLiqsolMintPda();
|
|
14822
|
+
const liqsolMintAuthority = this.pgs.deriveLiqsolMintAuthorityPda();
|
|
14823
|
+
const reservePool = this.pgs.deriveReservePoolPda();
|
|
14824
|
+
const vault = this.pgs.deriveVaultPda();
|
|
14825
|
+
const controllerState = this.pgs.deriveStakeControllerStatePda();
|
|
14826
|
+
const payoutState = this.pgs.derivePayoutStatePda();
|
|
14827
|
+
const bucketAuthority = this.pgs.deriveBucketAuthorityPda();
|
|
14828
|
+
const payRateHistory = this.pgs.derivePayRateHistoryPda();
|
|
14829
|
+
const globalConfig = this.pgs.deriveGlobalConfigPda();
|
|
14830
|
+
const userAta = getAssociatedTokenAddressSync(liqsolMint, user, true, TOKEN_2022_PROGRAM_ID);
|
|
14831
|
+
const distributionState = this.pgs.deriveDistributionStatePda();
|
|
14832
|
+
const userRecord = this.pgs.deriveUserRecordPda(userAta);
|
|
14833
|
+
const bucketTokenAccount = getAssociatedTokenAddressSync(
|
|
14834
|
+
liqsolMint,
|
|
14835
|
+
bucketAuthority,
|
|
14836
|
+
true,
|
|
14837
|
+
TOKEN_2022_PROGRAM_ID
|
|
14838
|
+
);
|
|
14839
|
+
const seed = Math.floor(Math.random() * 2 ** 32);
|
|
14840
|
+
const ephemeralStake = await this.pgs.deriveEphemeralStakeAddress(user, seed);
|
|
14841
|
+
return await this.program.methods.deposit(new BN(amount.toString()), seed).accounts({
|
|
14842
|
+
user,
|
|
14843
|
+
depositAuthority,
|
|
14844
|
+
systemProgram: SystemProgram.programId,
|
|
14845
|
+
tokenProgram: TOKEN_2022_PROGRAM_ID,
|
|
14846
|
+
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
14847
|
+
liqsolProgram: this.pgs.PROGRAM_IDS.LIQSOL_TOKEN,
|
|
14848
|
+
stakeProgram: StakeProgram.programId,
|
|
14849
|
+
liqsolMint,
|
|
14850
|
+
userAta,
|
|
14851
|
+
liqsolMintAuthority,
|
|
14852
|
+
reservePool,
|
|
14853
|
+
vault,
|
|
14854
|
+
ephemeralStake,
|
|
14855
|
+
controllerState,
|
|
14856
|
+
payoutState,
|
|
14857
|
+
bucketAuthority,
|
|
14858
|
+
bucketTokenAccount,
|
|
14859
|
+
userRecord,
|
|
14860
|
+
distributionState,
|
|
14861
|
+
payRateHistory,
|
|
14862
|
+
instructionsSysvar: SYSVAR_INSTRUCTIONS_PUBKEY,
|
|
14863
|
+
clock: SYSVAR_CLOCK_PUBKEY,
|
|
14864
|
+
stakeHistory: SYSVAR_STAKE_HISTORY_PUBKEY,
|
|
14865
|
+
rent: SYSVAR_RENT_PUBKEY,
|
|
14866
|
+
globalConfig
|
|
14867
|
+
}).instruction();
|
|
14868
|
+
}
|
|
14869
|
+
async buildWithdrawTx(amount, user = this.wallet.publicKey) {
|
|
14870
|
+
if (!user) throw new Error("ConvertClient.buildWithdrawTx: wallet not connected");
|
|
14871
|
+
if (!amount || amount <= BigInt(0))
|
|
14872
|
+
throw new Error("ConvertClient.buildWithdrawTx: amount must be greater than zero.");
|
|
14873
|
+
const liqsolMint = this.pgs.deriveLiqsolMintPda();
|
|
14874
|
+
const userAta = getAssociatedTokenAddressSync(liqsolMint, user, true, TOKEN_2022_PROGRAM_ID);
|
|
14875
|
+
const userRecord = this.pgs.deriveUserRecordPda(userAta);
|
|
14876
|
+
const distributionState = this.pgs.deriveDistributionStatePda();
|
|
14877
|
+
const global = this.pgs.deriveWithdrawGlobalPda();
|
|
14878
|
+
const reservePool = this.pgs.deriveReservePoolPda();
|
|
14879
|
+
const stakeAllocationState = this.pgs.deriveStakeAllocationStatePda();
|
|
14880
|
+
const stakeMetrics = this.pgs.deriveStakeMetricsPda();
|
|
14881
|
+
const maintenanceLedger = this.pgs.deriveMaintenanceLedgerPda();
|
|
14882
|
+
const globalConfig = this.pgs.deriveGlobalConfigPda();
|
|
14883
|
+
const globalAcct = await this.program.account.global.fetch(global);
|
|
14884
|
+
const rawId = globalAcct.nextReceiptId;
|
|
14885
|
+
const receiptId = normalizeToBigInt(rawId);
|
|
14886
|
+
const mintAuthority = this.pgs.deriveWithdrawMintAuthorityPda();
|
|
14887
|
+
const metadata = this.pgs.deriveWithdrawMintMetadataPda();
|
|
14888
|
+
const nftMint = this.pgs.deriveWithdrawNftMintPda(receiptId);
|
|
14889
|
+
const receiptData = this.pgs.deriveLiqReceiptDataPda(nftMint);
|
|
14890
|
+
const owner = user;
|
|
14891
|
+
const nftAta = getAssociatedTokenAddressSync(nftMint, owner, true, TOKEN_2022_PROGRAM_ID);
|
|
14892
|
+
const bucketAuthority = this.pgs.deriveBucketAuthorityPda();
|
|
14893
|
+
const bucketTokenAccount = getAssociatedTokenAddressSync(
|
|
14894
|
+
liqsolMint,
|
|
14895
|
+
bucketAuthority,
|
|
14896
|
+
true,
|
|
14897
|
+
TOKEN_2022_PROGRAM_ID
|
|
14898
|
+
);
|
|
14899
|
+
return await this.program.methods.requestWithdraw(new BN(amount.toString())).accounts({
|
|
14900
|
+
user,
|
|
14901
|
+
owner,
|
|
14902
|
+
global,
|
|
14903
|
+
liqsolMint,
|
|
14904
|
+
userAta,
|
|
14905
|
+
userRecord,
|
|
14906
|
+
reservePool,
|
|
14907
|
+
stakeAllocationState,
|
|
14908
|
+
stakeMetrics,
|
|
14909
|
+
maintenanceLedger,
|
|
14910
|
+
clock: SYSVAR_CLOCK_PUBKEY,
|
|
14911
|
+
mintAuthority,
|
|
14912
|
+
receiptData,
|
|
14913
|
+
metadata,
|
|
14914
|
+
nftMint,
|
|
14915
|
+
nftAta,
|
|
14916
|
+
distributionState,
|
|
14917
|
+
bucketTokenAccount,
|
|
14918
|
+
tokenProgram: TOKEN_2022_PROGRAM_ID,
|
|
14919
|
+
tokenInterface: TOKEN_2022_PROGRAM_ID,
|
|
14920
|
+
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
14921
|
+
systemProgram: SystemProgram.programId,
|
|
14922
|
+
rent: SYSVAR_RENT_PUBKEY,
|
|
14923
|
+
globalConfig
|
|
14924
|
+
}).instruction();
|
|
14925
|
+
}
|
|
14926
|
+
async fetchWithdrawReceipts(owner) {
|
|
14927
|
+
const globalPda = this.pgs.deriveWithdrawGlobalPda();
|
|
14928
|
+
const globalAcct = await this.program.account.global.fetch(globalPda);
|
|
14929
|
+
const nextId = normalizeToBigInt(globalAcct.nextReceiptId);
|
|
14930
|
+
const mintToId = new Map();
|
|
14931
|
+
for (let i = BigInt(0); i < nextId; i++) {
|
|
14932
|
+
const mint = this.pgs.deriveWithdrawNftMintPda(i);
|
|
14933
|
+
mintToId.set(mint.toBase58(), i);
|
|
14934
|
+
}
|
|
14935
|
+
const tokenAccounts = await this.connection.getParsedTokenAccountsByOwner(owner, {
|
|
14936
|
+
programId: TOKEN_2022_PROGRAM_ID
|
|
14937
|
+
});
|
|
14938
|
+
const receipts = [];
|
|
14939
|
+
for (const { pubkey, account } of tokenAccounts.value) {
|
|
14940
|
+
const info = account.data?.["parsed"]?.info;
|
|
14941
|
+
if (!info) continue;
|
|
14942
|
+
const amount = info.tokenAmount;
|
|
14943
|
+
const decimals = Number(amount?.decimals ?? 0);
|
|
14944
|
+
const uiAmount = Number(amount?.uiAmount ?? 0);
|
|
14945
|
+
if (decimals !== 0 || uiAmount !== 1) continue;
|
|
14946
|
+
const mintStr = info.mint;
|
|
14947
|
+
if (!mintStr) continue;
|
|
14948
|
+
const receiptId = mintToId.get(mintStr);
|
|
14949
|
+
if (receiptId === void 0) continue;
|
|
14950
|
+
const mintKey = new PublicKey(mintStr);
|
|
14951
|
+
const receiptDataPda = this.pgs.deriveLiqReceiptDataPda(mintKey);
|
|
14952
|
+
let receiptData;
|
|
14953
|
+
try {
|
|
14954
|
+
const raw = await this.program.account.liqReceiptData.fetch(receiptDataPda);
|
|
14955
|
+
receiptData = {
|
|
14956
|
+
receiptId: normalizeToBigInt(raw.receiptId),
|
|
14957
|
+
liqports: normalizeToBigInt(raw.liqports),
|
|
14958
|
+
epoch: normalizeToBigInt(raw.epoch),
|
|
14959
|
+
fulfilled: Boolean(raw.fulfilled)
|
|
14960
|
+
};
|
|
14961
|
+
} catch (err) {
|
|
14962
|
+
console.warn(`ConvertClient: failed to fetch receipt data for mint ${mintStr}`, err);
|
|
14963
|
+
continue;
|
|
14964
|
+
}
|
|
14965
|
+
const { etaMs, readyAtMs } = await this.estimateEpochEta(receiptData.epoch);
|
|
14966
|
+
const status = receiptData.fulfilled ? "claimed" : etaMs <= 0 ? "ready" : "queued";
|
|
14967
|
+
const amountView = {
|
|
14968
|
+
amount: receiptData.liqports,
|
|
14969
|
+
decimals: 9,
|
|
14970
|
+
symbol: "SOL"
|
|
14971
|
+
};
|
|
14972
|
+
receipts.push({
|
|
14973
|
+
tokenId: receiptData.receiptId,
|
|
14974
|
+
receipt: {
|
|
14975
|
+
amount: amountView,
|
|
14976
|
+
readyAt: readyAtMs,
|
|
14977
|
+
chain: "SOL",
|
|
14978
|
+
epoch: receiptData.epoch,
|
|
14979
|
+
status,
|
|
14980
|
+
mint: mintKey.toBase58(),
|
|
14981
|
+
ownerAta: pubkey.toBase58()
|
|
14982
|
+
}
|
|
14983
|
+
});
|
|
14984
|
+
}
|
|
14985
|
+
return receipts;
|
|
14986
|
+
}
|
|
14987
|
+
async buildClaimWithdrawTx(receiptId, user) {
|
|
14988
|
+
const mintAccount = this.pgs.deriveWithdrawNftMintPda(receiptId);
|
|
14989
|
+
const receiptData = this.pgs.deriveLiqReceiptDataPda(mintAccount);
|
|
14990
|
+
const ownerAta = getAssociatedTokenAddressSync(
|
|
14991
|
+
mintAccount,
|
|
14992
|
+
user,
|
|
14993
|
+
true,
|
|
14994
|
+
TOKEN_2022_PROGRAM_ID
|
|
14995
|
+
);
|
|
14996
|
+
const accounts = {
|
|
14997
|
+
user,
|
|
14998
|
+
global: this.pgs.deriveWithdrawGlobalPda(),
|
|
14999
|
+
mintAuthority: this.pgs.deriveWithdrawMintAuthorityPda(),
|
|
15000
|
+
receiptData,
|
|
15001
|
+
mintAccount,
|
|
15002
|
+
ownerAta,
|
|
15003
|
+
reservePool: this.pgs.deriveReservePoolPda(),
|
|
15004
|
+
vault: this.pgs.deriveVaultPda(),
|
|
15005
|
+
clock: SYSVAR_CLOCK_PUBKEY,
|
|
15006
|
+
stakeHistory: SYSVAR_STAKE_HISTORY_PUBKEY,
|
|
15007
|
+
globalConfig: this.pgs.deriveGlobalConfigPda(),
|
|
15008
|
+
tokenProgram: TOKEN_2022_PROGRAM_ID,
|
|
15009
|
+
stakeProgram: StakeProgram.programId,
|
|
15010
|
+
systemProgram: SystemProgram.programId,
|
|
15011
|
+
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID
|
|
15012
|
+
};
|
|
15013
|
+
return this.program.methods.claimWithdraw().accounts(accounts).instruction();
|
|
15014
|
+
}
|
|
15015
|
+
async estimateEpochEta(targetEpoch) {
|
|
15016
|
+
const conn = this.connection;
|
|
15017
|
+
const epochInfo = await conn.getEpochInfo();
|
|
15018
|
+
const schedule = await conn.getEpochSchedule();
|
|
15019
|
+
const currentEpoch = BigInt(epochInfo.epoch);
|
|
15020
|
+
if (targetEpoch <= currentEpoch) {
|
|
15021
|
+
const now = Date.now();
|
|
15022
|
+
return { etaMs: 0, readyAtMs: now };
|
|
15023
|
+
}
|
|
15024
|
+
let slotTimeSec = 0.4;
|
|
15025
|
+
try {
|
|
15026
|
+
const samples = await conn.getRecentPerformanceSamples(1);
|
|
15027
|
+
if (samples?.length) {
|
|
15028
|
+
const s = samples[0];
|
|
15029
|
+
slotTimeSec = s.numSlots > 0 ? s.samplePeriodSecs / s.numSlots : slotTimeSec;
|
|
15030
|
+
}
|
|
15031
|
+
} catch (_) {
|
|
15032
|
+
}
|
|
15033
|
+
const slotsPerEpoch = BigInt(schedule.slotsPerEpoch);
|
|
15034
|
+
const slotsRemainingInCurrent = slotsPerEpoch - BigInt(epochInfo.slotIndex);
|
|
15035
|
+
const epochsRemaining = targetEpoch - currentEpoch - BigInt(1);
|
|
15036
|
+
const slotsRemaining = (epochsRemaining > 0 ? epochsRemaining * slotsPerEpoch : BigInt(0)) + slotsRemainingInCurrent;
|
|
15037
|
+
const etaSeconds = Number(slotsRemaining) * slotTimeSec;
|
|
15038
|
+
const etaMs = Math.max(0, Math.round(etaSeconds * 1e3));
|
|
15039
|
+
return { etaMs, readyAtMs: Date.now() + etaMs };
|
|
15040
|
+
}
|
|
15041
|
+
};
|
|
14961
15042
|
|
|
14962
15043
|
class DistributionClient {
|
|
14963
15044
|
constructor(provider, pgs) {
|
|
@@ -15729,7 +15810,7 @@ const _SolanaStakingClient = class _SolanaStakingClient {
|
|
|
15729
15810
|
commitment
|
|
15730
15811
|
});
|
|
15731
15812
|
this.program = new SolanaProgramService(this.anchor, config.network.chainId);
|
|
15732
|
-
this.
|
|
15813
|
+
this.convertClient = new ConvertClient$1(this.anchor, this.program);
|
|
15733
15814
|
this.distributionClient = new DistributionClient(this.anchor, this.program);
|
|
15734
15815
|
this.leaderboardClient = new LeaderboardClient(this.anchor, this.program);
|
|
15735
15816
|
this.outpostClient = new OutpostClient(this.anchor, this.program);
|
|
@@ -15756,7 +15837,7 @@ const _SolanaStakingClient = class _SolanaStakingClient {
|
|
|
15756
15837
|
if (amountLamports <= BigInt(0))
|
|
15757
15838
|
throw new Error("Deposit amount must be greater than zero.");
|
|
15758
15839
|
try {
|
|
15759
|
-
const ix = await this.
|
|
15840
|
+
const ix = await this.convertClient.buildDepositTx(amountLamports, this.squadsVaultPDA);
|
|
15760
15841
|
return !!this.squadsX ? await this.sendSquadsIxs(ix) : await this.buildAndSendIx(ix);
|
|
15761
15842
|
} catch (err) {
|
|
15762
15843
|
console.log(`Failed to deposit Solana: ${err}`);
|
|
@@ -15768,13 +15849,29 @@ const _SolanaStakingClient = class _SolanaStakingClient {
|
|
|
15768
15849
|
if (amountLamports <= BigInt(0))
|
|
15769
15850
|
throw new Error("Withdraw amount must be greater than zero.");
|
|
15770
15851
|
try {
|
|
15771
|
-
const ix = await this.
|
|
15852
|
+
const ix = await this.convertClient.buildWithdrawTx(amountLamports, this.squadsVaultPDA);
|
|
15772
15853
|
return !!this.squadsX ? await this.sendSquadsIxs(ix) : await this.buildAndSendIx(ix);
|
|
15773
15854
|
} catch (err) {
|
|
15774
15855
|
console.log(`Failed to withdraw Solana: ${err}`);
|
|
15775
15856
|
throw err;
|
|
15776
15857
|
}
|
|
15777
15858
|
}
|
|
15859
|
+
async getPendingWithdraws() {
|
|
15860
|
+
this.ensureUser();
|
|
15861
|
+
const owner = this.squadsVaultPDA ?? this.anchor.wallet.publicKey;
|
|
15862
|
+
return await this.convertClient.fetchWithdrawReceipts(owner);
|
|
15863
|
+
}
|
|
15864
|
+
async claimWithdraw(tokenId) {
|
|
15865
|
+
this.ensureUser();
|
|
15866
|
+
const owner = this.squadsVaultPDA ?? this.anchor.wallet.publicKey;
|
|
15867
|
+
try {
|
|
15868
|
+
const ix = await this.convertClient.buildClaimWithdrawTx(tokenId, owner);
|
|
15869
|
+
return !!this.squadsX ? await this.sendSquadsIxs(ix) : await this.buildAndSendIx(ix);
|
|
15870
|
+
} catch (err) {
|
|
15871
|
+
console.log(`Failed to claim withdraw on Solana: ${err}`);
|
|
15872
|
+
throw err;
|
|
15873
|
+
}
|
|
15874
|
+
}
|
|
15778
15875
|
async stake(amountLamports) {
|
|
15779
15876
|
this.ensureUser();
|
|
15780
15877
|
if (!amountLamports || amountLamports <= BigInt(0))
|
|
@@ -41289,47 +41386,25 @@ class ReceiptClient {
|
|
|
41289
41386
|
}
|
|
41290
41387
|
return results;
|
|
41291
41388
|
}
|
|
41292
|
-
async getOwnedReceiptNFTsFor(owner, fromBlock = 0, toBlock = "latest") {
|
|
41293
|
-
const receiptContract = this.contract.ReceiptNFT;
|
|
41294
|
-
const toLogs = await receiptContract.queryFilter(
|
|
41295
|
-
receiptContract.filters.Transfer(null, owner),
|
|
41296
|
-
fromBlock,
|
|
41297
|
-
toBlock
|
|
41298
|
-
);
|
|
41299
|
-
const fromLogs = await receiptContract.queryFilter(
|
|
41300
|
-
receiptContract.filters.Transfer(owner, null),
|
|
41301
|
-
fromBlock,
|
|
41302
|
-
toBlock
|
|
41303
|
-
);
|
|
41304
|
-
const owned = new Set();
|
|
41305
|
-
for (const e of toLogs) {
|
|
41306
|
-
const tokenId = e.args?.tokenId;
|
|
41307
|
-
if (!tokenId) continue;
|
|
41308
|
-
owned.add(tokenId.toString());
|
|
41309
|
-
}
|
|
41310
|
-
for (const e of fromLogs) {
|
|
41311
|
-
const tokenId = e.args?.tokenId;
|
|
41312
|
-
if (!tokenId) continue;
|
|
41313
|
-
owned.delete(tokenId.toString());
|
|
41314
|
-
}
|
|
41315
|
-
return Array.from(owned).map((id) => BigNumber.from(id));
|
|
41316
|
-
}
|
|
41317
41389
|
async fetchWithdrawReceipts(address) {
|
|
41318
41390
|
const tokenIds = await this.getOwnedWithdrawReceiptsFor(address);
|
|
41319
41391
|
const results = [];
|
|
41320
41392
|
for (const idBN of tokenIds) {
|
|
41321
41393
|
try {
|
|
41322
41394
|
const receiptData = await this.contract.WithdrawalQueue.info(idBN);
|
|
41395
|
+
const readyAtMs = Number(receiptData.readyAt) * 1e3;
|
|
41396
|
+
const status = readyAtMs <= Date.now() ? "ready" : "queued";
|
|
41323
41397
|
results.push({
|
|
41324
41398
|
tokenId: idBN.toBigInt(),
|
|
41325
41399
|
receipt: {
|
|
41326
|
-
|
|
41327
|
-
ethBalance: {
|
|
41400
|
+
amount: {
|
|
41328
41401
|
amount: receiptData.ethAmount.toBigInt(),
|
|
41329
41402
|
decimals: 18,
|
|
41330
41403
|
symbol: "ETH"
|
|
41331
41404
|
},
|
|
41332
|
-
readyAt:
|
|
41405
|
+
readyAt: readyAtMs,
|
|
41406
|
+
chain: "ETH",
|
|
41407
|
+
status
|
|
41333
41408
|
}
|
|
41334
41409
|
});
|
|
41335
41410
|
} catch (err) {
|
|
@@ -41364,6 +41439,66 @@ class ReceiptClient {
|
|
|
41364
41439
|
}
|
|
41365
41440
|
return Array.from(owned).map((id) => BigNumber.from(id));
|
|
41366
41441
|
}
|
|
41442
|
+
async getOwnedReceiptNFTsFor(owner, fromBlock = 0, toBlock = "latest") {
|
|
41443
|
+
const receiptContract = this.contract.ReceiptNFT;
|
|
41444
|
+
const toLogs = await receiptContract.queryFilter(
|
|
41445
|
+
receiptContract.filters.Transfer(null, owner),
|
|
41446
|
+
fromBlock,
|
|
41447
|
+
toBlock
|
|
41448
|
+
);
|
|
41449
|
+
const fromLogs = await receiptContract.queryFilter(
|
|
41450
|
+
receiptContract.filters.Transfer(owner, null),
|
|
41451
|
+
fromBlock,
|
|
41452
|
+
toBlock
|
|
41453
|
+
);
|
|
41454
|
+
const owned = new Set();
|
|
41455
|
+
for (const e of toLogs) {
|
|
41456
|
+
const tokenId = e.args?.tokenId;
|
|
41457
|
+
if (!tokenId) continue;
|
|
41458
|
+
owned.add(tokenId.toString());
|
|
41459
|
+
}
|
|
41460
|
+
for (const e of fromLogs) {
|
|
41461
|
+
const tokenId = e.args?.tokenId;
|
|
41462
|
+
if (!tokenId) continue;
|
|
41463
|
+
owned.delete(tokenId.toString());
|
|
41464
|
+
}
|
|
41465
|
+
return Array.from(owned).map((id) => BigNumber.from(id));
|
|
41466
|
+
}
|
|
41467
|
+
}
|
|
41468
|
+
|
|
41469
|
+
class ValidatorClient {
|
|
41470
|
+
get contract() {
|
|
41471
|
+
return this.contractService.contract;
|
|
41472
|
+
}
|
|
41473
|
+
constructor(contract) {
|
|
41474
|
+
this.contractService = contract;
|
|
41475
|
+
}
|
|
41476
|
+
async validatorDepositAndLockBond() {
|
|
41477
|
+
const amountWei = ethers.utils.parseEther("32");
|
|
41478
|
+
try {
|
|
41479
|
+
await this.contract.DepositManager.callStatic.validatorDepositAndLockBond({ value: amountWei });
|
|
41480
|
+
} catch (err) {
|
|
41481
|
+
let errorObj = formatContractErrors(err);
|
|
41482
|
+
throw new Error(errorObj.name ?? errorObj.raw);
|
|
41483
|
+
}
|
|
41484
|
+
const tx = await this.contract.DepositManager.validatorDepositAndLockBond({ value: amountWei });
|
|
41485
|
+
const receipt = await tx.wait(1);
|
|
41486
|
+
let staked;
|
|
41487
|
+
const ev = receipt.events?.find((e) => e.event === "Staked");
|
|
41488
|
+
if (ev && ev.args) {
|
|
41489
|
+
const { sender, amount, shares } = ev.args;
|
|
41490
|
+
staked = {
|
|
41491
|
+
sender,
|
|
41492
|
+
amount: BigNumber.from(amount),
|
|
41493
|
+
shares: BigNumber.from(shares)
|
|
41494
|
+
};
|
|
41495
|
+
}
|
|
41496
|
+
return {
|
|
41497
|
+
txHash: tx.hash,
|
|
41498
|
+
receipt,
|
|
41499
|
+
staked
|
|
41500
|
+
};
|
|
41501
|
+
}
|
|
41367
41502
|
}
|
|
41368
41503
|
|
|
41369
41504
|
const INITIAL_TRANCHE_SUPPLY = 35e3;
|
|
@@ -41388,6 +41523,7 @@ class EthereumStakingClient {
|
|
|
41388
41523
|
this.stakeClient = new StakeClient(this.contractService);
|
|
41389
41524
|
this.oppClient = new OPPClient(this.contractService);
|
|
41390
41525
|
this.receiptClient = new ReceiptClient(this.contractService);
|
|
41526
|
+
this.validatorClient = new ValidatorClient(this.contractService);
|
|
41391
41527
|
} catch (error) {
|
|
41392
41528
|
throw error;
|
|
41393
41529
|
}
|
|
@@ -41411,7 +41547,7 @@ class EthereumStakingClient {
|
|
|
41411
41547
|
const result = await this.convertClient.performWithdraw(address, amountWei);
|
|
41412
41548
|
return result.txHash;
|
|
41413
41549
|
}
|
|
41414
|
-
async
|
|
41550
|
+
async getPendingWithdraws() {
|
|
41415
41551
|
this.ensureUser();
|
|
41416
41552
|
const address = await this.signer.getAddress();
|
|
41417
41553
|
return await this.receiptClient.fetchWithdrawReceipts(address);
|
|
@@ -41444,6 +41580,11 @@ class EthereumStakingClient {
|
|
|
41444
41580
|
let result = await this.pretokenClient.purchasePretokensWithLiqETH(amount, buyer);
|
|
41445
41581
|
return result && result.txHash ? result.txHash : "Error - no resulting txHash";
|
|
41446
41582
|
}
|
|
41583
|
+
async validatorDeposit() {
|
|
41584
|
+
this.ensureUser();
|
|
41585
|
+
let result = await this.validatorClient.validatorDepositAndLockBond();
|
|
41586
|
+
return result && result.txHash ? result.txHash : "Error - no resulting txHash";
|
|
41587
|
+
}
|
|
41447
41588
|
async getPortfolio() {
|
|
41448
41589
|
try {
|
|
41449
41590
|
if (!this.signer) return Promise.resolve(null);
|
|
@@ -41700,13 +41841,13 @@ const CONTRACT_NAMES = [
|
|
|
41700
41841
|
];
|
|
41701
41842
|
|
|
41702
41843
|
var types$1 = /*#__PURE__*/Object.freeze({
|
|
41703
|
-
|
|
41704
|
-
|
|
41844
|
+
__proto__: null,
|
|
41845
|
+
CONTRACT_NAMES: CONTRACT_NAMES
|
|
41705
41846
|
});
|
|
41706
41847
|
|
|
41707
41848
|
var types = /*#__PURE__*/Object.freeze({
|
|
41708
|
-
|
|
41849
|
+
__proto__: null
|
|
41709
41850
|
});
|
|
41710
41851
|
|
|
41711
|
-
export { ADDRESSES, ADDRESS_BOOK_BY_CHAIN, CHAINLINK_FEED, CHAINLINK_PROGRAM, CONTRACTS_BY_CHAIN, DEFAULT_AVERAGE_PAY_RATE, DEFAULT_PAY_RATE_LOOKBACK,
|
|
41852
|
+
export { ADDRESSES, ADDRESS_BOOK_BY_CHAIN, CHAINLINK_FEED, CHAINLINK_PROGRAM, CONTRACTS_BY_CHAIN, ConvertClient$1 as ConvertClient, DEFAULT_AVERAGE_PAY_RATE, DEFAULT_PAY_RATE_LOOKBACK, DistributionClient, EPHEMERAL_RENT_EXEMPTION, ERC1155Abi, ERC20Abi, ERC721Abi, types$1 as ETH, EthereumContractService, EthereumStakingClient, HOODI_ADDRESSES, INDEX_SCALE$1 as INDEX_SCALE, INITIAL_TRANCHE_SUPPLY, LAMPORTS_PER_SOL, LeaderboardClient, MAINNET_ADDRESSES, OutpostClient, PAY_RATE_SCALE_FACTOR, PDA_SEEDS, PROGRAM_IDS_BY_CHAIN, PurchaseAsset, ReceiptNFTKind, SCALE, types as SOL, SolanaStakingClient, Staker, SupportedEvmChainID, SupportedSolChainID, TokenClient, airdropSol, buildOutpostAccounts, buildSolanaTrancheLadder, buildSolanaTrancheSnapshot, ceilDiv, deriveEphemeralStakeAddress, generateRandomDepositAmount, generateTestKeypair, getEpochSnapshot, getErrorMessage, getProgramIds, lamportsToSol, msToEpochEnd, normalizeToBigInt, scheduledInstruction, sleep, solToLamports, toBigint, tokensToShares, waitForConfirmation, waitUntilSafeToExecuteFunction };
|
|
41712
41853
|
//# sourceMappingURL=stake.browser.js.map
|