@btq-js/tx
TypeScript icon, indicating that this package has built-in type declarations

0.0.38 • Public • Published

@btq-js/tx

This package is based on EthereumJS's Tx package. Most of the implementation and interfaces remains the same, except that:

  1. For signature scheme, we replaced ECDSA with Falcon for quantum safety.
  2. Transation structure remains the same. However, definitions for r, s and v are changed due to new signature scheme. Please see the definition in the table describing txData.
  3. In TxOptions we add a new option publicKey due to the design that Falcon public key can not be recovered from its signature. For more detail please take a look at TxOptions section.

We strongly suggest to read through the documentations from EthereumJS's Tx package beforehead.

Please note that:

This package depends on @btq-js/falcon-js by default. If we want to change the underlying falcon implementation from javascript to web assembly, please follw these simple steps


Installation

To obtain the latest version, simply require the project using npm:

npm install @btq-js/tx

You can also use yarn or pnpm based on your project's setup:

yarn add @btq-js/tx
pnpm add @btq-js/tx

Transaction Types

Currently the following transaction types are supported

Name Description
FeeMarketEIP1559Transaction EIP-1559, gas fee market
AccessListEIP2930Transaction EIP-2930, optional access lists
Legacy Transaction Legacy or type-0 transactions

Gas Fee Market Transactions (EIP-1559)

Name Value
Class FeeMarketEIP1559Transaction
Type 2
txData type FeeMarketEIP1559TxData
import { FeeMarketEIP1559Transaction } from '@btq-js/tx';

const txData = {
  type: 2,
  nonce: 0,
  maxPriorityFeePerGas: 100,
  maxFeePerGas: 1000,
  gasLimit: 1000000000,
  value: 0,
  to: '0x8dDDbD32233CfAA36aa659feebFCD4368DF8c18f',
};
const tx = FeeMarketEIP1559Transaction.fromTxData(txData);

Access List Transactions (EIP-2930)

Name Value
Class AccessListEIP2930Transaction
Type 1
txData type AccessListEIP2930TxData
import { AccessListEIP2930Transaction } from '@btq-js/tx';

const txData = {
  type: 1,
  nonce: 1,
  gasPrice: 100,
  gasLimit: 1000000000,
  value: 0,
  to: '0x8dDDbD32233CfAA36aa659feebFCD4368DF8c18f',
  chainId: '0x01',
  accessList: [
    {
      address: '0x0000000000000000000000000000000000000101',
      storageKeys: ['0x0000000000000000000000000000000000000000000000000000000000000000', '0x00000000000000000000000000000000000000000000000000000000000060a7'],
    },
  ],
};
const tx = AccessListEIP2930Transaction.fromTxData(txData);

Legacy Transactions

Name Value
Class Transaction
Type 0 (internal)
txData type txData
import { Transaction } from '@btq-js/tx';

const txParams = {
  nonce: 1,
  gasPrice: 100,
  gasLimit: 1000000000,
  value: 0,
  to: '0x8dDDbD32233CfAA36aa659feebFCD4368DF8c18f',
  data: '0x1a8451e600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
};

const tx = Transaction.fromTxData(txParams);

Transaction Factory

If you only know on runtime which tx type will be used within your code or if you want to keep your code transparent to tx types, this library comes with a TransactionFactory for your convenience which can be used as follows:

import { TransactionFactory } from '@btq-js/tx';

const txData = {}; // Use data from the different tx type examples
const tx = TransactionFactory.fromTxData(txData);
if (tx.supports(Capability.EIP2930AccessLists)) {
  // Do something which only makes sense for txs with support for access lists
}

The correct tx type class for instantiation will then be chosen on runtime based on the data provided as an input.

TransactionFactory supports the following static constructor methods except for fromEthersProvider() provided by @ethereumjs/tx:

  • public static fromTxData(txData: TxData | AccessListEIP2930TxData, txOptions: TxOptions = {}): TypedTransaction
  • public static fromSerializedData(data: Buffer, txOptions: TxOptions = {}): TypedTransaction
  • public static fromBlockBodyData(data: Buffer | Buffer[], txOptions: TxOptions = {})

Tx signing

import falcon from '@btq-js/falcon-js';

const seed = Buffer.from('<random_seed>', 'hex');

const key = await falcon.keyPair(seed);

const signedTx = await tx.sign(Buffer.from(key.publicKey), Buffer.from(key.privateKey));

Tx serialization

const serializedTx = signedTx.serialize().toString('hex');

const requestData = {
  jsonrpc: '2.0',
  method: 'eth_sendRawTransaction',
  params: [serializedTx],
  id: 1,
};

const postTx = {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(requestData),
};

await fetch(network, postData);

TxOptions

We add a new option publicKey which does not exist in EthereumJS's Tx package

Name Type
common? Common
freeze? boolean
publicKey? Buffer

Unlike ECDSA, Falcon public can not be recovered from its signature, if you want to verify a signed tx which has nonce larger than 0 (its r value is address instead of publicKey), you should provide publicKey.

Please see the following example:

import falcon from '@btq-js/falcon-js';
import { Transaction } from '@btq-js/tx';

const seed = Buffer.from('<random_seed>', 'hex');
const key = await falcon.keyPair(seed);
const publicKey = Buffer.from(key.publicKey);

const txData = {
  nonce: 1,
  gasPrice: 100,
  gasLimit: 1000000000,
  value: 0,
  to: '0x8dDDbD32233CfAA36aa659feebFCD4368DF8c18f',
  data: '0x1a8451e600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
  r: '<address>',
  s: '<signature_generated_by_falcon>',
  v: '<chainId_and_metadata>',
};

const signedTx = Transaction.fromTxData(txData, { publicKey });
// Verification will fail if publicKey is not provided.
const isVerified = await signedTx.verifySignature();

Readme

Keywords

none

Package Sidebar

Install

npm i @btq-js/tx

Weekly Downloads

37

Version

0.0.38

License

none

Unpacked Size

228 kB

Total Files

47

Last publish

Collaborators

  • _alex_dev
  • wei_btq