Kaynağa Gözat

Add initializeAccount test for JS client

Loris Leiva 1 yıl önce
ebeveyn
işleme
5ab61692b2

+ 40 - 0
clients/js/test/_setup.ts

@@ -9,6 +9,7 @@ import {
   TransactionMessageWithBlockhashLifetime,
   TransactionSigner,
   airdropFactory,
+  appendTransactionMessageInstructions,
   createSolanaRpc,
   createSolanaRpcSubscriptions,
   createTransactionMessage,
@@ -21,6 +22,12 @@ import {
   setTransactionMessageLifetimeUsingBlockhash,
   signTransactionMessageWithSigners,
 } from '@solana/web3.js';
+import {
+  TOKEN_PROGRAM_ADDRESS,
+  getInitializeMintInstruction,
+  getMintSize,
+} from '../src/index.js';
+import { getCreateAccountInstruction } from '@solana-program/system';
 
 type Client = {
   rpc: Rpc<SolanaRpcApi>;
@@ -78,3 +85,36 @@ export const signAndSendTransaction = async (
 export const getBalance = async (client: Client, address: Address) =>
   (await client.rpc.getBalance(address, { commitment: 'confirmed' }).send())
     .value;
+
+export const createMint = async (
+  client: Client,
+  authority: TransactionSigner
+): Promise<Address> => {
+  const space = BigInt(getMintSize());
+  const [transactionMessage, rent, mint] = await Promise.all([
+    createDefaultTransaction(client, authority),
+    client.rpc.getMinimumBalanceForRentExemption(space).send(),
+    generateKeyPairSigner(),
+  ]);
+  const instructions = [
+    getCreateAccountInstruction({
+      payer: authority,
+      newAccount: mint,
+      lamports: rent,
+      space,
+      programAddress: TOKEN_PROGRAM_ADDRESS,
+    }),
+    getInitializeMintInstruction({
+      mint: mint.address,
+      decimals: 2,
+      mintAuthority: authority.address,
+    }),
+  ];
+  await pipe(
+    transactionMessage,
+    (tx) => appendTransactionMessageInstructions(instructions, tx),
+    (tx) => signAndSendTransaction(client, tx)
+  );
+
+  return mint.address;
+};

+ 75 - 0
clients/js/test/initializeAccount.test.ts

@@ -0,0 +1,75 @@
+import { getCreateAccountInstruction } from '@solana-program/system';
+import {
+  Account,
+  appendTransactionMessageInstructions,
+  generateKeyPairSigner,
+  none,
+  pipe,
+} from '@solana/web3.js';
+import test from 'ava';
+import {
+  AccountState,
+  TOKEN_PROGRAM_ADDRESS,
+  Token,
+  fetchToken,
+  getInitializeAccountInstruction,
+  getTokenSize,
+} from '../src/index.js';
+import {
+  createDefaultSolanaClient,
+  createDefaultTransaction,
+  createMint,
+  generateKeyPairSignerWithSol,
+  signAndSendTransaction,
+} from './_setup.js';
+
+test('it creates and initializes a new token account', async (t) => {
+  // Given a mint account, its mint authority and two generated keypairs
+  // for the token to be created and its owner.
+  const client = createDefaultSolanaClient();
+  const [mintAuthority, token, owner] = await Promise.all([
+    generateKeyPairSignerWithSol(client),
+    generateKeyPairSigner(),
+    generateKeyPairSigner(),
+  ]);
+  const mint = await createMint(client, mintAuthority);
+
+  // When we create and initialize a token account at this address.
+  const space = BigInt(getTokenSize());
+  const rent = await client.rpc.getMinimumBalanceForRentExemption(space).send();
+  const instructions = [
+    getCreateAccountInstruction({
+      payer: mintAuthority,
+      newAccount: token,
+      lamports: rent,
+      space,
+      programAddress: TOKEN_PROGRAM_ADDRESS,
+    }),
+    getInitializeAccountInstruction({
+      account: token.address,
+      mint,
+      owner: owner.address,
+    }),
+  ];
+  await pipe(
+    await createDefaultTransaction(client, mintAuthority),
+    (tx) => appendTransactionMessageInstructions(instructions, tx),
+    (tx) => signAndSendTransaction(client, tx)
+  );
+
+  // Then we expect the token account to exist and have the following data.
+  const tokenAccount = await fetchToken(client.rpc, token.address);
+  t.like(tokenAccount, <Account<Token>>{
+    address: token.address,
+    data: {
+      mint,
+      owner: owner.address,
+      amount: 0n,
+      delegate: none(),
+      state: AccountState.Initialized,
+      isNative: none(),
+      delegatedAmount: 0n,
+      closeAuthority: none(),
+    },
+  });
+});