Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clients/js-legacy/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
"@solana/web3.js": "^1.98.4",
"@solana/addresses": "6.5.0",
"@solana/prettier-config-solana": "^0.0.6",
"@solana/rpc-api": "6.5.0",
"@solana/rpc-spec": "6.5.0",
"@solana/spl-single-pool": "workspace:*",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-prettier": "^5.5.5",
Expand Down
17 changes: 13 additions & 4 deletions clients/js-legacy/src/internal.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,33 @@
import { Address } from '@solana/addresses';
import {
GetAccountInfoApi,
GetMinimumBalanceForRentExemptionApi,
GetStakeMinimumDelegationApi,
} from '@solana/rpc-api';
import { Rpc } from '@solana/rpc-spec';
import { Connection, Transaction, TransactionInstruction, PublicKey } from '@solana/web3.js';
import { Buffer } from 'buffer';

export function rpc(connection: Connection) {
export function rpc(
connection: Connection,
): Rpc<GetAccountInfoApi & GetMinimumBalanceForRentExemptionApi & GetStakeMinimumDelegationApi> {
return {
getAccountInfo(address: string) {
getAccountInfo(address: Address): any {
return {
async send() {
const pubkey = new PublicKey(address);
return await connection.getAccountInfo(pubkey);
},
};
},
getMinimumBalanceForRentExemption(size: bigint) {
getMinimumBalanceForRentExemption(size: bigint): any {
return {
async send() {
return BigInt(await connection.getMinimumBalanceForRentExemption(Number(size)));
},
};
},
getStakeMinimumDelegation() {
getStakeMinimumDelegation(): any {
return {
async send() {
const minimumDelegation = await connection.getStakeMinimumDelegation();
Expand Down
8 changes: 6 additions & 2 deletions clients/js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@
},
"dependencies": {
"@solana/addresses": "6.5.0",
"@solana/instructions": "2.3.0",
"@solana/transaction-messages": "2.2.1"
"@solana/functional": "6.5.0",
"@solana/instructions": "6.5.0",
"@solana/instruction-plans": "6.5.0",
"@solana/rpc-api": "6.5.0",
"@solana/rpc-spec": "6.5.0",
"@solana/transaction-messages": "6.5.0"
}
}
48 changes: 24 additions & 24 deletions clients/js/src/instructions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import { getAddressCodec, Address } from '@solana/addresses';
import {
ReadonlySignerAccount,
ReadonlyAccount,
IInstructionWithAccounts,
IInstructionWithData,
InstructionWithAccounts,
InstructionWithData,
WritableAccount,
WritableSignerAccount,
IInstruction,
Instruction,
AccountRole,
} from '@solana/instructions';

Expand Down Expand Up @@ -42,8 +42,8 @@ import {
u64,
} from './quarantine.js';

type InitializePoolInstruction = IInstruction<typeof SINGLE_POOL_PROGRAM_ID> &
IInstructionWithAccounts<
type InitializePoolInstruction = Instruction<typeof SINGLE_POOL_PROGRAM_ID> &
InstructionWithAccounts<
[
ReadonlyAccount<VoteAccountAddress>,
WritableAccount<PoolAddress>,
Expand All @@ -60,10 +60,10 @@ type InitializePoolInstruction = IInstruction<typeof SINGLE_POOL_PROGRAM_ID> &
ReadonlyAccount<typeof STAKE_PROGRAM_ID>,
]
> &
IInstructionWithData<Uint8Array>;
InstructionWithData<Uint8Array>;

type ReplenishPoolInstruction = IInstruction<typeof SINGLE_POOL_PROGRAM_ID> &
IInstructionWithAccounts<
type ReplenishPoolInstruction = Instruction<typeof SINGLE_POOL_PROGRAM_ID> &
InstructionWithAccounts<
[
ReadonlyAccount<VoteAccountAddress>,
ReadonlyAccount<PoolAddress>,
Expand All @@ -76,10 +76,10 @@ type ReplenishPoolInstruction = IInstruction<typeof SINGLE_POOL_PROGRAM_ID> &
ReadonlyAccount<typeof STAKE_PROGRAM_ID>,
]
> &
IInstructionWithData<Uint8Array>;
InstructionWithData<Uint8Array>;

type DepositStakeInstruction = IInstruction<typeof SINGLE_POOL_PROGRAM_ID> &
IInstructionWithAccounts<
type DepositStakeInstruction = Instruction<typeof SINGLE_POOL_PROGRAM_ID> &
InstructionWithAccounts<
[
ReadonlyAccount<PoolAddress>,
WritableAccount<PoolStakeAddress>,
Expand All @@ -96,10 +96,10 @@ type DepositStakeInstruction = IInstruction<typeof SINGLE_POOL_PROGRAM_ID> &
ReadonlyAccount<typeof STAKE_PROGRAM_ID>,
]
> &
IInstructionWithData<Uint8Array>;
InstructionWithData<Uint8Array>;

type WithdrawStakeInstruction = IInstruction<typeof SINGLE_POOL_PROGRAM_ID> &
IInstructionWithAccounts<
type WithdrawStakeInstruction = Instruction<typeof SINGLE_POOL_PROGRAM_ID> &
InstructionWithAccounts<
[
ReadonlyAccount<PoolAddress>,
WritableAccount<PoolStakeAddress>,
Expand All @@ -114,10 +114,10 @@ type WithdrawStakeInstruction = IInstruction<typeof SINGLE_POOL_PROGRAM_ID> &
ReadonlyAccount<typeof STAKE_PROGRAM_ID>,
]
> &
IInstructionWithData<Uint8Array>;
InstructionWithData<Uint8Array>;

type CreateTokenMetadataInstruction = IInstruction<typeof SINGLE_POOL_PROGRAM_ID> &
IInstructionWithAccounts<
type CreateTokenMetadataInstruction = Instruction<typeof SINGLE_POOL_PROGRAM_ID> &
InstructionWithAccounts<
[
ReadonlyAccount<PoolAddress>,
ReadonlyAccount<PoolMintAddress>,
Expand All @@ -129,10 +129,10 @@ type CreateTokenMetadataInstruction = IInstruction<typeof SINGLE_POOL_PROGRAM_ID
ReadonlyAccount<typeof SYSTEM_PROGRAM_ID>,
]
> &
IInstructionWithData<Uint8Array>;
InstructionWithData<Uint8Array>;

type UpdateTokenMetadataInstruction = IInstruction<typeof SINGLE_POOL_PROGRAM_ID> &
IInstructionWithAccounts<
type UpdateTokenMetadataInstruction = Instruction<typeof SINGLE_POOL_PROGRAM_ID> &
InstructionWithAccounts<
[
ReadonlyAccount<VoteAccountAddress>,
ReadonlyAccount<PoolAddress>,
Expand All @@ -142,10 +142,10 @@ type UpdateTokenMetadataInstruction = IInstruction<typeof SINGLE_POOL_PROGRAM_ID
ReadonlyAccount<typeof MPL_METADATA_PROGRAM_ID>,
]
> &
IInstructionWithData<Uint8Array>;
InstructionWithData<Uint8Array>;

type InitializeOnRampInstruction = IInstruction<typeof SINGLE_POOL_PROGRAM_ID> &
IInstructionWithAccounts<
type InitializeOnRampInstruction = Instruction<typeof SINGLE_POOL_PROGRAM_ID> &
InstructionWithAccounts<
[
ReadonlyAccount<PoolAddress>,
WritableAccount<PoolOnRampAddress>,
Expand All @@ -155,7 +155,7 @@ type InitializeOnRampInstruction = IInstruction<typeof SINGLE_POOL_PROGRAM_ID> &
ReadonlyAccount<typeof STAKE_PROGRAM_ID>,
]
> &
IInstructionWithData<Uint8Array>;
InstructionWithData<Uint8Array>;

const enum SinglePoolInstructionType {
InitializePool = 0,
Expand Down
148 changes: 76 additions & 72 deletions clients/js/src/transactions.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
import { Address } from '@solana/addresses';
import { pipe } from '@solana/functional';
import {
InstructionPlan,
assertIsSingleTransactionPlan,
createTransactionPlanner,
parallelInstructionPlan,
sequentialInstructionPlan,
} from '@solana/instruction-plans';
import {
GetAccountInfoApi,
GetMinimumBalanceForRentExemptionApi,
GetStakeMinimumDelegationApi,
} from '@solana/rpc-api';
import { Rpc } from '@solana/rpc-spec';
import {
appendTransactionMessageInstruction,
createTransactionMessage,
setTransactionMessageFeePayer,
TransactionVersion,
TransactionMessage,
} from '@solana/transaction-messages';
Expand Down Expand Up @@ -40,7 +55,7 @@ import {
} from './quarantine.js';

interface DepositParams {
rpc: any; // XXX Rpc<???>
rpc: Rpc<GetAccountInfoApi & GetMinimumBalanceForRentExemptionApi & GetStakeMinimumDelegationApi>;
pool: PoolAddress;
userWallet: Address;
userStakeAccount?: Address;
Expand All @@ -52,7 +67,7 @@ interface DepositParams {
}

interface WithdrawParams {
rpc: any; // XXX Rpc<???>
rpc: Rpc<GetMinimumBalanceForRentExemptionApi & GetStakeMinimumDelegationApi>;
pool: PoolAddress;
userWallet: Address;
userStakeAccount: Address;
Expand All @@ -78,83 +93,72 @@ export const SinglePoolProgram = {
createAndDelegateUserStake: createAndDelegateUserStakeTransaction,
};

export async function initializeTransaction(
rpc: any, // XXX not exported: Rpc<???>,
async function getInitializeInstructionPlan(
rpc: Rpc<GetMinimumBalanceForRentExemptionApi & GetStakeMinimumDelegationApi>,
voteAccount: VoteAccountAddress,
payer: Address,
skipMetadata = false,
): Promise<TransactionMessage> {
let transaction = createTransactionMessage({ version: 0 });

): Promise<InstructionPlan> {
const pool = await findPoolAddress(SINGLE_POOL_PROGRAM_ID, voteAccount);
const [stake, mint, onramp, poolRent, stakeRent, mintRent, minimumDelegationObj] =
await Promise.all([
findPoolStakeAddress(SINGLE_POOL_PROGRAM_ID, pool),
findPoolMintAddress(SINGLE_POOL_PROGRAM_ID, pool),
findPoolOnRampAddress(SINGLE_POOL_PROGRAM_ID, pool),
rpc.getMinimumBalanceForRentExemption(SINGLE_POOL_ACCOUNT_SIZE).send(),
rpc.getMinimumBalanceForRentExemption(STAKE_ACCOUNT_SIZE).send(),
rpc.getMinimumBalanceForRentExemption(MINT_SIZE).send(),
rpc.getStakeMinimumDelegation().send(),
]);
const [
stake,
mint,
onramp,
poolRent,
stakeRent,
mintRent,
minimumDelegationObj,
initializePool,
initializeOnRamp,
] = await Promise.all([
findPoolStakeAddress(SINGLE_POOL_PROGRAM_ID, pool),
findPoolMintAddress(SINGLE_POOL_PROGRAM_ID, pool),
findPoolOnRampAddress(SINGLE_POOL_PROGRAM_ID, pool),
rpc.getMinimumBalanceForRentExemption(SINGLE_POOL_ACCOUNT_SIZE).send(),
rpc.getMinimumBalanceForRentExemption(STAKE_ACCOUNT_SIZE).send(),
rpc.getMinimumBalanceForRentExemption(MINT_SIZE).send(),
rpc.getStakeMinimumDelegation().send(),
initializePoolInstruction(voteAccount),
initializeOnRampInstruction(pool),
]);
const lamportsPerSol = 1_000_000_000n;
const minimumPoolBalance =
minimumDelegationObj.value > lamportsPerSol ? minimumDelegationObj.value : lamportsPerSol;

transaction = appendTransactionMessageInstruction(
SystemInstruction.transfer({
from: payer,
to: pool,
lamports: poolRent,
}),
transaction,
);

transaction = appendTransactionMessageInstruction(
SystemInstruction.transfer({
from: payer,
to: stake,
lamports: stakeRent + minimumPoolBalance,
}),
transaction,
);

transaction = appendTransactionMessageInstruction(
SystemInstruction.transfer({
from: payer,
to: onramp,
lamports: stakeRent,
}),
transaction,
);

transaction = appendTransactionMessageInstruction(
SystemInstruction.transfer({
from: payer,
to: mint,
lamports: mintRent,
}),
transaction,
);

transaction = appendTransactionMessageInstruction(
await initializePoolInstruction(voteAccount),
transaction,
);

transaction = appendTransactionMessageInstruction(
await initializeOnRampInstruction(pool),
transaction,
);

if (!skipMetadata) {
transaction = appendTransactionMessageInstruction(
await createTokenMetadataInstruction(pool, payer),
transaction,
);
}
return sequentialInstructionPlan([
parallelInstructionPlan([
SystemInstruction.transfer({ from: payer, to: pool, lamports: poolRent }),
SystemInstruction.transfer({
from: payer,
to: stake,
lamports: stakeRent + minimumPoolBalance,
}),
SystemInstruction.transfer({ from: payer, to: onramp, lamports: stakeRent }),
SystemInstruction.transfer({ from: payer, to: mint, lamports: mintRent }),
]),
initializePool,
initializeOnRamp,
...(skipMetadata ? [] : [await createTokenMetadataInstruction(pool, payer)]),
]);
}

return transaction;
export async function initializeTransaction(
rpc: Rpc<GetMinimumBalanceForRentExemptionApi & GetStakeMinimumDelegationApi>,
voteAccount: VoteAccountAddress,
payer: Address,
skipMetadata = false,
): Promise<TransactionMessage> {
const transactionPlanner = createTransactionPlanner({
createTransactionMessage: () =>
pipe(createTransactionMessage({ version: 0 }), (m) =>
setTransactionMessageFeePayer(payer, m),
),
});

const instructionPlan = await getInitializeInstructionPlan(rpc, voteAccount, payer, skipMetadata);
const transactionPlan = await transactionPlanner(instructionPlan);
assertIsSingleTransactionPlan(transactionPlan);
return transactionPlan.message;
}

export async function replenishPoolTransaction(
Expand Down Expand Up @@ -321,7 +325,7 @@ export async function updateTokenMetadataTransaction(
}

export async function initializeOnRampTransaction(
rpc: any, // XXX not exported: Rpc<???>,
rpc: Rpc<GetMinimumBalanceForRentExemptionApi & GetStakeMinimumDelegationApi>,
pool: PoolAddress,
payer: Address,
): Promise<TransactionMessage> {
Expand Down Expand Up @@ -351,7 +355,7 @@ export async function initializeOnRampTransaction(

/** @deprecated */
export async function createAndDelegateUserStakeTransaction(
rpc: any, // XXX not exported: Rpc<???>,
rpc: Rpc<GetMinimumBalanceForRentExemptionApi & GetStakeMinimumDelegationApi>,
voteAccount: VoteAccountAddress,
userWallet: Address,
stakeAmount: bigint,
Expand Down
Loading
Loading