@ignitionfi/spl-stake-pool 1.1.23 → 1.1.25
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 +140 -18
- package/dist/index.browser.cjs.js.map +1 -1
- package/dist/index.browser.esm.js +140 -19
- package/dist/index.browser.esm.js.map +1 -1
- package/dist/index.cjs.js +140 -18
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +42 -6
- package/dist/index.esm.js +140 -19
- package/dist/index.esm.js.map +1 -1
- package/dist/index.iife.js +140 -18
- 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 -3
- package/package.json +1 -1
- package/src/constants.ts +1 -3
- package/src/index.ts +124 -22
- package/src/instructions.ts +70 -4
- package/src/utils/stake.ts +5 -2
package/dist/index.iife.js
CHANGED
|
@@ -22025,13 +22025,16 @@ var solanaStakePool = (function (exports, node_buffer) {
|
|
|
22025
22025
|
continue;
|
|
22026
22026
|
}
|
|
22027
22027
|
const stakeAccountAddress = await findStakeProgramAddress(stakePoolProgramId, validator.voteAccountAddress, stakePoolAddress);
|
|
22028
|
-
|
|
22028
|
+
// For active stake accounts, subtract the minimum balance that must remain
|
|
22029
|
+
// to allow for merges and maintain rent exemption
|
|
22030
|
+
const availableActiveLamports = validator.activeStakeLamports.sub(minBalance);
|
|
22031
|
+
if (availableActiveLamports.gt(new BN(0))) {
|
|
22029
22032
|
const isPreferred = (_a = stakePool === null || stakePool === void 0 ? void 0 : stakePool.preferredWithdrawValidatorVoteAddress) === null || _a === void 0 ? void 0 : _a.equals(validator.voteAccountAddress);
|
|
22030
22033
|
accounts.push({
|
|
22031
22034
|
type: isPreferred ? 'preferred' : 'active',
|
|
22032
22035
|
voteAddress: validator.voteAccountAddress,
|
|
22033
22036
|
stakeAddress: stakeAccountAddress,
|
|
22034
|
-
lamports:
|
|
22037
|
+
lamports: availableActiveLamports,
|
|
22035
22038
|
});
|
|
22036
22039
|
}
|
|
22037
22040
|
const transientStakeLamports = validator.transientStakeLamports.sub(minBalance);
|
|
@@ -22322,6 +22325,14 @@ var solanaStakePool = (function (exports, node_buffer) {
|
|
|
22322
22325
|
LayoutExports$1.ns64('userStakeSeed'),
|
|
22323
22326
|
]),
|
|
22324
22327
|
},
|
|
22328
|
+
WithdrawFromStakeAccountWithSession: {
|
|
22329
|
+
index: 30,
|
|
22330
|
+
layout: LayoutExports$1.struct([
|
|
22331
|
+
LayoutExports$1.u8('instruction'),
|
|
22332
|
+
LayoutExports$1.ns64('lamports'),
|
|
22333
|
+
LayoutExports$1.ns64('userStakeSeed'),
|
|
22334
|
+
]),
|
|
22335
|
+
},
|
|
22325
22336
|
});
|
|
22326
22337
|
/**
|
|
22327
22338
|
* Stake Pool Instruction class
|
|
@@ -22755,9 +22766,9 @@ var solanaStakePool = (function (exports, node_buffer) {
|
|
|
22755
22766
|
}
|
|
22756
22767
|
/**
|
|
22757
22768
|
* Creates a transaction instruction to withdraw WSOL from a stake pool using a session.
|
|
22769
|
+
* Rent for ATA creation (if needed) is paid from the withdrawal amount.
|
|
22758
22770
|
*/
|
|
22759
22771
|
static withdrawWsolWithSession(params) {
|
|
22760
|
-
var _a;
|
|
22761
22772
|
const type = STAKE_POOL_INSTRUCTION_LAYOUTS.WithdrawWsolWithSession;
|
|
22762
22773
|
const data = encodeData(type, {
|
|
22763
22774
|
poolTokensIn: params.poolTokensIn,
|
|
@@ -22778,7 +22789,6 @@ var solanaStakePool = (function (exports, node_buffer) {
|
|
|
22778
22789
|
{ pubkey: params.tokenProgramId, isSigner: false, isWritable: false },
|
|
22779
22790
|
{ pubkey: params.wsolMint, isSigner: false, isWritable: false },
|
|
22780
22791
|
{ pubkey: params.programSigner, isSigner: false, isWritable: true },
|
|
22781
|
-
{ pubkey: (_a = params.payer) !== null && _a !== void 0 ? _a : params.userTransferAuthority, isSigner: true, isWritable: true },
|
|
22782
22792
|
{ pubkey: params.userWallet, isSigner: false, isWritable: false },
|
|
22783
22793
|
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
|
|
22784
22794
|
];
|
|
@@ -22799,6 +22809,7 @@ var solanaStakePool = (function (exports, node_buffer) {
|
|
|
22799
22809
|
}
|
|
22800
22810
|
/**
|
|
22801
22811
|
* Creates a transaction instruction to withdraw stake from a stake pool using a Fogo session.
|
|
22812
|
+
* The stake account is created as a PDA and rent is paid by the payer (typically paymaster).
|
|
22802
22813
|
*/
|
|
22803
22814
|
static withdrawStakeWithSession(params) {
|
|
22804
22815
|
const type = STAKE_POOL_INSTRUCTION_LAYOUTS.WithdrawStakeWithSession;
|
|
@@ -22822,8 +22833,8 @@ var solanaStakePool = (function (exports, node_buffer) {
|
|
|
22822
22833
|
{ pubkey: params.tokenProgramId, isSigner: false, isWritable: false },
|
|
22823
22834
|
{ pubkey: StakeProgram.programId, isSigner: false, isWritable: false },
|
|
22824
22835
|
{ pubkey: params.programSigner, isSigner: false, isWritable: false },
|
|
22825
|
-
{ pubkey: params.payer, isSigner: true, isWritable: true },
|
|
22826
22836
|
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
|
|
22837
|
+
{ pubkey: params.payer, isSigner: true, isWritable: true },
|
|
22827
22838
|
];
|
|
22828
22839
|
return new TransactionInstruction({
|
|
22829
22840
|
programId: params.programId,
|
|
@@ -22831,6 +22842,43 @@ var solanaStakePool = (function (exports, node_buffer) {
|
|
|
22831
22842
|
data,
|
|
22832
22843
|
});
|
|
22833
22844
|
}
|
|
22845
|
+
/**
|
|
22846
|
+
* Creates a transaction instruction to withdraw SOL from a deactivated user stake account using a Fogo session.
|
|
22847
|
+
* The stake account must be fully deactivated (inactive).
|
|
22848
|
+
* User receives full stake balance (payer's rent contribution compensates for reduced split).
|
|
22849
|
+
*/
|
|
22850
|
+
static withdrawFromStakeAccountWithSession(params) {
|
|
22851
|
+
// For u64::MAX (full withdrawal), we need to manually encode since buffer-layout doesn't handle bigint well
|
|
22852
|
+
const U64_MAX = BigInt('18446744073709551615');
|
|
22853
|
+
const isFullWithdrawal = params.lamports >= U64_MAX;
|
|
22854
|
+
// Manually create the instruction data buffer using Uint8Array for browser compatibility
|
|
22855
|
+
// Layout: u8 instruction (1) + u64 lamports (8) + u64 userStakeSeed (8) = 17 bytes
|
|
22856
|
+
const data = new Uint8Array(17);
|
|
22857
|
+
data[0] = 30; // instruction discriminator (WithdrawFromStakeAccountWithSession = 30)
|
|
22858
|
+
// Write lamports as u64 little-endian (bytes 1-8)
|
|
22859
|
+
const lamportsBigInt = isFullWithdrawal ? U64_MAX : params.lamports;
|
|
22860
|
+
for (let i = 0; i < 8; i++) {
|
|
22861
|
+
data[1 + i] = Number((lamportsBigInt >> BigInt(i * 8)) & BigInt(0xff));
|
|
22862
|
+
}
|
|
22863
|
+
// Write userStakeSeed as u64 little-endian (bytes 9-16)
|
|
22864
|
+
const seedBigInt = BigInt(params.userStakeSeed);
|
|
22865
|
+
for (let i = 0; i < 8; i++) {
|
|
22866
|
+
data[9 + i] = Number((seedBigInt >> BigInt(i * 8)) & BigInt(0xff));
|
|
22867
|
+
}
|
|
22868
|
+
// Account order matches Rust: stake_account, recipient, clock, stake_history, session_signer
|
|
22869
|
+
const keys = [
|
|
22870
|
+
{ pubkey: params.userStakeAccount, isSigner: false, isWritable: true },
|
|
22871
|
+
{ pubkey: params.userWallet, isSigner: false, isWritable: true },
|
|
22872
|
+
{ pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false },
|
|
22873
|
+
{ pubkey: SYSVAR_STAKE_HISTORY_PUBKEY, isSigner: false, isWritable: false },
|
|
22874
|
+
{ pubkey: params.sessionSigner, isSigner: true, isWritable: false },
|
|
22875
|
+
];
|
|
22876
|
+
return new TransactionInstruction({
|
|
22877
|
+
programId: params.programId,
|
|
22878
|
+
keys,
|
|
22879
|
+
data: Buffer.from(data),
|
|
22880
|
+
});
|
|
22881
|
+
}
|
|
22834
22882
|
/**
|
|
22835
22883
|
* Creates an instruction to create metadata
|
|
22836
22884
|
* using the mpl token metadata program for the pool token
|
|
@@ -23094,14 +23142,21 @@ var solanaStakePool = (function (exports, node_buffer) {
|
|
|
23094
23142
|
/**
|
|
23095
23143
|
* Creates instructions required to deposit sol to stake pool.
|
|
23096
23144
|
*/
|
|
23097
|
-
async function depositWsolWithSession(connection, stakePoolAddress, signerOrSession, userPubkey, lamports, minimumPoolTokensOut = 0, destinationTokenAccount, referrerTokenAccount, depositAuthority, payer
|
|
23145
|
+
async function depositWsolWithSession(connection, stakePoolAddress, signerOrSession, userPubkey, lamports, minimumPoolTokensOut = 0, destinationTokenAccount, referrerTokenAccount, depositAuthority, payer,
|
|
23146
|
+
/**
|
|
23147
|
+
* Skip WSOL balance validation. Set to true when adding wrap instructions
|
|
23148
|
+
* in the same transaction that will fund the WSOL account before deposit.
|
|
23149
|
+
*/
|
|
23150
|
+
skipBalanceCheck = false) {
|
|
23098
23151
|
const wsolTokenAccount = getAssociatedTokenAddressSync(NATIVE_MINT, userPubkey);
|
|
23099
|
-
|
|
23100
|
-
|
|
23101
|
-
|
|
23102
|
-
|
|
23103
|
-
|
|
23104
|
-
|
|
23152
|
+
if (!skipBalanceCheck) {
|
|
23153
|
+
const tokenAccountInfo = await connection.getTokenAccountBalance(wsolTokenAccount, 'confirmed');
|
|
23154
|
+
const wsolBalance = tokenAccountInfo
|
|
23155
|
+
? parseInt(tokenAccountInfo.value.amount)
|
|
23156
|
+
: 0;
|
|
23157
|
+
if (wsolBalance < lamports) {
|
|
23158
|
+
throw new Error(`Not enough WSOL to deposit into pool. Maximum deposit amount is ${lamportsToSol(wsolBalance)} WSOL.`);
|
|
23159
|
+
}
|
|
23105
23160
|
}
|
|
23106
23161
|
const stakePoolAccount = await getStakePoolAccount(connection, stakePoolAddress);
|
|
23107
23162
|
const stakePoolProgramId = getStakePoolProgramId(connection.rpcEndpoint);
|
|
@@ -23397,8 +23452,9 @@ var solanaStakePool = (function (exports, node_buffer) {
|
|
|
23397
23452
|
}
|
|
23398
23453
|
/**
|
|
23399
23454
|
* Creates instructions required to withdraw wSOL from a stake pool.
|
|
23455
|
+
* Rent for ATA creation (if needed) is paid from the withdrawal amount.
|
|
23400
23456
|
*/
|
|
23401
|
-
async function withdrawWsolWithSession(connection, stakePoolAddress, signerOrSession, userPubkey, amount, minimumLamportsOut = 0, solWithdrawAuthority
|
|
23457
|
+
async function withdrawWsolWithSession(connection, stakePoolAddress, signerOrSession, userPubkey, amount, minimumLamportsOut = 0, solWithdrawAuthority) {
|
|
23402
23458
|
const stakePoolAccount = await getStakePoolAccount(connection, stakePoolAddress);
|
|
23403
23459
|
const stakePoolProgramId = getStakePoolProgramId(connection.rpcEndpoint);
|
|
23404
23460
|
const stakePool = stakePoolAccount.account.data;
|
|
@@ -23431,7 +23487,6 @@ var solanaStakePool = (function (exports, node_buffer) {
|
|
|
23431
23487
|
wsolMint: NATIVE_MINT,
|
|
23432
23488
|
programSigner,
|
|
23433
23489
|
userWallet: userPubkey,
|
|
23434
|
-
payer,
|
|
23435
23490
|
poolTokensIn: poolTokens,
|
|
23436
23491
|
minimumLamportsOut,
|
|
23437
23492
|
}));
|
|
@@ -23462,17 +23517,83 @@ var solanaStakePool = (function (exports, node_buffer) {
|
|
|
23462
23517
|
}
|
|
23463
23518
|
throw new Error(`No available user stake seed found between ${startSeed} and ${startSeed + maxSeed - 1}`);
|
|
23464
23519
|
}
|
|
23520
|
+
/**
|
|
23521
|
+
* Fetches all user stake accounts created via WithdrawStakeWithSession.
|
|
23522
|
+
* These are PDAs derived from [b"user_stake", user_wallet, seed].
|
|
23523
|
+
*
|
|
23524
|
+
* @param connection - Solana connection
|
|
23525
|
+
* @param programId - The stake pool program ID
|
|
23526
|
+
* @param userPubkey - User's wallet address
|
|
23527
|
+
* @param maxSeed - Maximum seed to check (default: 100)
|
|
23528
|
+
* @returns Array of user stake accounts with their details
|
|
23529
|
+
*/
|
|
23530
|
+
async function getUserStakeAccounts(connection, programId, userPubkey, maxSeed = 100) {
|
|
23531
|
+
var _c, _d;
|
|
23532
|
+
const stakeAccounts = [];
|
|
23533
|
+
const currentEpoch = (await connection.getEpochInfo()).epoch;
|
|
23534
|
+
for (let seed = 0; seed < maxSeed; seed++) {
|
|
23535
|
+
const pda = findUserStakeProgramAddress(programId, userPubkey, seed);
|
|
23536
|
+
const accountInfo = await connection.getAccountInfo(pda);
|
|
23537
|
+
if (!accountInfo) {
|
|
23538
|
+
continue; // Skip empty slots, there might be gaps
|
|
23539
|
+
}
|
|
23540
|
+
// Check if owned by stake program
|
|
23541
|
+
if (!accountInfo.owner.equals(StakeProgram.programId)) {
|
|
23542
|
+
continue;
|
|
23543
|
+
}
|
|
23544
|
+
// Parse stake account data
|
|
23545
|
+
const stakeAccount = {
|
|
23546
|
+
pubkey: pda,
|
|
23547
|
+
seed,
|
|
23548
|
+
lamports: accountInfo.lamports,
|
|
23549
|
+
state: 'inactive',
|
|
23550
|
+
};
|
|
23551
|
+
try {
|
|
23552
|
+
// Parse the stake account to get delegation info
|
|
23553
|
+
const parsedAccount = await connection.getParsedAccountInfo(pda);
|
|
23554
|
+
if (parsedAccount.value && 'parsed' in parsedAccount.value.data) {
|
|
23555
|
+
const parsed = parsedAccount.value.data.parsed;
|
|
23556
|
+
if (parsed.type === 'delegated' && ((_d = (_c = parsed.info) === null || _c === void 0 ? void 0 : _c.stake) === null || _d === void 0 ? void 0 : _d.delegation)) {
|
|
23557
|
+
const delegation = parsed.info.stake.delegation;
|
|
23558
|
+
stakeAccount.voter = new PublicKey(delegation.voter);
|
|
23559
|
+
stakeAccount.activationEpoch = Number(delegation.activationEpoch);
|
|
23560
|
+
stakeAccount.deactivationEpoch = Number(delegation.deactivationEpoch);
|
|
23561
|
+
// Determine state based on epochs
|
|
23562
|
+
const activationEpoch = stakeAccount.activationEpoch;
|
|
23563
|
+
const deactivationEpoch = stakeAccount.deactivationEpoch;
|
|
23564
|
+
if (deactivationEpoch !== undefined && deactivationEpoch < Number.MAX_SAFE_INTEGER && deactivationEpoch <= currentEpoch) {
|
|
23565
|
+
stakeAccount.state = 'inactive';
|
|
23566
|
+
}
|
|
23567
|
+
else if (deactivationEpoch !== undefined && deactivationEpoch < Number.MAX_SAFE_INTEGER) {
|
|
23568
|
+
stakeAccount.state = 'deactivating';
|
|
23569
|
+
}
|
|
23570
|
+
else if (activationEpoch !== undefined && activationEpoch <= currentEpoch) {
|
|
23571
|
+
stakeAccount.state = 'active';
|
|
23572
|
+
}
|
|
23573
|
+
else {
|
|
23574
|
+
stakeAccount.state = 'activating';
|
|
23575
|
+
}
|
|
23576
|
+
}
|
|
23577
|
+
}
|
|
23578
|
+
}
|
|
23579
|
+
catch {
|
|
23580
|
+
// If parsing fails, keep default 'inactive' state
|
|
23581
|
+
}
|
|
23582
|
+
stakeAccounts.push(stakeAccount);
|
|
23583
|
+
}
|
|
23584
|
+
return stakeAccounts;
|
|
23585
|
+
}
|
|
23465
23586
|
/**
|
|
23466
23587
|
* Withdraws stake from a stake pool using a Fogo session.
|
|
23467
23588
|
*
|
|
23468
|
-
* The on-chain program creates stake account PDAs
|
|
23469
|
-
*
|
|
23589
|
+
* The on-chain program creates stake account PDAs. The rent for these accounts
|
|
23590
|
+
* is paid by the payer (typically the paymaster), not deducted from the user's withdrawal.
|
|
23470
23591
|
*
|
|
23471
23592
|
* @param connection - Solana connection
|
|
23472
23593
|
* @param stakePoolAddress - The stake pool to withdraw from
|
|
23473
23594
|
* @param signerOrSession - The session signer public key
|
|
23474
23595
|
* @param userPubkey - User's wallet (used for PDA derivation and token ownership)
|
|
23475
|
-
* @param payer - Payer for stake account rent (paymaster
|
|
23596
|
+
* @param payer - Payer for stake account rent (typically paymaster)
|
|
23476
23597
|
* @param amount - Amount of pool tokens to withdraw
|
|
23477
23598
|
* @param userStakeSeedStart - Starting seed for user stake PDA derivation (default: 0)
|
|
23478
23599
|
* @param useReserve - Whether to withdraw from reserve (default: false)
|
|
@@ -23544,7 +23665,7 @@ var solanaStakePool = (function (exports, node_buffer) {
|
|
|
23544
23665
|
const stakeReceiverPubkey = findUserStakeProgramAddress(stakePoolProgramId, userPubkey, userStakeSeed);
|
|
23545
23666
|
stakeAccountPubkeys.push(stakeReceiverPubkey);
|
|
23546
23667
|
userStakeSeeds.push(userStakeSeed);
|
|
23547
|
-
// The on-chain program
|
|
23668
|
+
// The on-chain program creates the stake account PDA and rent is paid by payer.
|
|
23548
23669
|
instructions.push(StakePoolInstruction.withdrawStakeWithSession({
|
|
23549
23670
|
programId: stakePoolProgramId,
|
|
23550
23671
|
stakePool: stakePoolAddress,
|
|
@@ -23957,6 +24078,7 @@ var solanaStakePool = (function (exports, node_buffer) {
|
|
|
23957
24078
|
exports.getStakePoolAccount = getStakePoolAccount;
|
|
23958
24079
|
exports.getStakePoolAccounts = getStakePoolAccounts;
|
|
23959
24080
|
exports.getStakePoolProgramId = getStakePoolProgramId;
|
|
24081
|
+
exports.getUserStakeAccounts = getUserStakeAccounts;
|
|
23960
24082
|
exports.increaseValidatorStake = increaseValidatorStake;
|
|
23961
24083
|
exports.removeValidatorFromPool = removeValidatorFromPool;
|
|
23962
24084
|
exports.stakePoolInfo = stakePoolInfo;
|