@ignitionfi/spl-stake-pool 1.1.20 → 1.1.22
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 +147 -1
- package/dist/index.browser.cjs.js.map +1 -1
- package/dist/index.browser.esm.js +147 -2
- package/dist/index.browser.esm.js.map +1 -1
- package/dist/index.cjs.js +147 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +8 -0
- package/dist/index.esm.js +147 -2
- package/dist/index.esm.js.map +1 -1
- package/dist/index.iife.js +147 -1
- 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 +23 -1
- package/package.json +1 -1
- package/src/index.ts +167 -0
- package/src/instructions.ts +64 -1
package/dist/index.iife.js
CHANGED
|
@@ -22264,7 +22264,8 @@ var solanaStakePool = (function (exports, node_buffer) {
|
|
|
22264
22264
|
index: 24,
|
|
22265
22265
|
layout: LayoutExports$1.struct([
|
|
22266
22266
|
LayoutExports$1.u8('instruction'),
|
|
22267
|
-
LayoutExports$1.ns64('
|
|
22267
|
+
LayoutExports$1.ns64('poolTokensIn'),
|
|
22268
|
+
LayoutExports$1.ns64('minimumLamportsOut'),
|
|
22268
22269
|
]),
|
|
22269
22270
|
},
|
|
22270
22271
|
DepositSolWithSlippage: {
|
|
@@ -22297,6 +22298,14 @@ var solanaStakePool = (function (exports, node_buffer) {
|
|
|
22297
22298
|
LayoutExports$1.ns64('minimumLamportsOut'),
|
|
22298
22299
|
]),
|
|
22299
22300
|
},
|
|
22301
|
+
WithdrawStakeWithSession: {
|
|
22302
|
+
index: 29,
|
|
22303
|
+
layout: LayoutExports$1.struct([
|
|
22304
|
+
LayoutExports$1.u8('instruction'),
|
|
22305
|
+
LayoutExports$1.ns64('poolTokensIn'),
|
|
22306
|
+
LayoutExports$1.ns64('minimumLamportsOut'),
|
|
22307
|
+
]),
|
|
22308
|
+
},
|
|
22300
22309
|
});
|
|
22301
22310
|
/**
|
|
22302
22311
|
* Stake Pool Instruction class
|
|
@@ -22772,6 +22781,37 @@ var solanaStakePool = (function (exports, node_buffer) {
|
|
|
22772
22781
|
data,
|
|
22773
22782
|
});
|
|
22774
22783
|
}
|
|
22784
|
+
/**
|
|
22785
|
+
* Creates a transaction instruction to withdraw stake from a stake pool using a Fogo session.
|
|
22786
|
+
*/
|
|
22787
|
+
static withdrawStakeWithSession(params) {
|
|
22788
|
+
const type = STAKE_POOL_INSTRUCTION_LAYOUTS.WithdrawStakeWithSession;
|
|
22789
|
+
const data = encodeData(type, {
|
|
22790
|
+
poolTokensIn: params.poolTokensIn,
|
|
22791
|
+
minimumLamportsOut: params.minimumLamportsOut,
|
|
22792
|
+
});
|
|
22793
|
+
const keys = [
|
|
22794
|
+
{ pubkey: params.stakePool, isSigner: false, isWritable: true },
|
|
22795
|
+
{ pubkey: params.validatorList, isSigner: false, isWritable: true },
|
|
22796
|
+
{ pubkey: params.withdrawAuthority, isSigner: false, isWritable: false },
|
|
22797
|
+
{ pubkey: params.stakeToSplit, isSigner: false, isWritable: true },
|
|
22798
|
+
{ pubkey: params.stakeToReceive, isSigner: false, isWritable: true },
|
|
22799
|
+
{ pubkey: params.sessionSigner, isSigner: true, isWritable: false }, // user_stake_authority_info (signer_or_session)
|
|
22800
|
+
{ pubkey: params.sessionSigner, isSigner: false, isWritable: false }, // user_transfer_authority_info (not used in session path)
|
|
22801
|
+
{ pubkey: params.burnFromPool, isSigner: false, isWritable: true },
|
|
22802
|
+
{ pubkey: params.managerFeeAccount, isSigner: false, isWritable: true },
|
|
22803
|
+
{ pubkey: params.poolMint, isSigner: false, isWritable: true },
|
|
22804
|
+
{ pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false },
|
|
22805
|
+
{ pubkey: params.tokenProgramId, isSigner: false, isWritable: false },
|
|
22806
|
+
{ pubkey: StakeProgram.programId, isSigner: false, isWritable: false },
|
|
22807
|
+
{ pubkey: params.programSigner, isSigner: false, isWritable: false },
|
|
22808
|
+
];
|
|
22809
|
+
return new TransactionInstruction({
|
|
22810
|
+
programId: params.programId,
|
|
22811
|
+
keys,
|
|
22812
|
+
data,
|
|
22813
|
+
});
|
|
22814
|
+
}
|
|
22775
22815
|
/**
|
|
22776
22816
|
* Creates an instruction to create metadata
|
|
22777
22817
|
* using the mpl token metadata program for the pool token
|
|
@@ -23381,6 +23421,111 @@ var solanaStakePool = (function (exports, node_buffer) {
|
|
|
23381
23421
|
signers,
|
|
23382
23422
|
};
|
|
23383
23423
|
}
|
|
23424
|
+
/**
|
|
23425
|
+
* Creates instructions required to withdraw stake from a stake pool using a Fogo session.
|
|
23426
|
+
* The withdrawn stake account will be authorized to the user's wallet.
|
|
23427
|
+
*/
|
|
23428
|
+
async function withdrawStakeWithSession(connection, stakePoolAddress, signerOrSession, userPubkey, amount, payer, useReserve = false, voteAccountAddress, minimumLamportsOut = 0, validatorComparator) {
|
|
23429
|
+
const stakePoolAccount = await getStakePoolAccount(connection, stakePoolAddress);
|
|
23430
|
+
const stakePoolProgramId = getStakePoolProgramId(connection.rpcEndpoint);
|
|
23431
|
+
const stakePool = stakePoolAccount.account.data;
|
|
23432
|
+
const poolTokens = solToLamports(amount);
|
|
23433
|
+
const poolAmount = new BN(poolTokens);
|
|
23434
|
+
const poolTokenAccount = getAssociatedTokenAddressSync(stakePool.poolMint, userPubkey);
|
|
23435
|
+
const tokenAccount = await getAccount(connection, poolTokenAccount);
|
|
23436
|
+
if (tokenAccount.amount < poolTokens) {
|
|
23437
|
+
throw new Error(`Not enough token balance to withdraw ${amount} pool tokens.
|
|
23438
|
+
Maximum withdraw amount is ${lamportsToSol(tokenAccount.amount)} pool tokens.`);
|
|
23439
|
+
}
|
|
23440
|
+
const [programSigner] = PublicKey.findProgramAddressSync([Buffer.from('fogo_session_program_signer')], stakePoolProgramId);
|
|
23441
|
+
const withdrawAuthority = await findWithdrawAuthorityProgramAddress(stakePoolProgramId, stakePoolAddress);
|
|
23442
|
+
const stakeAccountRentExemption = await connection.getMinimumBalanceForRentExemption(StakeProgram.space);
|
|
23443
|
+
// Determine which stake accounts to withdraw from
|
|
23444
|
+
const withdrawAccounts = [];
|
|
23445
|
+
if (useReserve) {
|
|
23446
|
+
withdrawAccounts.push({
|
|
23447
|
+
stakeAddress: stakePool.reserveStake,
|
|
23448
|
+
voteAddress: undefined,
|
|
23449
|
+
poolAmount,
|
|
23450
|
+
});
|
|
23451
|
+
}
|
|
23452
|
+
else if (voteAccountAddress) {
|
|
23453
|
+
const stakeAccountAddress = await findStakeProgramAddress(stakePoolProgramId, voteAccountAddress, stakePoolAddress);
|
|
23454
|
+
const stakeAccount = await connection.getAccountInfo(stakeAccountAddress);
|
|
23455
|
+
if (!stakeAccount) {
|
|
23456
|
+
throw new Error(`Validator stake account not found for vote address ${voteAccountAddress.toBase58()}`);
|
|
23457
|
+
}
|
|
23458
|
+
const availableLamports = new BN(stakeAccount.lamports - MINIMUM_ACTIVE_STAKE - stakeAccountRentExemption);
|
|
23459
|
+
if (availableLamports.lt(new BN(0))) {
|
|
23460
|
+
throw new Error('Invalid Stake Account');
|
|
23461
|
+
}
|
|
23462
|
+
const availableForWithdrawal = calcLamportsWithdrawAmount(stakePool, availableLamports);
|
|
23463
|
+
if (availableForWithdrawal.lt(poolAmount)) {
|
|
23464
|
+
throw new Error(`Not enough lamports available for withdrawal from ${stakeAccountAddress},
|
|
23465
|
+
${poolAmount} asked, ${availableForWithdrawal} available.`);
|
|
23466
|
+
}
|
|
23467
|
+
withdrawAccounts.push({
|
|
23468
|
+
stakeAddress: stakeAccountAddress,
|
|
23469
|
+
voteAddress: voteAccountAddress,
|
|
23470
|
+
poolAmount,
|
|
23471
|
+
});
|
|
23472
|
+
}
|
|
23473
|
+
else {
|
|
23474
|
+
// Get the list of accounts to withdraw from automatically
|
|
23475
|
+
withdrawAccounts.push(...(await prepareWithdrawAccounts(connection, stakePool, stakePoolAddress, poolAmount, validatorComparator, poolTokenAccount.equals(stakePool.managerFeeAccount))));
|
|
23476
|
+
}
|
|
23477
|
+
const instructions = [];
|
|
23478
|
+
const stakeAccountPubkeys = [];
|
|
23479
|
+
// Max 5 accounts to prevent an error: "Transaction too large"
|
|
23480
|
+
const maxWithdrawAccounts = 5;
|
|
23481
|
+
let i = 0;
|
|
23482
|
+
for (const withdrawAccount of withdrawAccounts) {
|
|
23483
|
+
if (i >= maxWithdrawAccounts) {
|
|
23484
|
+
break;
|
|
23485
|
+
}
|
|
23486
|
+
// Create a deterministic stake account address using a seed
|
|
23487
|
+
// This avoids needing the new account to sign (required for sessions)
|
|
23488
|
+
// We use payer as base so only payer needs to sign (payer = basePubkey)
|
|
23489
|
+
// The seed includes timestamp + random component to ensure uniqueness
|
|
23490
|
+
const uniqueId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
23491
|
+
const seed = `ws:${uniqueId}:${i}`.slice(0, 32); // Seed max 32 chars
|
|
23492
|
+
const stakeReceiverPubkey = await PublicKey.createWithSeed(payer, seed, StakeProgram.programId);
|
|
23493
|
+
stakeAccountPubkeys.push(stakeReceiverPubkey);
|
|
23494
|
+
// Create the stake account using createAccountWithSeed
|
|
23495
|
+
// Since basePubkey === fromPubkey (both are payer), only payer needs to sign
|
|
23496
|
+
instructions.push(SystemProgram.createAccountWithSeed({
|
|
23497
|
+
fromPubkey: payer,
|
|
23498
|
+
newAccountPubkey: stakeReceiverPubkey,
|
|
23499
|
+
basePubkey: payer,
|
|
23500
|
+
seed,
|
|
23501
|
+
lamports: stakeAccountRentExemption,
|
|
23502
|
+
space: StakeProgram.space,
|
|
23503
|
+
programId: StakeProgram.programId,
|
|
23504
|
+
}));
|
|
23505
|
+
// Add the withdraw stake with session instruction
|
|
23506
|
+
instructions.push(StakePoolInstruction.withdrawStakeWithSession({
|
|
23507
|
+
programId: stakePoolProgramId,
|
|
23508
|
+
stakePool: stakePoolAddress,
|
|
23509
|
+
validatorList: stakePool.validatorList,
|
|
23510
|
+
withdrawAuthority,
|
|
23511
|
+
stakeToSplit: withdrawAccount.stakeAddress,
|
|
23512
|
+
stakeToReceive: stakeReceiverPubkey,
|
|
23513
|
+
sessionSigner: signerOrSession,
|
|
23514
|
+
burnFromPool: poolTokenAccount,
|
|
23515
|
+
managerFeeAccount: stakePool.managerFeeAccount,
|
|
23516
|
+
poolMint: stakePool.poolMint,
|
|
23517
|
+
tokenProgramId: stakePool.tokenProgramId,
|
|
23518
|
+
programSigner,
|
|
23519
|
+
poolTokensIn: withdrawAccount.poolAmount.toNumber(),
|
|
23520
|
+
minimumLamportsOut,
|
|
23521
|
+
}));
|
|
23522
|
+
i++;
|
|
23523
|
+
}
|
|
23524
|
+
return {
|
|
23525
|
+
instructions,
|
|
23526
|
+
stakeAccountPubkeys,
|
|
23527
|
+
};
|
|
23528
|
+
}
|
|
23384
23529
|
async function addValidatorToPool(connection, stakePoolAddress, validatorVote, seed) {
|
|
23385
23530
|
const stakePoolAccount = await getStakePoolAccount(connection, stakePoolAddress);
|
|
23386
23531
|
const stakePoolProgramId = getStakePoolProgramId(connection.rpcEndpoint);
|
|
@@ -23768,6 +23913,7 @@ var solanaStakePool = (function (exports, node_buffer) {
|
|
|
23768
23913
|
exports.updateStakePool = updateStakePool;
|
|
23769
23914
|
exports.withdrawSol = withdrawSol;
|
|
23770
23915
|
exports.withdrawStake = withdrawStake;
|
|
23916
|
+
exports.withdrawStakeWithSession = withdrawStakeWithSession;
|
|
23771
23917
|
exports.withdrawWsolWithSession = withdrawWsolWithSession;
|
|
23772
23918
|
|
|
23773
23919
|
return exports;
|