Skip to content

Commit

Permalink
add remaining accounts param to depositStake and remove spl stake poo… (
Browse files Browse the repository at this point in the history
#18)

* add remaining accounts param to depositStake and remove spl stake pool package and replace with more handrolled stuff using coral borsh

* update package version
  • Loading branch information
ggnine-jito authored Jan 16, 2025
1 parent 9c69a34 commit 19da190
Show file tree
Hide file tree
Showing 8 changed files with 179 additions and 51 deletions.
5 changes: 0 additions & 5 deletions .github/workflows/npm-publish.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
name: Publish Package to NPM

on:
push:
branches: [ master ]
paths:
- 'package/**'
- '.github/workflows/npm-publish.yml'
workflow_dispatch:

jobs:
Expand Down
5 changes: 3 additions & 2 deletions package/dist/depositStake.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Connection, PublicKey, Signer, TransactionInstruction } from "@solana/web3.js";
import { Connection, PublicKey, Signer, TransactionInstruction, AccountMeta } from "@solana/web3.js";
/**
* Creates instructions required to deposit stake to stake pool via
* Stake Deposit Interceptor.
Expand All @@ -10,8 +10,9 @@ import { Connection, PublicKey, Signer, TransactionInstruction } from "@solana/w
* @param validatorVote
* @param depositStake
* @param poolTokenReceiverAccount
* @param remainingAccounts - optional additional accounts to append to the instruction
*/
export declare const depositStake: (connection: Connection, payer: PublicKey, stakePoolAddress: PublicKey, authorizedPubkey: PublicKey, validatorVote: PublicKey, depositStake: PublicKey, poolTokenReceiverAccount?: PublicKey) => Promise<{
export declare const depositStake: (connection: Connection, payer: PublicKey, stakePoolAddress: PublicKey, authorizedPubkey: PublicKey, validatorVote: PublicKey, depositStake: PublicKey, poolTokenReceiverAccount?: PublicKey, remainingAccounts?: AccountMeta[]) => Promise<{
instructions: TransactionInstruction[];
signers: Signer[];
}>;
49 changes: 43 additions & 6 deletions package/dist/depositStake.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,41 @@
Object.defineProperty(exports, "__esModule", { value: true });
exports.depositStake = void 0;
const web3_js_1 = require("@solana/web3.js");
const spl_stake_pool_1 = require("@solana/spl-stake-pool");
const generated_1 = require("./generated");
const spl_token_1 = require("@solana/spl-token");
const borsh_1 = require("@coral-xyz/borsh");
/**
* Copied from @solana/spl-stake-pool for compatibility reasons.
* Source: https://github.com/solana-labs/solana-program-library/blob/b7dd8fee/stake-pool/js/src/index.ts
*/
const STAKE_POOL_PROGRAM_ID = new web3_js_1.PublicKey("SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy");
const StakePoolLayout = (0, borsh_1.struct)([
(0, borsh_1.u8)('accountType'),
(0, borsh_1.publicKey)('manager'),
(0, borsh_1.publicKey)('staker'),
(0, borsh_1.publicKey)('stakeDepositAuthority'),
(0, borsh_1.u8)('stakeWithdrawBumpSeed'),
(0, borsh_1.publicKey)('validatorList'),
(0, borsh_1.publicKey)('reserveStake'),
(0, borsh_1.publicKey)('poolMint'),
(0, borsh_1.publicKey)('managerFeeAccount'),
(0, borsh_1.publicKey)('tokenProgramId'),
(0, borsh_1.u64)('totalLamports'),
(0, borsh_1.u64)('poolTokenSupply'),
(0, borsh_1.u64)('lastUpdateEpoch'),
]);
const getStakePoolAccount = async (connection, stakePoolAddress) => {
const account = await connection.getAccountInfo(stakePoolAddress);
if (!account)
throw new Error("Stake pool account not found");
const data = StakePoolLayout.decode(account.data);
return {
pubkey: stakePoolAddress,
account: {
data
}
};
};
/**
* Creates instructions required to deposit stake to stake pool via
* Stake Deposit Interceptor.
Expand All @@ -16,12 +48,13 @@ const spl_token_1 = require("@solana/spl-token");
* @param validatorVote
* @param depositStake
* @param poolTokenReceiverAccount
* @param remainingAccounts - optional additional accounts to append to the instruction
*/
const depositStake = async (connection, payer, stakePoolAddress, authorizedPubkey, validatorVote, depositStake, poolTokenReceiverAccount) => {
const stakePool = await (0, spl_stake_pool_1.getStakePoolAccount)(connection, stakePoolAddress);
const depositStake = async (connection, payer, stakePoolAddress, authorizedPubkey, validatorVote, depositStake, poolTokenReceiverAccount, remainingAccounts) => {
const stakePool = await getStakePoolAccount(connection, stakePoolAddress);
const stakePoolDepositAuthority = await generated_1.StakePoolDepositStakeAuthority.fromAccountAddress(connection, stakePool.account.data.stakeDepositAuthority);
const withdrawAuthority = await findWithdrawAuthorityProgramAddress(spl_stake_pool_1.STAKE_POOL_PROGRAM_ID, stakePoolAddress);
const validatorStake = await findStakeProgramAddress(spl_stake_pool_1.STAKE_POOL_PROGRAM_ID, validatorVote, stakePoolAddress);
const withdrawAuthority = await findWithdrawAuthorityProgramAddress(STAKE_POOL_PROGRAM_ID, stakePoolAddress);
const validatorStake = await findStakeProgramAddress(STAKE_POOL_PROGRAM_ID, validatorVote, stakePoolAddress);
const instructions = [];
const signers = [];
const base = web3_js_1.Keypair.generate();
Expand Down Expand Up @@ -58,7 +91,7 @@ const depositStake = async (connection, payer, stakePoolAddress, authorizedPubke
};
const depositStakeIxAccounts = {
payer,
stakePoolProgram: spl_stake_pool_1.STAKE_POOL_PROGRAM_ID,
stakePoolProgram: STAKE_POOL_PROGRAM_ID,
depositReceipt: depositReceiptAddress,
stakePool: stakePoolAddress,
validatorStakeList: stakePool.account.data.validatorList,
Expand All @@ -79,6 +112,10 @@ const depositStake = async (connection, payer, stakePoolAddress, authorizedPubke
systemProgram: web3_js_1.SystemProgram.programId,
};
const depositStakeIx = (0, generated_1.createDepositStakeInstruction)(depositStakeIxAccounts, depositStakeIxArgs);
// Add any remaining accounts to the instruction
if (remainingAccounts?.length) {
depositStakeIx.keys.push(...remainingAccounts);
}
instructions.push(depositStakeIx);
return {
instructions,
Expand Down
6 changes: 3 additions & 3 deletions package/dist/generated/accounts/DepositReceipt.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@ export declare class DepositReceipt implements DepositReceiptArgs {
owner: string;
stakePool: string;
stakePoolDepositStakeAuthority: string;
depositTime: any;
lstAmount: any;
coolDownSeconds: any;
depositTime: beet.bignum;
lstAmount: beet.bignum;
coolDownSeconds: beet.bignum;
initialFeeBps: number;
bumpSeed: number;
reserved: number[];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ export declare class StakePoolDepositStakeAuthority implements StakePoolDepositS
authority: string;
vault: string;
stakePoolProgramId: string;
coolDownSeconds: any;
coolDownSeconds: beet.bignum;
initalFeeBps: number;
feeWallet: string;
bumpSeed: number;
Expand Down
33 changes: 24 additions & 9 deletions package/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@jito-foundation/stake-deposit-interceptor-sdk",
"version": "1.6.2",
"version": "1.7.0",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
Expand All @@ -19,19 +19,34 @@
"dependencies": {
"@metaplex-foundation/beet": "^0.7.1",
"@metaplex-foundation/beet-solana": "^0.4.0",
"@solana/spl-stake-pool": "^1.1.8",
"@solana/spl-token": "^0.4.0",
"@solana/buffer-layout": "^4.0.0",
"@solana/buffer-layout-utils": "^0.2.0",
"bs58": "^5.0.0",
"buffer": "^6.0.3",
"bn.js": "^5.2.0"
},
"peerDependencies": {
"@solana/web3.js": "^1.73.5",
"@solana/spl-token": "^0.4.0",
"@coral-xyz/borsh": "^0.30.1",
"@noble/ed25519": "^1.7.1",
"@noble/curves": "^1.1.0",
"@noble/hashes": "^1.3.1",
"@noble/ed25519": "^1.7.1",
"@noble/secp256k1": "^1.6.3",
"rpc-websockets": "^7.5.1",
"bs58": "^5.0.0",
"buffer": "^6.0.3",
"superstruct": "^1.0.3"
"rpc-websockets": "^7.5.1"
},
"devDependencies": {
"typescript": "^5.0.0"
"typescript": "^5.0.0",
"@solana/web3.js": "^1.73.5",
"@solana/spl-token": "^0.4.0",
"@coral-xyz/borsh": "^0.30.1",
"@noble/ed25519": "^1.7.1",
"@noble/curves": "^1.1.0",
"@noble/hashes": "^1.3.1",
"@noble/secp256k1": "^1.6.3",
"rpc-websockets": "^7.5.1",
"superstruct": "^1.0.3",
"@types/node": "^20.0.0",
"@types/bn.js": "^5.1.0"
}
}
76 changes: 71 additions & 5 deletions package/src/depositStake.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,8 @@ import {
SYSVAR_CLOCK_PUBKEY,
SYSVAR_STAKE_HISTORY_PUBKEY,
TransactionInstruction,
AccountMeta,
} from "@solana/web3.js";
import {
getStakePoolAccount,
STAKE_POOL_PROGRAM_ID,
} from "@solana/spl-stake-pool";
import {
createDepositStakeInstruction,
DepositStakeInstructionAccounts,
Expand All @@ -26,6 +23,67 @@ import {
getAssociatedTokenAddressSync,
TOKEN_PROGRAM_ID,
} from "@solana/spl-token";
import BN from "bn.js";
import { struct, u8, publicKey, u64 } from '@coral-xyz/borsh';

/**
* Copied from @solana/spl-stake-pool for compatibility reasons.
* Source: https://github.com/solana-labs/solana-program-library/blob/b7dd8fee/stake-pool/js/src/index.ts
*/
const STAKE_POOL_PROGRAM_ID = new PublicKey("SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy");

/**
* Copied from @solana/spl-stake-pool for compatibility.
* We only need the account data structure, not the full package.
*/
type StakePoolLayout = {
accountType: number;
manager: PublicKey;
staker: PublicKey;
stakeDepositAuthority: PublicKey;
stakeWithdrawBumpSeed: number;
validatorList: PublicKey;
reserveStake: PublicKey;
poolMint: PublicKey;
managerFeeAccount: PublicKey;
tokenProgramId: PublicKey;
totalLamports: BN;
poolTokenSupply: BN;
lastUpdateEpoch: BN;
};

const StakePoolLayout = struct<StakePoolLayout>([
u8('accountType'),
publicKey('manager'),
publicKey('staker'),
publicKey('stakeDepositAuthority'),
u8('stakeWithdrawBumpSeed'),
publicKey('validatorList'),
publicKey('reserveStake'),
publicKey('poolMint'),
publicKey('managerFeeAccount'),
publicKey('tokenProgramId'),
u64('totalLamports'),
u64('poolTokenSupply'),
u64('lastUpdateEpoch'),
]);

const getStakePoolAccount = async (
connection: Connection,
stakePoolAddress: PublicKey
) => {
const account = await connection.getAccountInfo(stakePoolAddress);
if (!account) throw new Error("Stake pool account not found");

const data = StakePoolLayout.decode(account.data) as StakePoolLayout;

return {
pubkey: stakePoolAddress,
account: {
data
}
};
};

/**
* Creates instructions required to deposit stake to stake pool via
Expand All @@ -38,6 +96,7 @@ import {
* @param validatorVote
* @param depositStake
* @param poolTokenReceiverAccount
* @param remainingAccounts - optional additional accounts to append to the instruction
*/
export const depositStake = async (
connection: Connection,
Expand All @@ -46,7 +105,8 @@ export const depositStake = async (
authorizedPubkey: PublicKey,
validatorVote: PublicKey,
depositStake: PublicKey,
poolTokenReceiverAccount?: PublicKey
poolTokenReceiverAccount?: PublicKey,
remainingAccounts?: AccountMeta[]
) => {
const stakePool = await getStakePoolAccount(connection, stakePoolAddress);
const stakePoolDepositAuthority =
Expand Down Expand Up @@ -147,6 +207,12 @@ export const depositStake = async (
depositStakeIxAccounts,
depositStakeIxArgs
);

// Add any remaining accounts to the instruction
if (remainingAccounts?.length) {
depositStakeIx.keys.push(...remainingAccounts);
}

instructions.push(depositStakeIx);

return {
Expand Down
Loading

0 comments on commit 19da190

Please sign in to comment.