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
19 changes: 4 additions & 15 deletions clients/js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
"scripts": {
"build": "rimraf dist && tsup && tsc -p ./tsconfig.declarations.json",
"build:docs": "typedoc",
"test": "ava",
"dev": "vitest",
"test": "vitest run",
"lint": "eslint --ext js,ts,tsx src",
"lint:fix": "eslint --fix --ext js,ts,tsx src",
"format": "prettier --check src test",
Expand All @@ -49,30 +50,18 @@
"@solana-program/system": "^0.12.0"
},
"devDependencies": {
"@ava/typescript": "^4.1.0",
"@solana/eslint-config-solana": "^3.0.3",
"@solana/kit": "^6.5.0",
"@solana/kit-client-rpc": "^0.9.0",
"@types/node": "^24",
"@typescript-eslint/eslint-plugin": "^7.16.1",
"@typescript-eslint/parser": "^7.16.1",
"ava": "^6.1.3",
"eslint": "^8.57.0",
"prettier": "^3.8.1",
"rimraf": "^5.0.5",
"tsup": "^8.1.2",
"typedoc": "^0.25.12",
"typescript": "^5.9.3"
},
"ava": {
"nodeArguments": [
"--no-warnings"
],
"typescript": {
"compile": false,
"rewritePaths": {
"test/": "dist/test/"
}
}
"typescript": "^5.9.3",
"vitest": "^4.0.15"
}
}
3,793 changes: 1,753 additions & 2,040 deletions clients/js/pnpm-lock.yaml

Large diffs are not rendered by default.

22 changes: 11 additions & 11 deletions clients/js/test/batch.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
some,
} from '@solana/kit';
import { createLocalClient } from '@solana/kit-client-rpc';
import test from 'ava';
import { expect, it } from 'vitest';
import {
AccountState,
getBatchInstruction,
Expand All @@ -28,7 +28,7 @@ import {
tokenProgram,
} from '../src';

test('it batches multiple token instructions together', async t => {
it('batches multiple token instructions together', async () => {
// Given a local validator client with some generated keypairs.
const client = await createLocalClient().use(systemProgram()).use(tokenProgram());
const [mint, token, mintAuthority, tokenOwner] = await Promise.all([
Expand Down Expand Up @@ -76,7 +76,7 @@ test('it batches multiple token instructions together', async t => {

// Then we expect the mint account to have the correct data.
const mintAccount = await client.token.accounts.mint.fetch(mint.address);
t.like(mintAccount.data, {
expect(mintAccount.data).toMatchObject({
mintAuthority: some(mintAuthority.address),
supply: 123_45n,
decimals: 2,
Expand All @@ -86,15 +86,15 @@ test('it batches multiple token instructions together', async t => {

// And we expect the token account to have the correct data.
const tokenAccount = await client.token.accounts.token.fetch(token.address);
t.like(tokenAccount.data, {
expect(tokenAccount.data).toMatchObject({
mint: mint.address,
owner: tokenOwner.address,
amount: 123_45n,
state: AccountState.Initialized,
});
});

test('it fails to batch nested batch instructions', async t => {
it('fails to batch nested batch instructions', async () => {
// Given a local validator client with some generated keypairs.
const client = await createLocalClient().use(systemProgram()).use(tokenProgram());
const [mint, token, mintAuthority, tokenOwner] = await Promise.all([
Expand Down Expand Up @@ -129,10 +129,10 @@ test('it fails to batch nested batch instructions', async t => {
]);

// Then we expect an error to be thrown.
t.throws(createNestedBatch, { message: 'Batch instructions cannot be nested within other batch instructions.' });
expect(createNestedBatch).toThrow('Batch instructions cannot be nested within other batch instructions.');
});

test('it parses batch instructions including its inner instructions', async t => {
it('parses batch instructions including its inner instructions', async () => {
// Given a batch instruction with multiple token inner instructions.
const [mint, token, mintAuthority, tokenOwner] = await Promise.all([
generateKeyPairSigner(),
Expand Down Expand Up @@ -163,7 +163,7 @@ test('it parses batch instructions including its inner instructions', async t =>
const parsedInstruction = parseBatchInstruction(batchInstruction);

// Then we expect the parsed instruction to have the following inner instructions.
t.deepEqual(parsedInstruction.instructions, [
expect(parsedInstruction.instructions).toEqual([
{
instructionType: TokenInstruction.InitializeMint2,
programAddress: TOKEN_PROGRAM_ADDRESS,
Expand Down Expand Up @@ -209,7 +209,7 @@ test('it parses batch instructions including its inner instructions', async t =>
]);
});

test('it parses batch instructions from a fetched transaction', async t => {
it('parses batch instructions from a fetched transaction', async () => {
// Given a client with some generated keypairs.
const client = await createLocalClient().use(systemProgram()).use(tokenProgram());
const [mint, token, mintAuthority, tokenOwner] = await Promise.all([
Expand Down Expand Up @@ -259,7 +259,7 @@ test('it parses batch instructions from a fetched transaction', async t => {
const transactionResult = await client.rpc
.getTransaction(result.context.signature, { encoding: 'base64', maxSupportedTransactionVersion: 0 })
.send();
t.assert(transactionResult);
expect(transactionResult).toBeTruthy();
const transactionBytes = getBase64Encoder().encode(transactionResult!.transaction[0]);
const transaction = getTransactionDecoder().decode(transactionBytes);
const compiledMessage = getCompiledTransactionMessageDecoder().decode(transaction.messageBytes);
Expand All @@ -272,7 +272,7 @@ test('it parses batch instructions from a fetched transaction', async t => {
const parsedInstruction = parseBatchInstruction(batchInstruction);

// Then we expect the parsed instruction to have the following inner instructions.
t.deepEqual(parsedInstruction.instructions, [
expect(parsedInstruction.instructions).toEqual([
{
instructionType: TokenInstruction.InitializeMint2,
programAddress: TOKEN_PROGRAM_ADDRESS,
Expand Down
34 changes: 17 additions & 17 deletions clients/js/test/burnChecked.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { appendTransactionMessageInstruction, generateKeyPairSigner, pipe } from '@solana/kit';
import test from 'ava';
import { expect, it } from 'vitest';
import { fetchMint, fetchToken, getApproveInstruction, getBurnCheckedInstruction } from '../src';
import {
createDefaultSolanaClient,
Expand All @@ -10,7 +10,7 @@ import {
signAndSendTransaction,
} from './_setup';

test('it burns tokens with correct decimals', async t => {
it('burns tokens with correct decimals', async () => {
// Given a mint with 9 decimals and a token account with 200 tokens.
const client = createDefaultSolanaClient();
const [payer, mintAuthority, owner] = await Promise.all([
Expand All @@ -36,14 +36,14 @@ test('it burns tokens with correct decimals', async t => {
);

const { data: mintData } = await fetchMint(client.rpc, mint);
t.is(mintData.supply, 175n);
expect(mintData.supply).toBe(175n);

// Then we expect the token account to have 175 tokens remaining.
const { data: tokenData } = await fetchToken(client.rpc, token);
t.is(tokenData.amount, 175n);
expect(tokenData.amount).toBe(175n);
});

test('it burns tokens using a delegate', async t => {
it('burns tokens using a delegate', async () => {
// Given a token account with 100 tokens and a delegate approved for 60 tokens.
const client = createDefaultSolanaClient();
const [payer, mintAuthority, owner, delegate] = await Promise.all([
Expand Down Expand Up @@ -84,11 +84,11 @@ test('it burns tokens using a delegate', async t => {

// Then the token account should have 70 tokens remaining.
const { data: tokenData } = await fetchToken(client.rpc, token);
t.is(tokenData.amount, 70n);
t.is(tokenData.delegatedAmount, 30n); // Remaining delegated amount
expect(tokenData.amount).toBe(70n);
expect(tokenData.delegatedAmount).toBe(30n); // Remaining delegated amount
});

test('it fails when decimals mismatch', async t => {
it('fails when decimals mismatch', async () => {
// Given a mint with 9 decimals and a token account with tokens.
const client = createDefaultSolanaClient();
const [payer, mintAuthority, owner] = await Promise.all([
Expand All @@ -112,10 +112,10 @@ test('it fails when decimals mismatch', async t => {
);

// Then it should fail with MintDecimalsMismatch error.
await t.throwsAsync(signAndSendTransaction(client, transactionMessage));
await expect(signAndSendTransaction(client, transactionMessage)).rejects.toThrow();
});

test('it fails when burning more than account balance', async t => {
it('fails when burning more than account balance', async () => {
// Given a token account with only 50 tokens.
const client = createDefaultSolanaClient();
const [payer, mintAuthority, owner] = await Promise.all([
Expand All @@ -139,10 +139,10 @@ test('it fails when burning more than account balance', async t => {
);

// Then it should fail with InsufficientFunds error.
await t.throwsAsync(signAndSendTransaction(client, transactionMessage));
await expect(signAndSendTransaction(client, transactionMessage)).rejects.toThrow();
});

test('it fails when authority is not a signer', async t => {
it('fails when authority is not a signer', async () => {
// Given a token account with tokens.
const client = createDefaultSolanaClient();
const [payer, mintAuthority, owner, wrongAuthority] = await Promise.all([
Expand All @@ -167,10 +167,10 @@ test('it fails when authority is not a signer', async t => {
);

// Then it should fail (owner mismatch or missing signature).
await t.throwsAsync(signAndSendTransaction(client, transactionMessage));
await expect(signAndSendTransaction(client, transactionMessage)).rejects.toThrow();
});

test('it fails when delegate has insufficient delegated amount', async t => {
it('fails when delegate has insufficient delegated amount', async () => {
// Given a token account with 100 tokens and a delegate approved for only 20 tokens.
const client = createDefaultSolanaClient();
const [payer, mintAuthority, owner, delegate] = await Promise.all([
Expand Down Expand Up @@ -208,10 +208,10 @@ test('it fails when delegate has insufficient delegated amount', async t => {
);

// Then it should fail with InsufficientFunds error.
await t.throwsAsync(signAndSendTransaction(client, transactionMessage));
await expect(signAndSendTransaction(client, transactionMessage)).rejects.toThrow();
});

test('it burns zero tokens successfully', async t => {
it('burns zero tokens successfully', async () => {
// Given a token account with tokens.
const client = createDefaultSolanaClient();
const [payer, mintAuthority, owner] = await Promise.all([
Expand All @@ -238,5 +238,5 @@ test('it burns zero tokens successfully', async t => {

// Then the balance should remain unchanged.
const { data: tokenData } = await fetchToken(client.rpc, token);
t.is(tokenData.amount, 100n);
expect(tokenData.amount).toBe(100n);
});
6 changes: 3 additions & 3 deletions clients/js/test/createAssociatedToken.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Account, appendTransactionMessageInstruction, generateKeyPairSigner, none, pipe } from '@solana/kit';
import test from 'ava';
import { expect, it } from 'vitest';
import {
AccountState,
TOKEN_PROGRAM_ADDRESS,
Expand All @@ -16,7 +16,7 @@ import {
signAndSendTransaction,
} from './_setup';

test('it creates a new associated token account', async t => {
it('creates a new associated token account', async () => {
// Given a mint account, its mint authority and a token owner.
const client = createDefaultSolanaClient();
const [payer, mintAuthority, owner] = await Promise.all([
Expand Down Expand Up @@ -45,7 +45,7 @@ test('it creates a new associated token account', async t => {
owner: owner.address,
tokenProgram: TOKEN_PROGRAM_ADDRESS,
});
t.like(await fetchToken(client.rpc, ata), <Account<Token>>{
expect(await fetchToken(client.rpc, ata)).toMatchObject(<Account<Token>>{
address: ata,
data: {
mint,
Expand Down
6 changes: 3 additions & 3 deletions clients/js/test/createAssociatedTokenIdempotent.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Account, appendTransactionMessageInstruction, generateKeyPairSigner, none, pipe } from '@solana/kit';
import test from 'ava';
import { expect, it } from 'vitest';
import {
AccountState,
TOKEN_PROGRAM_ADDRESS,
Expand All @@ -16,7 +16,7 @@ import {
signAndSendTransaction,
} from './_setup';

test('it creates a new associated token account', async t => {
it('creates a new associated token account', async () => {
// Given a mint account, its mint authority and a token owner.
const client = createDefaultSolanaClient();
const [payer, mintAuthority, owner] = await Promise.all([
Expand Down Expand Up @@ -45,7 +45,7 @@ test('it creates a new associated token account', async t => {
owner: owner.address,
tokenProgram: TOKEN_PROGRAM_ADDRESS,
});
t.like(await fetchToken(client.rpc, ata), <Account<Token>>{
expect(await fetchToken(client.rpc, ata)).toMatchObject(<Account<Token>>{
address: ata,
data: {
mint,
Expand Down
14 changes: 7 additions & 7 deletions clients/js/test/createMint.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Account, generateKeyPairSigner, none, some } from '@solana/kit';
import { createLocalClient } from '@solana/kit-client-rpc';
import test from 'ava';
import { expect, it } from 'vitest';
import { fetchMint, getCreateMintInstructionPlan, Mint, tokenProgram } from '../src';
import { createDefaultSolanaClient, createDefaultTransactionPlanner, generateKeyPairSignerWithSol } from './_setup';

test('it creates and initializes a new mint account', async t => {
it('creates and initializes a new mint account', async () => {
// Given an authority and a mint account.
const client = createDefaultSolanaClient();
const authority = await generateKeyPairSignerWithSol(client);
Expand All @@ -24,7 +24,7 @@ test('it creates and initializes a new mint account', async t => {

// Then we expect the mint account to exist and have the following data.
const mintAccount = await fetchMint(client.rpc, mint.address);
t.like(mintAccount, <Account<Mint>>{
expect(mintAccount).toMatchObject(<Account<Mint>>{
address: mint.address,
data: {
mintAuthority: some(authority.address),
Expand All @@ -36,7 +36,7 @@ test('it creates and initializes a new mint account', async t => {
});
});

test('it creates a new mint account with a freeze authority', async t => {
it('creates a new mint account with a freeze authority', async () => {
// Given an authority and a mint account.
const client = createDefaultSolanaClient();
const [payer, mintAuthority, freezeAuthority, mint] = await Promise.all([
Expand All @@ -61,7 +61,7 @@ test('it creates a new mint account with a freeze authority', async t => {

// Then we expect the mint account to exist and have the following data.
const mintAccount = await fetchMint(client.rpc, mint.address);
t.like(mintAccount, <Account<Mint>>{
expect(mintAccount).toMatchObject(<Account<Mint>>{
address: mint.address,
data: {
mintAuthority: some(mintAuthority.address),
Expand All @@ -70,7 +70,7 @@ test('it creates a new mint account with a freeze authority', async t => {
});
});

test('it creates and initializes a new mint account using the token program plugin', async t => {
it('creates and initializes a new mint account using the token program plugin', async () => {
// Given a client with the token program plugin, and a mint account.
const client = await createLocalClient().use(tokenProgram());
const mint = await generateKeyPairSigner();
Expand All @@ -82,7 +82,7 @@ test('it creates and initializes a new mint account using the token program plug

// Then we expect the mint account to exist and have the following data.
const mintAccount = await client.token.accounts.mint.fetch(mint.address);
t.like(mintAccount, {
expect(mintAccount).toMatchObject({
address: mint.address,
data: {
mintAuthority: some(client.payer.address),
Expand Down
6 changes: 3 additions & 3 deletions clients/js/test/initializeAccount.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { getCreateAccountInstruction } from '@solana-program/system';
import { Account, appendTransactionMessageInstructions, generateKeyPairSigner, none, pipe } from '@solana/kit';
import test from 'ava';
import { expect, it } from 'vitest';
import {
AccountState,
TOKEN_PROGRAM_ADDRESS,
Expand All @@ -17,7 +17,7 @@ import {
signAndSendTransaction,
} from './_setup';

test('it creates and initializes a new token account', async t => {
it('creates and initializes a new token account', async () => {
// Given a mint account, its mint authority and two generated keypairs
// for the token to be created and its owner.
const client = createDefaultSolanaClient();
Expand Down Expand Up @@ -54,7 +54,7 @@ test('it creates and initializes a new token account', async t => {

// 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>>{
expect(tokenAccount).toMatchObject(<Account<Token>>{
address: token.address,
data: {
mint,
Expand Down
Loading
Loading