UNPKG

@metaplex-foundation/umi-transaction-factory-web3js

Version:

A transaction factory implementation relying on Solana's web3.js

101 lines (98 loc) 4.19 kB
import { SdkError } from '@metaplex-foundation/umi'; import { mapSerializer, struct, array, bytes, shortU16, publicKey, string, base58, u8 } from '@metaplex-foundation/umi/serializers'; import { toWeb3JsMessageFromInput, fromWeb3JsMessage } from '@metaplex-foundation/umi-web3js-adapters'; import { VersionedTransaction } from '@solana/web3.js'; /* eslint-disable no-bitwise */ const TRANSACTION_VERSION_FLAG = 0x80; const TRANSACTION_VERSION_MASK = 0x7f; function createWeb3JsTransactionFactory() { const create = input => { const web3JsMessage = toWeb3JsMessageFromInput(input); const message = fromWeb3JsMessage(web3JsMessage); const web3JsTransaction = new VersionedTransaction(web3JsMessage, input.signatures); return { message, serializedMessage: serializeMessage(message), signatures: web3JsTransaction.signatures }; }; const serialize = transaction => getTransactionSerializer().serialize(transaction); const deserialize = serializedTransaction => getTransactionSerializer().deserialize(serializedTransaction)[0]; const serializeMessage = message => getTransactionMessageSerializer().serialize(message); const deserializeMessage = serializedMessage => getTransactionMessageSerializer().deserialize(serializedMessage)[0]; const getTransactionSerializer = () => ({ ...mapSerializer(struct([['signatures', array(bytes({ size: 64 }), { size: shortU16() })], ['serializedMessage', bytes()]]), value => value, value => ({ ...value, message: deserializeMessage(value.serializedMessage) })), description: 'Transaction' }); const getTransactionMessageSerializer = () => ({ description: 'TransactionMessage', fixedSize: null, maxSize: null, serialize: value => { const serializer = getTransactionMessageSerializerForVersion(value.version); return serializer.serialize(value); }, deserialize: (bytes, offset = 0) => { const [version] = getTransactionVersionSerializer().deserialize(bytes, offset); const serializer = getTransactionMessageSerializerForVersion(version); return serializer.deserialize(bytes, offset); } }); const getTransactionMessageSerializerForVersion = version => struct([['version', getTransactionVersionSerializer()], ['header', getTransactionMessageHeaderSerializer()], ['accounts', array(publicKey(), { size: shortU16() })], ['blockhash', string({ encoding: base58, size: 32 })], ['instructions', array(getCompiledInstructionSerializer(), { size: shortU16() })], ['addressLookupTables', array(getCompiledAddressLookupTableSerializer(), { size: version === 'legacy' ? 0 : shortU16() })]]); const getTransactionVersionSerializer = () => ({ description: 'TransactionVersion', fixedSize: null, maxSize: 1, serialize: value => { if (value === 'legacy') return new Uint8Array([]); return new Uint8Array([TRANSACTION_VERSION_FLAG | value]); }, deserialize: (bytes, offset = 0) => { const slice = bytes.slice(offset); if (slice.length === 0 || (slice[0] & TRANSACTION_VERSION_FLAG) === 0) { return ['legacy', offset]; } const version = slice[0] & TRANSACTION_VERSION_MASK; if (version > 0) { throw new SdkError(`Unsupported transaction version: ${version}.`); } return [version, offset + 1]; } }); const getTransactionMessageHeaderSerializer = () => struct([['numRequiredSignatures', u8()], ['numReadonlySignedAccounts', u8()], ['numReadonlyUnsignedAccounts', u8()]]); const getCompiledInstructionSerializer = () => struct([['programIndex', u8()], ['accountIndexes', array(u8(), { size: shortU16() })], ['data', bytes({ size: shortU16() })]]); const getCompiledAddressLookupTableSerializer = () => struct([['publicKey', publicKey()], ['writableIndexes', array(u8(), { size: shortU16() })], ['readonlyIndexes', array(u8(), { size: shortU16() })]]); return { create, serialize, deserialize, serializeMessage, deserializeMessage }; } export { createWeb3JsTransactionFactory }; //# sourceMappingURL=createWeb3JsTransactionFactory.mjs.map