Web3 module to interact with the Ethereum blockchain and smart contracts.
67
The cryptographic operations functionality provides comprehensive signing capabilities including message signing, transaction signing, and EIP-712 typed data signing with support for various signature formats.
Signs arbitrary messages using an account's private key.
sign(message: Bytes, addressOrIndex: Address | Numbers, returnFormat?: DataFormat): Promise<SignatureObject>;Parameters:
message: The message to sign (hex string or bytes)addressOrIndex: Account address or wallet index to sign withreturnFormat: Output format configurationUsage Example:
// Sign a simple message
const message = "Hello, Ethereum!";
const signature = await eth.sign(message, "0x742d35Cc6634C0532925a3b8D7389Fc3C1b6c5E");
console.log("Message signature:", {
messageHash: signature.messageHash,
r: signature.r,
s: signature.s,
v: signature.v,
signature: signature.signature
});
// Sign hex-encoded data
const hexMessage = "0x48656c6c6f2c20457468657265756d21"; // "Hello, Ethereum!" in hex
const hexSignature = await eth.sign(hexMessage, "0x742d35Cc6634C0532925a3b8D7389Fc3C1b6c5E");
// Verify signature (using web3-utils)
import { recover } from "web3-utils";
const recoveredAddress = recover(message, signature.signature);
console.log("Signature verification:", recoveredAddress === "0x742d35Cc6634C0532925a3b8D7389Fc3C1b6c5E");Signs a transaction without broadcasting it to the network.
signTransaction(transaction: Transaction, returnFormat?: DataFormat): Promise<SignedTransactionInfoAPI>;Usage Example:
// Sign a transaction for later broadcast
const transaction = {
from: "0x742d35Cc6634C0532925a3b8D7389Fc3C1b6c5E",
to: "0x8ba1f109551bD432803012645Hac136c1c1b6c5E",
value: "1000000000000000000", // 1 ETH
gas: "21000",
gasPrice: "20000000000", // 20 Gwei
nonce: await eth.getTransactionCount("0x742d35Cc6634C0532925a3b8D7389Fc3C1b6c5E")
};
const signedTx = await eth.signTransaction(transaction);
console.log("Signed transaction:", {
messageHash: signedTx.messageHash,
r: signedTx.r,
s: signedTx.s,
v: signedTx.v,
rawTransaction: signedTx.rawTransaction
});
// Broadcast the signed transaction later
const receipt = await eth.sendSignedTransaction(signedTx.rawTransaction);// Sign EIP-1559 transaction
const eip1559Transaction = {
from: "0x742d35Cc6634C0532925a3b8D7389Fc3C1b6c5E",
to: "0x8ba1f109551bD432803012645Hac136c1c1b6c5E",
value: "1000000000000000000",
gas: "21000",
maxFeePerGas: "30000000000", // 30 Gwei
maxPriorityFeePerGas: "2000000000", // 2 Gwei
nonce: await eth.getTransactionCount("0x742d35Cc6634C0532925a3b8D7389Fc3C1b6c5E"),
type: 2 // EIP-1559
};
const signed1559Tx = await eth.signTransaction(eip1559Transaction);Signs structured data according to EIP-712 standard for improved user experience and security.
signTypedData(address: Address, typedData: Eip712TypedData, useLegacy?: boolean, returnFormat?: DataFormat): Promise<SignatureObject>;Parameters:
address: Signer's addresstypedData: EIP-712 structured data objectuseLegacy: Use legacy signing format (default: false)returnFormat: Output format configurationUsage Example:
// Define EIP-712 domain and types
const domain = {
name: "MyDApp",
version: "1",
chainId: 1,
verifyingContract: "0x1234567890123456789012345678901234567890"
};
const types = {
Person: [
{ name: "name", type: "string" },
{ name: "wallet", type: "address" }
],
Mail: [
{ name: "from", type: "Person" },
{ name: "to", type: "Person" },
{ name: "contents", type: "string" }
]
};
const message = {
from: {
name: "Alice",
wallet: "0x742d35Cc6634C0532925a3b8D7389Fc3C1b6c5E"
},
to: {
name: "Bob",
wallet: "0x8ba1f109551bD432803012645Hac136c1c1b6c5E"
},
contents: "Hello Bob!"
};
const typedData = {
domain,
types,
primaryType: "Mail",
message
};
// Sign the typed data
const signature = await eth.signTypedData(
"0x742d35Cc6634C0532925a3b8D7389Fc3C1b6c5E",
typedData
);
console.log("EIP-712 signature:", signature);// Sign ERC-20 permit for gasless approvals
async function signPermit(
tokenAddress: Address,
owner: Address,
spender: Address,
value: string,
deadline: number,
nonce: number
) {
const domain = {
name: "Token Name", // Get from token contract
version: "1",
chainId: await eth.getChainId(),
verifyingContract: tokenAddress
};
const types = {
Permit: [
{ name: "owner", type: "address" },
{ name: "spender", type: "address" },
{ name: "value", type: "uint256" },
{ name: "nonce", type: "uint256" },
{ name: "deadline", type: "uint256" }
]
};
const message = {
owner,
spender,
value,
nonce,
deadline
};
const typedData = {
domain,
types,
primaryType: "Permit",
message
};
return await eth.signTypedData(owner, typedData);
}// Sign meta-transaction for gasless execution
async function signMetaTransaction(
from: Address,
to: Address,
data: string,
nonce: number,
relayerAddress: Address
) {
const domain = {
name: "MetaTransactionRelay",
version: "1",
chainId: await eth.getChainId(),
verifyingContract: relayerAddress
};
const types = {
MetaTransaction: [
{ name: "from", type: "address" },
{ name: "to", type: "address" },
{ name: "data", type: "bytes" },
{ name: "nonce", type: "uint256" }
]
};
const message = {
from,
to,
data,
nonce
};
const typedData = {
domain,
types,
primaryType: "MetaTransaction",
message
};
return await eth.signTypedData(from, typedData);
}import { recover, hashMessage } from "web3-utils";
// Verify message signature
function verifyMessageSignature(message: string, signature: string, expectedSigner: Address): boolean {
try {
const recoveredAddress = recover(message, signature);
return recoveredAddress.toLowerCase() === expectedSigner.toLowerCase();
} catch (error) {
console.error("Signature verification failed:", error);
return false;
}
}
// Verify EIP-712 signature (requires additional library like @ethersproject/hash)
async function verifyTypedDataSignature(
typedData: Eip712TypedData,
signature: string,
expectedSigner: Address
): Promise<boolean> {
try {
// This would require implementing EIP-712 hash calculation
// or using a library like ethers.js _TypedDataEncoder
const digest = computeTypedDataHash(typedData);
const recoveredAddress = recover(digest, signature);
return recoveredAddress.toLowerCase() === expectedSigner.toLowerCase();
} catch (error) {
console.error("Typed data signature verification failed:", error);
return false;
}
}// Sign multiple messages in batch
async function signMultipleMessages(
messages: string[],
signerAddress: Address
): Promise<SignatureObject[]> {
const signatures = await Promise.all(
messages.map(message => eth.sign(message, signerAddress))
);
return signatures;
}
// Sign multiple transactions in batch
async function signMultipleTransactions(
transactions: Transaction[],
signerAddress: Address
): Promise<SignedTransactionInfoAPI[]> {
// Add nonces if not present
const baseNonce = await eth.getTransactionCount(signerAddress);
const txsWithNonces = transactions.map((tx, index) => ({
...tx,
from: signerAddress,
nonce: tx.nonce ?? (baseNonce + index)
}));
const signedTxs = await Promise.all(
txsWithNonces.map(tx => eth.signTransaction(tx))
);
return signedTxs;
}// Convert between signature formats
function parseSignature(signature: string) {
if (signature.startsWith('0x')) {
signature = signature.slice(2);
}
const r = '0x' + signature.slice(0, 64);
const s = '0x' + signature.slice(64, 128);
const v = parseInt(signature.slice(128, 130), 16);
return { r, s, v };
}
function combineSignature(r: string, s: string, v: number): string {
const rHex = r.startsWith('0x') ? r.slice(2) : r;
const sHex = s.startsWith('0x') ? s.slice(2) : s;
const vHex = v.toString(16).padStart(2, '0');
return '0x' + rHex + sHex + vHex;
}interface SignatureObject {
messageHash: HexString32Bytes;
r: HexString32Bytes;
s: HexString32Bytes;
v: HexString;
signature: HexString;
}
interface SignedTransactionInfoAPI {
messageHash: HexString32Bytes;
r: HexString32Bytes;
s: HexString32Bytes;
v: HexString;
rawTransaction: HexString;
transactionHash: HexString32Bytes;
}
interface Eip712TypedData {
domain: {
name?: string;
version?: string;
chainId?: Numbers;
verifyingContract?: Address;
salt?: HexString32Bytes;
};
types: {
[key: string]: Array<{
name: string;
type: string;
}>;
};
primaryType: string;
message: {
[key: string]: any;
};
}
interface Transaction {
from: Address;
to?: Address;
value?: Numbers;
gas?: Numbers;
gasPrice?: Numbers;
maxFeePerGas?: Numbers;
maxPriorityFeePerGas?: Numbers;
data?: Bytes;
nonce?: Numbers;
type?: Numbers;
accessList?: AccessList;
chainId?: Numbers;
}
type Address = HexString20Bytes;
type Numbers = HexString | number | bigint;
type Bytes = HexString;Install with Tessl CLI
npx tessl i tessl/npm-web3-ethdocs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10