Browse Source

Update Kinobi to 0.19 and Web3.js to tp3

Loris Leiva 1 year ago
parent
commit
22862c8ba6

+ 5 - 0
.changeset/wet-zoos-melt.md

@@ -0,0 +1,5 @@
+---
+"create-solana-program": minor
+---
+
+Update Kinobi to 0.19 and Web3.js to tp3

+ 2 - 2
.github/workflows/main.yml

@@ -7,7 +7,7 @@ on:
     branches: [main]
 
 env:
-  SOLANA_VERSION: 1.18.4
+  SOLANA_VERSION: 1.18.12
 
 jobs:
   lint:
@@ -33,7 +33,7 @@ jobs:
     runs-on: ubuntu-latest
     strategy:
       matrix:
-        solana: ["1.17.24", "1.18.4"]
+        solana: ["1.17.24", "1.18.12"]
     steps:
       - name: Git checkout
         uses: actions/checkout@v4

+ 1 - 1
template/clients/base/package.json

@@ -7,6 +7,6 @@
     "validator:stop": "zx ./scripts/stop-validator.mjs"
   },
   "devDependencies": {
-    "@metaplex-foundation/kinobi": "^0.18.0"
+    "@metaplex-foundation/kinobi": "^0.19.0"
   }
 }

+ 3 - 2
template/clients/base/scripts/generate-clients.mjs.njk

@@ -4,7 +4,8 @@ import * as k from "@metaplex-foundation/kinobi";
 import { getAllProgramIdls } from "./utils.mjs";
 
 // Instanciate Kinobi.
-const kinobi = k.createFromIdls(getAllProgramIdls());
+const [idl, ...additionalIdls] = getAllProgramIdls();
+const kinobi = k.createFromIdl(idl, additionalIdls);
 
 // Update programs.
 kinobi.update(
@@ -18,7 +19,7 @@ kinobi.update(
   k.updateAccountsVisitor({
     counter: {
       seeds: [
-        k.constantPdaSeedNodeFromString("counter"),
+        k.constantPdaSeedNodeFromString("utf8", "counter"),
         k.variablePdaSeedNode(
           "authority",
           k.publicKeyTypeNode(),

+ 4 - 9
template/clients/js/clients/js/package.json.njk

@@ -32,19 +32,14 @@
     "registry": "https://registry.npmjs.org"
   },
   "license": "MIT",
-  "dependencies": {
-    "@solana/accounts": "^2.0.0-preview",
-    "@solana/addresses": "^2.0.0-preview",
-    "@solana/codecs": "^2.0.0-preview",
-    "@solana/instructions": "^2.0.0-preview",
-    "@solana/programs": "^2.0.0-preview",
-    "@solana/signers": "^2.0.0-preview"
+  "peerDependencies": {
+    "@solana/web3.js": "tp3"
   },
   "devDependencies": {
     "@ava/typescript": "^4.1.0",
     "@solana/eslint-config-solana": "^3.0.0",
-    "@solana/web3.js": "^2.0.0-preview",
-    "@solana/webcrypto-ed25519-polyfill": "^2.0.0-preview",
+    "@solana/web3.js": "tp3",
+    "@solana/webcrypto-ed25519-polyfill": "tp3",
     "@typescript-eslint/eslint-plugin": "^7.3.1",
     "@typescript-eslint/parser": "^7.3.1",
     "ava": "^6.1.2",

+ 15 - 13
template/clients/js/clients/js/test/_setup.ts

@@ -1,8 +1,8 @@
 import {
   Address,
   Commitment,
-  CompilableTransaction,
-  ITransactionWithBlockhashLifetime,
+  CompilableTransactionMessage,
+  TransactionMessageWithBlockhashLifetime,
   ProgramDerivedAddress,
   Rpc,
   RpcSubscriptions,
@@ -10,18 +10,18 @@ import {
   SolanaRpcSubscriptionsApi,
   TransactionSigner,
   airdropFactory,
-  appendTransactionInstruction,
+  appendTransactionMessageInstruction,
   createSolanaRpc,
   createSolanaRpcSubscriptions,
-  createTransaction,
+  createTransactionMessage,
   generateKeyPairSigner,
   getSignatureFromTransaction,
   lamports,
   pipe,
   sendAndConfirmTransactionFactory,
-  setTransactionFeePayerSigner,
-  setTransactionLifetimeUsingBlockhash,
-  signTransactionWithSigners,
+  setTransactionMessageFeePayerSigner,
+  setTransactionMessageLifetimeUsingBlockhash,
+  signTransactionMessageWithSigners,
 } from '@solana/web3.js';
 import { findCounterPda, getCreateInstructionAsync } from '../src/index.js';
 
@@ -57,18 +57,20 @@ export const createDefaultTransaction = async (
     .getLatestBlockhash()
     .send();
   return pipe(
-    createTransaction({ version: 0 }),
-    (tx) => setTransactionFeePayerSigner(feePayer, tx),
-    (tx) => setTransactionLifetimeUsingBlockhash(latestBlockhash, tx)
+    createTransactionMessage({ version: 0 }),
+    (tx) => setTransactionMessageFeePayerSigner(feePayer, tx),
+    (tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx)
   );
 };
 
 export const signAndSendTransaction = async (
   client: Client,
-  transaction: CompilableTransaction & ITransactionWithBlockhashLifetime,
+  transactionMessage: CompilableTransactionMessage &
+    TransactionMessageWithBlockhashLifetime,
   commitment: Commitment = 'confirmed'
 ) => {
-  const signedTransaction = await signTransactionWithSigners(transaction);
+  const signedTransaction =
+    await signTransactionMessageWithSigners(transactionMessage);
   const signature = getSignatureFromTransaction(signedTransaction);
   await sendAndConfirmTransactionFactory(client)(signedTransaction, {
     commitment,
@@ -91,7 +93,7 @@ export const createCounterForAuthority = async (
   ]);
   await pipe(
     transaction,
-    (tx) => appendTransactionInstruction(createIx, tx),
+    (tx) => appendTransactionMessageInstruction(createIx, tx),
     (tx) => signAndSendTransaction(client, tx)
   );
   return counterPda;

+ 7 - 3
template/clients/js/clients/js/test/create.test.ts

@@ -1,4 +1,8 @@
-import { appendTransactionInstruction, pipe } from '@solana/web3.js';
+import {
+  Account,
+  appendTransactionMessageInstruction,
+  pipe,
+} from '@solana/web3.js';
 import test from 'ava';
 import {
   Counter,
@@ -21,7 +25,7 @@ test('it creates a new counter account', async (t) => {
   const createIx = await getCreateInstructionAsync({ authority });
   await pipe(
     await createDefaultTransaction(client, authority),
-    (tx) => appendTransactionInstruction(createIx, tx),
+    (tx) => appendTransactionMessageInstruction(createIx, tx),
     (tx) => signAndSendTransaction(client, tx)
   );
 
@@ -29,7 +33,7 @@ test('it creates a new counter account', async (t) => {
   const counter = await fetchCounterFromSeeds(client.rpc, {
     authority: authority.address,
   });
-  t.like(counter, <Counter>{
+  t.like(counter, <Account<Counter>>{
     data: {
       authority: authority.address,
       value: 0,

+ 45 - 21
template/clients/js/clients/js/test/increment.test.ts.njk

@@ -1,6 +1,16 @@
-import { appendTransactionInstruction, lamports, pipe } from '@solana/web3.js';
+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 {
+  {{ programName | snakeCase | upper }}_ERROR__INVALID_PDA,
+  {{ programName | snakeCase | upper }}_ERROR__INVALID_PROGRAM_OWNER,
+  {{ programName | snakeCase | upper }}_PROGRAM_ADDRESS,
   fetchCounter,
   findCounterPda,
   getIncrementInstruction,
@@ -26,7 +36,7 @@ test('it increments an existing counter by 1 by default', async (t) => {
   const incrementIx = await getIncrementInstructionAsync({ authority });
   await pipe(
     await createDefaultTransaction(client, authority),
-    (tx) => appendTransactionInstruction(incrementIx, tx),
+    (tx) => appendTransactionMessageInstruction(incrementIx, tx),
     (tx) => signAndSendTransaction(client, tx)
   );
 
@@ -49,7 +59,7 @@ test('it can increment an existing counter by a specified amount', async (t) =>
   });
   await pipe(
     await createDefaultTransaction(client, authority),
-    (tx) => appendTransactionInstruction(incrementIx, tx),
+    (tx) => appendTransactionMessageInstruction(incrementIx, tx),
     (tx) => signAndSendTransaction(client, tx)
   );
 
@@ -67,20 +77,27 @@ test('it cannot increment a counter that does not exist', async (t) => {
 
   // When we try to increment the inexistent counter account.
   const incrementIx = await getIncrementInstructionAsync({ authority });
-  const promise = pipe(
+  const transactionMessage = pipe(
     await createDefaultTransaction(client, authority),
-    (tx) => appendTransactionInstruction(incrementIx, tx),
-    (tx) => signAndSendTransaction(client, tx)
+    (tx) => appendTransactionMessageInstruction(incrementIx, tx)
   );
+  const promise = signAndSendTransaction(client, transactionMessage);
 
   // Then we expect the program to throw an error.
-  const error = await t.throwsAsync<Error & { data: { logs: string[] } }>(
-    promise,
-    { message: /Error processing Instruction 0: custom program error: 0x2/ }
+  const error = await t.throwsAsync(promise);
+  t.true(
+    isSolanaError(
+      error,
+      SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE
+    )
   );
-  t.regex(
-    error.data.logs.join('\n'),
-    /Account "counter" \[.+\] expected program owner \[{{ programAddress }}\], got \[11111111111111111111111111111111\]/
+  t.true(
+    isProgramError(
+      error.cause,
+      transactionMessage,
+      {{ programName | snakeCase | upper }}_PROGRAM_ADDRESS,
+      {{ programName | snakeCase | upper }}_ERROR__INVALID_PROGRAM_OWNER
+    )
   );
 });
 
@@ -99,19 +116,26 @@ test('it cannot increment a counter that belongs to another authority', async (t
     authority: authorityB,
     counter: counterPda,
   });
-  const promise = pipe(
+  const transactionMessage = pipe(
     await createDefaultTransaction(client, authorityB),
-    (tx) => appendTransactionInstruction(incrementIx, tx),
-    (tx) => signAndSendTransaction(client, tx)
+    (tx) => appendTransactionMessageInstruction(incrementIx, tx)
   );
+  const promise = signAndSendTransaction(client, transactionMessage);
 
   // Then we expect the program to throw an error.
-  const error = await t.throwsAsync<Error & { data: { logs: string[] } }>(
-    promise,
-    { message: /Error processing Instruction 0: custom program error: 0x3/ }
+  const error = await t.throwsAsync(promise);
+  t.true(
+    isSolanaError(
+      error,
+      SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE
+    )
   );
-  t.regex(
-    error.data.logs.join('\n'),
-    /Account "counter" \[.+\] is an invalid PDA. Expected the following valid PDA \[.+\]/
+  t.true(
+    isProgramError(
+      error.cause,
+      transactionMessage,
+      {{ programName | snakeCase | upper }}_PROGRAM_ADDRESS,
+      {{ programName | snakeCase | upper }}_ERROR__INVALID_PDA
+    )
   );
 });