123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- import {
- SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE,
- appendTransactionMessageInstruction,
- isProgramError,
- isSolanaError,
- lamports,
- pipe,
- } from '@solana/web3.js';
- import test from 'ava';
- import {
- TOKEN_ERROR__INVALID_PDA,
- TOKEN_ERROR__INVALID_PROGRAM_OWNER,
- TOKEN_PROGRAM_ADDRESS,
- fetchCounter,
- findCounterPda,
- getIncrementInstruction,
- getIncrementInstructionAsync,
- } from '../src/index.js';
- import {
- createCounterForAuthority,
- createDefaultSolanaClient,
- createDefaultTransaction,
- generateKeyPairSignerWithSol,
- getBalance,
- signAndSendTransaction,
- } from './_setup.js';
- test('it increments an existing counter by 1 by default', async (t) => {
- // Given an authority key pair with an associated counter account of value 0.
- const client = createDefaultSolanaClient();
- const authority = await generateKeyPairSignerWithSol(client);
- const [counterPda] = await createCounterForAuthority(client, authority);
- t.is((await fetchCounter(client.rpc, counterPda)).data.value, 0);
- // When we increment the counter account.
- const incrementIx = await getIncrementInstructionAsync({ authority });
- await pipe(
- await createDefaultTransaction(client, authority),
- (tx) => appendTransactionMessageInstruction(incrementIx, tx),
- (tx) => signAndSendTransaction(client, tx)
- );
- // Then we expect the counter account to have a value of 1.
- const counter = await fetchCounter(client.rpc, counterPda);
- t.is(counter.data.value, 1);
- });
- test('it can increment an existing counter by a specified amount', async (t) => {
- // Given an authority key pair with an associated counter account of value 0.
- const client = createDefaultSolanaClient();
- const authority = await generateKeyPairSignerWithSol(client);
- const [counterPda] = await createCounterForAuthority(client, authority);
- t.is((await fetchCounter(client.rpc, counterPda)).data.value, 0);
- // When we increment the counter account by 5.
- const incrementIx = await getIncrementInstructionAsync({
- authority,
- amount: 5,
- });
- await pipe(
- await createDefaultTransaction(client, authority),
- (tx) => appendTransactionMessageInstruction(incrementIx, tx),
- (tx) => signAndSendTransaction(client, tx)
- );
- // Then we expect the counter account to have a value of 5.
- const counter = await fetchCounter(client.rpc, counterPda);
- t.is(counter.data.value, 5);
- });
- test('it cannot increment a counter that does not exist', async (t) => {
- // Given an authority key pair with no associated counter account.
- const client = createDefaultSolanaClient();
- const authority = await generateKeyPairSignerWithSol(client);
- const [counterPda] = await findCounterPda({ authority: authority.address });
- t.is(await getBalance(client, counterPda), lamports(0n));
- // When we try to increment the inexistent counter account.
- const incrementIx = await getIncrementInstructionAsync({ authority });
- const transactionMessage = pipe(
- await createDefaultTransaction(client, authority),
- (tx) => appendTransactionMessageInstruction(incrementIx, tx)
- );
- const promise = signAndSendTransaction(client, transactionMessage);
- // Then we expect the program to throw an error.
- const error = await t.throwsAsync(promise);
- t.true(
- isSolanaError(
- error,
- SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE
- )
- );
- t.true(
- isProgramError(
- error.cause,
- transactionMessage,
- TOKEN_PROGRAM_ADDRESS,
- TOKEN_ERROR__INVALID_PROGRAM_OWNER
- )
- );
- });
- test('it cannot increment a counter that belongs to another authority', async (t) => {
- // Given two authority key pairs such that
- // only one of them (authority A) is associated with a counter account.
- const client = createDefaultSolanaClient();
- const [authorityA, authorityB] = await Promise.all([
- generateKeyPairSignerWithSol(client),
- generateKeyPairSignerWithSol(client),
- ]);
- const [counterPda] = await createCounterForAuthority(client, authorityA);
- // When authority B tries to increment the counter account of authority A.
- const incrementIx = getIncrementInstruction({
- authority: authorityB,
- counter: counterPda,
- });
- const transactionMessage = pipe(
- await createDefaultTransaction(client, authorityB),
- (tx) => appendTransactionMessageInstruction(incrementIx, tx)
- );
- const promise = signAndSendTransaction(client, transactionMessage);
- // Then we expect the program to throw an error.
- const error = await t.throwsAsync(promise);
- t.true(
- isSolanaError(
- error,
- SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE
- )
- );
- t.true(
- isProgramError(
- error.cause,
- transactionMessage,
- TOKEN_PROGRAM_ADDRESS,
- TOKEN_ERROR__INVALID_PDA
- )
- );
- });
|