@nosana/kit
Version:
Nosana KIT
136 lines • 4.73 kB
JavaScript
import { parseBase64RpcAccount } from '@solana/kit';
import { NosanaError, ErrorCodes } from '../../../errors/NosanaError.js';
import * as programClient from '@nosana/stake-program';
import { convertBigIntToNumber } from '../../../utils/index.js';
import bs58 from 'bs58';
import * as Instructions from './instructions/index.js';
/**
* Creates a new StakeProgram instance.
*
* @param deps - Program dependencies (config, logger, solana service, wallet getter)
* @returns A StakeProgram instance with methods to interact with the stake program
*
* @example
* ```ts
* import { createStakeProgram } from '@nosana/kit';
*
* const stakeProgram = createStakeProgram({
* config,
* logger,
* solana,
* getWallet,
* });
*
* const stake = await stakeProgram.get('stake-address');
* ```
*/
export function createStakeProgram(deps, config) {
const programId = config.stakeAddress;
const client = programClient;
/**
* Transform stake account to include address and convert BigInt to numbers
*/
function transformStakeAccount(stakeAccount) {
const { discriminator: _, ...stakeAccountData } = stakeAccount.data;
return {
address: stakeAccount.address,
...convertBigIntToNumber(stakeAccountData),
};
}
function getRequiredWallet() {
const wallet = deps.getWallet();
if (!wallet) {
throw new NosanaError('Wallet is required for this operation', ErrorCodes.NO_WALLET);
}
return wallet;
}
function createInstructionsHelper() {
return {
deps,
config,
client,
getRequiredWallet,
getNosATA: deps.nos.getATA,
};
}
return {
async stake(params) {
return Instructions.stake(params, createInstructionsHelper());
},
async getAddress(owner) {
const resolvedOwner = owner ?? getRequiredWallet().address;
return deps.solana.pda(['stake', config.nosTokenAddress, resolvedOwner], programId);
},
async getByOwner(owner) {
const addr = await this.getAddress(owner);
return this.get(addr);
},
/**
* Fetch a stake account by address
*/
async get(addr) {
try {
const stakeAccount = await client.fetchStakeAccount(deps.solana.rpc, addr);
const stake = transformStakeAccount(stakeAccount);
return stake;
}
catch (err) {
deps.logger.error(`Failed to fetch stake ${err}`);
throw err;
}
},
/**
* Fetch multiple stake accounts by address
*/
async multiple(addresses) {
try {
const stakeAccounts = await client.fetchAllStakeAccount(deps.solana.rpc, addresses);
const stakes = stakeAccounts.map((stakeAccount) => transformStakeAccount(stakeAccount));
return stakes;
}
catch (err) {
deps.logger.error(`Failed to fetch stakes ${err}`);
throw err;
}
},
/**
* Fetch all stake accounts
*/
async all() {
try {
const getProgramAccountsResponse = await deps.solana.rpc
.getProgramAccounts(programId, {
encoding: 'base64',
filters: [
{
memcmp: {
offset: BigInt(0),
bytes: bs58.encode(Buffer.from(client.STAKE_ACCOUNT_DISCRIMINATOR)),
encoding: 'base58',
},
},
],
})
.send();
const stakes = getProgramAccountsResponse
.map((result) => {
try {
const stakeAccount = programClient.decodeStakeAccount(parseBase64RpcAccount(result.pubkey, result.account));
return transformStakeAccount(stakeAccount);
}
catch (err) {
deps.logger.error(`Failed to decode stake ${err}`);
return null;
}
})
.filter((account) => account !== null);
return stakes;
}
catch (err) {
deps.logger.error(`Failed to fetch all stakes ${err}`);
throw err;
}
},
};
}
//# sourceMappingURL=StakeProgram.js.map