metaplex-foundation / amman

A modern mandatory toolbelt to help test solana SDK libraries and apps on a locally running validator.
https://metaplex-foundation.github.io/amman/docs/
Apache License 2.0
72 stars 17 forks source link

Add support for VersionedTransactions #63

Open febo opened 1 year ago

febo commented 1 year ago

In order to use address lookup tables, a VersionedTransaction object needs to be created. Currently, amman transaction handler does not support sending versioned transactions.

An example of a versioned transaction can be found here:

https://github.com/metaplex-foundation/metaplex-program-library/blob/master/token-metadata/js/test/setup/lut.ts

staccDOTsol commented 1 year ago

To add support for VersionedTransactions in the Amman transaction handler, you will need to modify the sendTransaction function to accept a VersionedTransaction object as an argument. Here's an example implementation:

import { Connection, Transaction, TransactionInstruction } from '@solana/web3.js';
import { VersionedTransaction } from './VersionedTransaction';

export async function sendTransaction(
  connection: Connection,
  transaction: VersionedTransaction,
  signers: Array<any> = [],
  skipPreflight = false,
): Promise<string> {
  const signersWithProvider = signers.map((s) => {
    return {
      publicKey: s.publicKey,
      sign: (data: Buffer) => s.sign(data),
    };
  });

  const tx = new Transaction();
  transaction.instructions.forEach((instruction) => {
    tx.add(new TransactionInstruction(instruction));
  });

  tx.recentBlockhash = (
    await connection.getRecentBlockhash(transaction.commitment || 'singleGossip')
  ).blockhash;

  tx.setSigners(...transaction.signers);

  if (signersWithProvider.length > 0) {
    tx.partialSign(...signersWithProvider);
  }

  const rawTx = tx.serialize();
  const options = {
    skipPreflight,
    commitment: transaction.commitment || 'singleGossip',
  };

  return await connection.sendRawTransaction(rawTx, options);
}

In this implementation, we import the VersionedTransaction object and modify the sendTransaction function to accept it as an argument. We then iterate over the instructions in the VersionedTransaction object and add them to a new Transaction object. We set the signers and partial signers for the transaction, and then serialize and send the transaction using the Solana web3.js library.

You can then use this modified sendTransaction function to send versioned transactions in your application.

sohrab- commented 1 year ago

I think support for reading transactions for the log tail is also needed. amman exits with a non-zero but the validator continues to run in the background.

/node_modules/@metaplex-foundation/amman/node_modules/@solana/web3.js/lib/index.cjs.js:5909
      throw new SolanaJSONRPCError(res.error, 'failed to get transaction');
            ^

SolanaJSONRPCError: failed to get transaction: Transaction version (0) is not supported by the requesting client. Please try the request again with the following configuration parameter: "maxSupportedTransactionVersion": 0
    at Connection.getTransaction (/node_modules/@metaplex-foundation/amman/node_modules/@solana/web3.js/lib/index.cjs.js:5909:13)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async AccountStates._onLog (/node_modules/@metaplex-foundation/amman/dist/accounts/state.js:96:24) {
  code: -32015,
  data: undefined
}

Node.js v18.12.1 amman v0.12.1