@ignitionfi/spl-stake-pool 1.1.19 → 1.1.21
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/dist/index.browser.cjs.js +153 -3
- package/dist/index.browser.cjs.js.map +1 -1
- package/dist/index.browser.esm.js +153 -4
- package/dist/index.browser.esm.js.map +1 -1
- package/dist/index.cjs.js +153 -3
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.esm.js +153 -4
- package/dist/index.esm.js.map +1 -1
- package/dist/index.iife.js +153 -3
- package/dist/index.iife.js.map +1 -1
- package/dist/index.iife.min.js +1 -1
- package/dist/index.iife.min.js.map +1 -1
- package/dist/instructions.d.ts +26 -2
- package/package.json +1 -1
- package/src/index.ts +163 -8
- package/src/instructions.ts +73 -2
|
@@ -1083,7 +1083,8 @@ const STAKE_POOL_INSTRUCTION_LAYOUTS = Object.freeze({
|
|
|
1083
1083
|
index: 24,
|
|
1084
1084
|
layout: BufferLayout__namespace.struct([
|
|
1085
1085
|
BufferLayout__namespace.u8('instruction'),
|
|
1086
|
-
BufferLayout__namespace.ns64('
|
|
1086
|
+
BufferLayout__namespace.ns64('poolTokensIn'),
|
|
1087
|
+
BufferLayout__namespace.ns64('minimumLamportsOut'),
|
|
1087
1088
|
]),
|
|
1088
1089
|
},
|
|
1089
1090
|
DepositSolWithSlippage: {
|
|
@@ -1116,6 +1117,14 @@ const STAKE_POOL_INSTRUCTION_LAYOUTS = Object.freeze({
|
|
|
1116
1117
|
BufferLayout__namespace.ns64('minimumLamportsOut'),
|
|
1117
1118
|
]),
|
|
1118
1119
|
},
|
|
1120
|
+
WithdrawStakeWithSession: {
|
|
1121
|
+
index: 29,
|
|
1122
|
+
layout: BufferLayout__namespace.struct([
|
|
1123
|
+
BufferLayout__namespace.u8('instruction'),
|
|
1124
|
+
BufferLayout__namespace.ns64('poolTokensIn'),
|
|
1125
|
+
BufferLayout__namespace.ns64('minimumLamportsOut'),
|
|
1126
|
+
]),
|
|
1127
|
+
},
|
|
1119
1128
|
});
|
|
1120
1129
|
/**
|
|
1121
1130
|
* Stake Pool Instruction class
|
|
@@ -1551,6 +1560,7 @@ class StakePoolInstruction {
|
|
|
1551
1560
|
* Creates a transaction instruction to withdraw WSOL from a stake pool using a session.
|
|
1552
1561
|
*/
|
|
1553
1562
|
static withdrawWsolWithSession(params) {
|
|
1563
|
+
var _a;
|
|
1554
1564
|
const type = STAKE_POOL_INSTRUCTION_LAYOUTS.WithdrawWsolWithSession;
|
|
1555
1565
|
const data = encodeData(type, {
|
|
1556
1566
|
poolTokensIn: params.poolTokensIn,
|
|
@@ -1571,6 +1581,9 @@ class StakePoolInstruction {
|
|
|
1571
1581
|
{ pubkey: params.tokenProgramId, isSigner: false, isWritable: false },
|
|
1572
1582
|
{ pubkey: params.wsolMint, isSigner: false, isWritable: false },
|
|
1573
1583
|
{ pubkey: params.programSigner, isSigner: false, isWritable: true },
|
|
1584
|
+
{ pubkey: (_a = params.payer) !== null && _a !== void 0 ? _a : params.userTransferAuthority, isSigner: true, isWritable: true },
|
|
1585
|
+
{ pubkey: params.userWallet, isSigner: false, isWritable: false },
|
|
1586
|
+
{ pubkey: web3_js.SystemProgram.programId, isSigner: false, isWritable: false },
|
|
1574
1587
|
];
|
|
1575
1588
|
if (params.solWithdrawAuthority) {
|
|
1576
1589
|
keys.push({
|
|
@@ -1579,6 +1592,39 @@ class StakePoolInstruction {
|
|
|
1579
1592
|
isWritable: false,
|
|
1580
1593
|
});
|
|
1581
1594
|
}
|
|
1595
|
+
// Associated Token Program must be last - only needed in transaction for CPI routing
|
|
1596
|
+
keys.push({ pubkey: splToken.ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false });
|
|
1597
|
+
return new web3_js.TransactionInstruction({
|
|
1598
|
+
programId: params.programId,
|
|
1599
|
+
keys,
|
|
1600
|
+
data,
|
|
1601
|
+
});
|
|
1602
|
+
}
|
|
1603
|
+
/**
|
|
1604
|
+
* Creates a transaction instruction to withdraw stake from a stake pool using a Fogo session.
|
|
1605
|
+
*/
|
|
1606
|
+
static withdrawStakeWithSession(params) {
|
|
1607
|
+
const type = STAKE_POOL_INSTRUCTION_LAYOUTS.WithdrawStakeWithSession;
|
|
1608
|
+
const data = encodeData(type, {
|
|
1609
|
+
poolTokensIn: params.poolTokensIn,
|
|
1610
|
+
minimumLamportsOut: params.minimumLamportsOut,
|
|
1611
|
+
});
|
|
1612
|
+
const keys = [
|
|
1613
|
+
{ pubkey: params.stakePool, isSigner: false, isWritable: true },
|
|
1614
|
+
{ pubkey: params.validatorList, isSigner: false, isWritable: true },
|
|
1615
|
+
{ pubkey: params.withdrawAuthority, isSigner: false, isWritable: false },
|
|
1616
|
+
{ pubkey: params.stakeToSplit, isSigner: false, isWritable: true },
|
|
1617
|
+
{ pubkey: params.stakeToReceive, isSigner: false, isWritable: true },
|
|
1618
|
+
{ pubkey: params.sessionSigner, isSigner: true, isWritable: false }, // user_stake_authority_info (signer_or_session)
|
|
1619
|
+
{ pubkey: params.sessionSigner, isSigner: false, isWritable: false }, // user_transfer_authority_info (not used in session path)
|
|
1620
|
+
{ pubkey: params.burnFromPool, isSigner: false, isWritable: true },
|
|
1621
|
+
{ pubkey: params.managerFeeAccount, isSigner: false, isWritable: true },
|
|
1622
|
+
{ pubkey: params.poolMint, isSigner: false, isWritable: true },
|
|
1623
|
+
{ pubkey: web3_js.SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false },
|
|
1624
|
+
{ pubkey: params.tokenProgramId, isSigner: false, isWritable: false },
|
|
1625
|
+
{ pubkey: web3_js.StakeProgram.programId, isSigner: false, isWritable: false },
|
|
1626
|
+
{ pubkey: params.programSigner, isSigner: false, isWritable: false },
|
|
1627
|
+
];
|
|
1582
1628
|
return new web3_js.TransactionInstruction({
|
|
1583
1629
|
programId: params.programId,
|
|
1584
1630
|
keys,
|
|
@@ -2152,7 +2198,7 @@ async function withdrawSol(connection, stakePoolAddress, tokenOwner, solReceiver
|
|
|
2152
2198
|
/**
|
|
2153
2199
|
* Creates instructions required to withdraw wSOL from a stake pool.
|
|
2154
2200
|
*/
|
|
2155
|
-
async function withdrawWsolWithSession(connection, stakePoolAddress, signerOrSession, userPubkey, amount, minimumLamportsOut = 0, solWithdrawAuthority) {
|
|
2201
|
+
async function withdrawWsolWithSession(connection, stakePoolAddress, signerOrSession, userPubkey, amount, minimumLamportsOut = 0, solWithdrawAuthority, payer) {
|
|
2156
2202
|
const stakePoolAccount = await getStakePoolAccount(connection, stakePoolAddress);
|
|
2157
2203
|
const stakePoolProgramId = getStakePoolProgramId(connection.rpcEndpoint);
|
|
2158
2204
|
const stakePool = stakePoolAccount.account.data;
|
|
@@ -2166,7 +2212,8 @@ async function withdrawWsolWithSession(connection, stakePoolAddress, signerOrSes
|
|
|
2166
2212
|
const userWsolAccount = splToken.getAssociatedTokenAddressSync(splToken.NATIVE_MINT, userPubkey);
|
|
2167
2213
|
const instructions = [];
|
|
2168
2214
|
const signers = [];
|
|
2169
|
-
|
|
2215
|
+
// The program handles wSOL ATA creation internally
|
|
2216
|
+
// This prevents rent drain attacks where paymaster pays for ATA and user reclaims rent
|
|
2170
2217
|
const [programSigner] = web3_js.PublicKey.findProgramAddressSync([Buffer.from('fogo_session_program_signer')], stakePoolProgramId);
|
|
2171
2218
|
const withdrawAuthority = await findWithdrawAuthorityProgramAddress(stakePoolProgramId, stakePoolAddress);
|
|
2172
2219
|
instructions.push(StakePoolInstruction.withdrawWsolWithSession({
|
|
@@ -2183,6 +2230,8 @@ async function withdrawWsolWithSession(connection, stakePoolAddress, signerOrSes
|
|
|
2183
2230
|
solWithdrawAuthority,
|
|
2184
2231
|
wsolMint: splToken.NATIVE_MINT,
|
|
2185
2232
|
programSigner,
|
|
2233
|
+
userWallet: userPubkey,
|
|
2234
|
+
payer,
|
|
2186
2235
|
poolTokensIn: poolTokens,
|
|
2187
2236
|
minimumLamportsOut,
|
|
2188
2237
|
}));
|
|
@@ -2191,6 +2240,106 @@ async function withdrawWsolWithSession(connection, stakePoolAddress, signerOrSes
|
|
|
2191
2240
|
signers,
|
|
2192
2241
|
};
|
|
2193
2242
|
}
|
|
2243
|
+
/**
|
|
2244
|
+
* Creates instructions required to withdraw stake from a stake pool using a Fogo session.
|
|
2245
|
+
* The withdrawn stake account will be authorized to the user's wallet.
|
|
2246
|
+
*/
|
|
2247
|
+
async function withdrawStakeWithSession(connection, stakePoolAddress, signerOrSession, userPubkey, amount, useReserve = false, voteAccountAddress, minimumLamportsOut = 0, payer, validatorComparator) {
|
|
2248
|
+
const stakePoolAccount = await getStakePoolAccount(connection, stakePoolAddress);
|
|
2249
|
+
const stakePoolProgramId = getStakePoolProgramId(connection.rpcEndpoint);
|
|
2250
|
+
const stakePool = stakePoolAccount.account.data;
|
|
2251
|
+
const poolTokens = solToLamports(amount);
|
|
2252
|
+
const poolAmount = new BN(poolTokens);
|
|
2253
|
+
const poolTokenAccount = splToken.getAssociatedTokenAddressSync(stakePool.poolMint, userPubkey);
|
|
2254
|
+
const tokenAccount = await splToken.getAccount(connection, poolTokenAccount);
|
|
2255
|
+
if (tokenAccount.amount < poolTokens) {
|
|
2256
|
+
throw new Error(`Not enough token balance to withdraw ${amount} pool tokens.
|
|
2257
|
+
Maximum withdraw amount is ${lamportsToSol(tokenAccount.amount)} pool tokens.`);
|
|
2258
|
+
}
|
|
2259
|
+
const [programSigner] = web3_js.PublicKey.findProgramAddressSync([Buffer.from('fogo_session_program_signer')], stakePoolProgramId);
|
|
2260
|
+
const withdrawAuthority = await findWithdrawAuthorityProgramAddress(stakePoolProgramId, stakePoolAddress);
|
|
2261
|
+
const stakeAccountRentExemption = await connection.getMinimumBalanceForRentExemption(web3_js.StakeProgram.space);
|
|
2262
|
+
// Determine which stake accounts to withdraw from
|
|
2263
|
+
const withdrawAccounts = [];
|
|
2264
|
+
if (useReserve) {
|
|
2265
|
+
withdrawAccounts.push({
|
|
2266
|
+
stakeAddress: stakePool.reserveStake,
|
|
2267
|
+
voteAddress: undefined,
|
|
2268
|
+
poolAmount,
|
|
2269
|
+
});
|
|
2270
|
+
}
|
|
2271
|
+
else if (voteAccountAddress) {
|
|
2272
|
+
const stakeAccountAddress = await findStakeProgramAddress(stakePoolProgramId, voteAccountAddress, stakePoolAddress);
|
|
2273
|
+
const stakeAccount = await connection.getAccountInfo(stakeAccountAddress);
|
|
2274
|
+
if (!stakeAccount) {
|
|
2275
|
+
throw new Error(`Validator stake account not found for vote address ${voteAccountAddress.toBase58()}`);
|
|
2276
|
+
}
|
|
2277
|
+
const availableLamports = new BN(stakeAccount.lamports - MINIMUM_ACTIVE_STAKE - stakeAccountRentExemption);
|
|
2278
|
+
if (availableLamports.lt(new BN(0))) {
|
|
2279
|
+
throw new Error('Invalid Stake Account');
|
|
2280
|
+
}
|
|
2281
|
+
const availableForWithdrawal = calcLamportsWithdrawAmount(stakePool, availableLamports);
|
|
2282
|
+
if (availableForWithdrawal.lt(poolAmount)) {
|
|
2283
|
+
throw new Error(`Not enough lamports available for withdrawal from ${stakeAccountAddress},
|
|
2284
|
+
${poolAmount} asked, ${availableForWithdrawal} available.`);
|
|
2285
|
+
}
|
|
2286
|
+
withdrawAccounts.push({
|
|
2287
|
+
stakeAddress: stakeAccountAddress,
|
|
2288
|
+
voteAddress: voteAccountAddress,
|
|
2289
|
+
poolAmount,
|
|
2290
|
+
});
|
|
2291
|
+
}
|
|
2292
|
+
else {
|
|
2293
|
+
// Get the list of accounts to withdraw from automatically
|
|
2294
|
+
withdrawAccounts.push(...(await prepareWithdrawAccounts(connection, stakePool, stakePoolAddress, poolAmount, validatorComparator, poolTokenAccount.equals(stakePool.managerFeeAccount))));
|
|
2295
|
+
}
|
|
2296
|
+
const instructions = [];
|
|
2297
|
+
const signers = [];
|
|
2298
|
+
const stakeAccountPubkeys = [];
|
|
2299
|
+
// Max 5 accounts to prevent an error: "Transaction too large"
|
|
2300
|
+
const maxWithdrawAccounts = 5;
|
|
2301
|
+
let i = 0;
|
|
2302
|
+
for (const withdrawAccount of withdrawAccounts) {
|
|
2303
|
+
if (i >= maxWithdrawAccounts) {
|
|
2304
|
+
break;
|
|
2305
|
+
}
|
|
2306
|
+
// Create a new stake account to receive the withdrawal
|
|
2307
|
+
const stakeReceiver = web3_js.Keypair.generate();
|
|
2308
|
+
signers.push(stakeReceiver);
|
|
2309
|
+
stakeAccountPubkeys.push(stakeReceiver.publicKey);
|
|
2310
|
+
// Create the stake account that will receive the split stake
|
|
2311
|
+
instructions.push(web3_js.SystemProgram.createAccount({
|
|
2312
|
+
fromPubkey: payer !== null && payer !== void 0 ? payer : userPubkey,
|
|
2313
|
+
newAccountPubkey: stakeReceiver.publicKey,
|
|
2314
|
+
lamports: stakeAccountRentExemption,
|
|
2315
|
+
space: web3_js.StakeProgram.space,
|
|
2316
|
+
programId: web3_js.StakeProgram.programId,
|
|
2317
|
+
}));
|
|
2318
|
+
// Add the withdraw stake with session instruction
|
|
2319
|
+
instructions.push(StakePoolInstruction.withdrawStakeWithSession({
|
|
2320
|
+
programId: stakePoolProgramId,
|
|
2321
|
+
stakePool: stakePoolAddress,
|
|
2322
|
+
validatorList: stakePool.validatorList,
|
|
2323
|
+
withdrawAuthority,
|
|
2324
|
+
stakeToSplit: withdrawAccount.stakeAddress,
|
|
2325
|
+
stakeToReceive: stakeReceiver.publicKey,
|
|
2326
|
+
sessionSigner: signerOrSession,
|
|
2327
|
+
burnFromPool: poolTokenAccount,
|
|
2328
|
+
managerFeeAccount: stakePool.managerFeeAccount,
|
|
2329
|
+
poolMint: stakePool.poolMint,
|
|
2330
|
+
tokenProgramId: stakePool.tokenProgramId,
|
|
2331
|
+
programSigner,
|
|
2332
|
+
poolTokensIn: withdrawAccount.poolAmount.toNumber(),
|
|
2333
|
+
minimumLamportsOut: solToLamports(minimumLamportsOut),
|
|
2334
|
+
}));
|
|
2335
|
+
i++;
|
|
2336
|
+
}
|
|
2337
|
+
return {
|
|
2338
|
+
instructions,
|
|
2339
|
+
signers,
|
|
2340
|
+
stakeAccountPubkeys,
|
|
2341
|
+
};
|
|
2342
|
+
}
|
|
2194
2343
|
async function addValidatorToPool(connection, stakePoolAddress, validatorVote, seed) {
|
|
2195
2344
|
const stakePoolAccount = await getStakePoolAccount(connection, stakePoolAddress);
|
|
2196
2345
|
const stakePoolProgramId = getStakePoolProgramId(connection.rpcEndpoint);
|
|
@@ -2578,5 +2727,6 @@ exports.updatePoolTokenMetadata = updatePoolTokenMetadata;
|
|
|
2578
2727
|
exports.updateStakePool = updateStakePool;
|
|
2579
2728
|
exports.withdrawSol = withdrawSol;
|
|
2580
2729
|
exports.withdrawStake = withdrawStake;
|
|
2730
|
+
exports.withdrawStakeWithSession = withdrawStakeWithSession;
|
|
2581
2731
|
exports.withdrawWsolWithSession = withdrawWsolWithSession;
|
|
2582
2732
|
//# sourceMappingURL=index.browser.cjs.js.map
|