Skip to content

Transaction Envelopes

Overview

A Transaction Envelope is a structure that defines the properties of a transaction, and is generally utilized to construct Transactions to be broadcast to a network.

Ox supports the core Ethereum Transaction Envelope types:

ModuleNameType
TransactionEnvelopeLegacyLegacy Transactions0x00
TransactionEnvelopeEip2930EIP-2930: Access List Transactions0x01
TransactionEnvelopeEip1559EIP-1559: Fee Market Transactions0x02
TransactionEnvelopeEip4844EIP-4844: Blob Transactions0x03
TransactionEnvelopeEip7702EIP-7702: Authorization Transactions0x04

Examples

Constructing

A Transaction Envelope can be constructed using the respective .from function.

The example below demonstrates how to construct an EIP-1559 Transaction Envelope using TransactionEnvelopeEip1559.from. EIP-1559 Transactions are the most commonly used Transaction Envelope type.

import { TransactionEnvelopeEip1559, Value } from 'ox'
 
const envelope = TransactionEnvelopeEip1559.from({
  chainId: 1,
  maxFeePerGas: Value.fromGwei('10'),
  maxPriorityFeePerGas: Value.fromGwei('1'),
  nonce: 69n,
  to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
  value: Value.fromEther('1.5'),
})

Signing

We can sign over a Transaction Envelope by passing the result of the Envelope's .getSignPayload function to the respective Signer's .sign function.

The example below demonstrates how to sign an EIP-1559 Transaction Envelope.

import { TransactionEnvelopeEip1559, Secp256k1, Value } from 'ox'
 
// Construct the Envelope.
const envelope = TransactionEnvelopeEip1559.from({
  chainId: 1,
  maxFeePerGas: Value.fromGwei('10'),
  maxPriorityFeePerGas: Value.fromGwei('1'),
  nonce: 69n,
  to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
  value: Value.fromEther('1.5'),
})
 
// Sign over the Envelope.
const signature = Secp256k1.sign({ 
  payload: TransactionEnvelopeEip1559.getSignPayload(envelope), 
  privateKey: '0x...', 
})
 
// Attach the Signature to the Envelope.
const 
const signed: { readonly chainId: 1; readonly maxFeePerGas: bigint; readonly maxPriorityFeePerGas: bigint; readonly nonce: 69n; readonly to: "0x70997970c51812dc3a010c7d01b50e0d17dc79c8"; readonly value: bigint; readonly type: "eip1559"; readonly r: bigint; readonly s: bigint; readonly yParity: number; }
signed
= TransactionEnvelopeEip1559.from(envelope, { signature })
↑ contains `r`, `s`, `yParity` signature properties.

Serializing

We can serialize a Transaction Envelope into RLP-encoded format by calling .serialize. We can also deserialize an RLP-encoded Transaction Envelope by calling .deserialize.

import { TransactionEnvelopeEip1559, Secp256k1, Value } from 'ox'
 
// Construct the Envelope.
const envelope = TransactionEnvelopeEip1559.from({
  chainId: 1,
  maxFeePerGas: Value.fromGwei('10'),
  maxPriorityFeePerGas: Value.fromGwei('1'),
  nonce: 69n,
  to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
  value: Value.fromEther('1.5'),
})
 
// Serialize the Envelope.
const 
const serialized: `0x02${string}`
serialized
= TransactionEnvelopeEip1559.serialize(envelope)
// Deserialize the Envelope. const
const deserialized: Compute<{ chainId: number; data?: Hex | undefined; input?: Hex | undefined; from?: Address | undefined; gas?: bigint | undefined; nonce?: bigint | undefined; ... 9 more ...; maxPriorityFeePerGas?: bigint | undefined; } | { ...; }>
deserialized
= TransactionEnvelopeEip1559.deserialize(serialized)

Sending

We can send a Transaction Envelope to the network by serializing the signed envelope with .serialize, and then broadcasting it over JSON-RPC with eth_sendRawTransaction.

In this example, we will use RpcTransport.fromHttp to broadcast a eth_sendRawTransaction request over HTTP JSON-RPC.

import { RpcTransport, TransactionEnvelopeEip1559, Secp256k1, Value } from 'ox'
 
// Construct the Envelope.
const envelope = TransactionEnvelopeEip1559.from({
  chainId: 1,
  maxFeePerGas: Value.fromGwei('10'),
  maxPriorityFeePerGas: Value.fromGwei('1'),
  nonce: 69n,
  to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
  value: Value.fromEther('1.5'),
})
 
// Sign over the Envelope.
const signature = Secp256k1.sign({
  payload: TransactionEnvelopeEip1559.getSignPayload(envelope),
  privateKey: '0x...',
})
 
// Serialize the Envelope with the Signature.
const serialized = TransactionEnvelopeEip1559.serialize(envelope, { 
  signature
})
 
// Broadcast the Envelope with `eth_sendRawTransaction`.
const transport = RpcTransport.fromHttp('https://1.rpc.thirdweb.com')
const hash = await transport.request({ 
  method: 'eth_sendRawTransaction', 
  params: [serialized], 
})

Wallets & Signing Servers

The examples above demonstrate how to manually construct & sign a Transaction Envelope, and assumes that you will fill the Transaction with required properties (nonce, fees, signature, etc) to successfully execute the Transaction.

If you are interacting with a Wallet, or more generally an entity that is responsible for filling & signing Transactions, this means you can skip the ceremony of manually filling the Transaction by using the eth_sendTransaction RPC method.

The example below demonstrates how to send a Transaction Envelope with eth_sendTransaction using an EIP-1193 Provider to interact with a Browser Extension Wallet. You could also use RpcTransport.fromHttp if your backend supports signing Transactions with eth_sendTransaction.

import 'ox/window'
import { Provider, TransactionEnvelopeEip1559, Value } from 'ox'
 
// Construct the Envelope.
const envelope = TransactionEnvelopeEip1559.from({
  chainId: 1,
  to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
  value: Value.fromEther('1.5'),
})
 
// Convert the Envelope to an RPC-compatible format. 
const envelope_rpc = TransactionEnvelopeEip1559.toRpc(envelope)
 
// Broadcast the Envelope with `eth_sendTransaction`. 
const provider = Provider.from(window.ethereum)
const hash = await provider.request({ 
  method: 'eth_sendTransaction', 
  params: [envelope_rpc], 
}) 

Related Modules

ModuleDescription
TransactionEnvelopeErrors & Types for working with Transaction Envelopes.
TransactionEnvelopeEip1559Utility functions for working with EIP-1559 Typed Transaction Envelopes.
TransactionEnvelopeEip2930Utility functions for working with EIP-2930 Typed Transaction Envelopes.
TransactionEnvelopeEip4844Utility functions for working with EIP-4844 Typed Transaction Envelopes.
TransactionEnvelopeEip7702Utility functions for working with EIP-7702 Typed Transaction Envelopes.
TransactionEnvelopeLegacyUtility functions for working with Legacy Transaction Envelopes.