Web3 module encode and decode EVM in/output.
—
Complete support for EIP-712 structured data encoding and message preparation for typed data signing. Essential for implementing secure off-chain message signing with structured data.
Gets the EIP-191 encoded message to sign from typed data object. Implements the EIP-712 standard for structured data hashing and signing.
/**
* Gets EIP-191 encoded message from typed data for signing
* @param typedData - The EIP-712 typed data object
* @param hash - Whether to hash the message with Keccak256
* @returns The encoded message (hashed if hash=true)
*/
function getEncodedEip712Data(
typedData: Eip712TypedData,
hash?: boolean
): string;Usage Examples:
import { getEncodedEip712Data } from "web3-eth-abi";
// Define EIP-712 typed data
const typedData = {
types: {
EIP712Domain: [
{ name: "name", type: "string" },
{ name: "version", type: "string" },
{ name: "chainId", type: "uint256" },
{ name: "verifyingContract", type: "address" }
],
Person: [
{ name: "name", type: "string" },
{ name: "wallet", type: "address" }
],
Mail: [
{ name: "from", type: "Person" },
{ name: "to", type: "Person" },
{ name: "contents", type: "string" }
]
},
primaryType: "Mail",
domain: {
name: "Ether Mail",
version: "1",
chainId: 1,
verifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
},
message: {
from: {
name: "Cow",
wallet: "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"
},
to: {
name: "Bob",
wallet: "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"
},
contents: "Hello, Bob!"
}
};
// Get encoded message for signing (not hashed)
const encodedMessage = getEncodedEip712Data(typedData, false);
console.log(encodedMessage);
// 0x1901... (EIP-191 prefix + domain separator + message hash)
// Get hashed message for signing
const hashedMessage = getEncodedEip712Data(typedData, true);
console.log(hashedMessage);
// 0x... (Keccak256 hash of the encoded message)
// Use with eth_signTypedData_v4
// The hashed message can be used directly with wallet signing methodsThe domain separator ensures that signatures are specific to a particular application and chain:
interface EIP712Domain {
name?: string; // Human readable name of signing domain
version?: string; // Current major version of signing domain
chainId?: number; // EIP-155 chain id
verifyingContract?: string; // Address of contract that will verify signature
salt?: string; // Disambiguating salt for protocol
}interface Eip712TypedData {
types: Record<string, Array<{ name: string; type: string }>>;
primaryType: string;
domain: Record<string, unknown>;
message: Record<string, unknown>;
}Custom types are defined in the types object, with each type specifying its fields and their types:
const types = {
Person: [
{ name: "name", type: "string" },
{ name: "wallet", type: "address" }
],
Mail: [
{ name: "from", type: "Person" }, // References Person type
{ name: "to", type: "Person" },
{ name: "contents", type: "string" }
]
};const permitTypedData = {
types: {
EIP712Domain: [
{ name: "name", type: "string" },
{ name: "version", type: "string" },
{ name: "chainId", type: "uint256" },
{ name: "verifyingContract", type: "address" }
],
Permit: [
{ name: "owner", type: "address" },
{ name: "spender", type: "address" },
{ name: "value", type: "uint256" },
{ name: "nonce", type: "uint256" },
{ name: "deadline", type: "uint256" }
]
},
primaryType: "Permit",
domain: {
name: "MyToken",
version: "1",
chainId: 1,
verifyingContract: "0x1234567890123456789012345678901234567890"
},
message: {
owner: "0xowner...",
spender: "0xspender...",
value: "1000000000000000000", // 1 token
nonce: 0,
deadline: 1700000000
}
};
const permitHash = getEncodedEip712Data(permitTypedData, true);const orderTypedData = {
types: {
EIP712Domain: [
{ name: "name", type: "string" },
{ name: "version", type: "string" },
{ name: "chainId", type: "uint256" },
{ name: "verifyingContract", type: "address" }
],
Order: [
{ name: "maker", type: "address" },
{ name: "taker", type: "address" },
{ name: "tokenA", type: "address" },
{ name: "tokenB", type: "address" },
{ name: "amountA", type: "uint256" },
{ name: "amountB", type: "uint256" },
{ name: "expiry", type: "uint256" },
{ name: "nonce", type: "uint256" }
]
},
primaryType: "Order",
domain: {
name: "MyDEX",
version: "1",
chainId: 1,
verifyingContract: "0xDEX_CONTRACT_ADDRESS"
},
message: {
maker: "0xmaker...",
taker: "0x0000000000000000000000000000000000000000", // Any taker
tokenA: "0xTokenA...",
tokenB: "0xTokenB...",
amountA: "1000000000000000000",
amountB: "500000000000000000",
expiry: 1700000000,
nonce: 1
}
};
const orderHash = getEncodedEip712Data(orderTypedData, true);Arrays in EIP-712 are encoded by hashing each element recursively and then hashing the concatenated hashes.
Strings and dynamic bytes are hashed using keccak256 when used in structured data.
interface Eip712TypedData {
types: Record<string, Array<{ name: string; type: string }>>;
primaryType: string;
domain: Record<string, unknown>;
message: Record<string, unknown>;
}
interface EIP712Domain {
name?: string;
version?: string;
chainId?: number;
verifyingContract?: string;
salt?: string;
}Install with Tessl CLI
npx tessl i tessl/npm-web3-eth-abi