Sign Typed Data (EIP-712)

EIP-712 is an Ethereum standard for hashing and signing typed structured data. This feature allows you to sign more than just a basic string message. It enables you to sign structured data, which can be useful for validating complex objects in decentralized applications, ensuring data integrity, and preventing signature replay attacks.
In this section, we will explore how to implement EIP-712 message signing using this library.
π§± 1. Framework Usage (ES6/Module Bundlers)
π Installation
If you havenβt already:
npm install multichain-wallet-connector
Or if you use Yarn:
yarn add multichain-wallet-connector
π A. Sign Typed Data Example
To sign structured data (e.g., user authentication, contract interactions), the EIP-712 standard requires the specification of a domain and message schema. Below is an example of how you can implement EIP-712 signing in your dApp:
import { connectWallet, signTypedData } from 'multichain-wallet-connector';
let provider, account;
async function connect() {
const res = await connectWallet({ chainId: 1 });//Replace with your chainId
provider = res.provider;
account = res.account;
}
sync function SignTypedData() {
if (!provider || !account) await connect();
// Define EIP-712 domain and message
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, // Mainnet
verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', // Your contract address here
},
message: {
from: {
name: 'Alice',
wallet: '0x1a9e3f6a3bfe827bfc0e9f1a3d9a768f1e36ab7d', // Alice's address
},
to: {
name: 'Bob',
wallet: '0x2d122fEF1613e82C0C90f443b59E54468e16525C', // Bob's address
},
contents: 'Hello Bob, this is a signed message!',
},
};
try {
const signature = await signTypedData(provider, typedData, account);
console.log('Signed Typed Data:', signature);
} catch (error) {
console.error('Error signing typed data:', error);
}
}
For typescript users, declare as a module in your types file:
declare module 'multichain-wallet-connector';
π 2. CommonJS via CDN (HTML/Vanilla JS)
β
Embed Script
<script src="https://cdn.jsdelivr.net/gh/Nworah-Gabriel/multichain-wallet-connector@v1.0.3/dist/connector.umd.min.js"></script>
Ensure this is added before your custom scripts in the HTML body.
π A. Sign Typed Data Example (CDN)
<script>
let provider, account;
async function connect() {
const res = await WalletConnector.connectWallet({ chainId: 1 }); // Mainnet
provider = res.provider;
account = res.account;
}
async function SignTypedData() {
if (!provider || !account) await connect();
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', // Replace with your contract address
},
message: {
from: {
name: 'Alice',
wallet: '0x1a9e3f6a3bfe827bfc0e9f1a3d9a768f1e36ab7d',
},
to: {
name: 'Bob',
wallet: '0x2d122fEF1613e82C0C90f443b59E54468e16525C',
},
contents: 'Hello Bob, this is a signed message!',
},
};
try {
const signature = await WalletConnector.signTypedData(provider, typedData, account);
console.log('Signed Typed Data:', signature);
} catch (error) {
console.error('Error signing typed data:', error);
}
}
</script>
<button onclick="SignTypedData()">Sign Typed Data</button>
βοΈ Error Handling (Recommended)
For production readiness, always wrap async calls with try/catch
:
try {
const signature = await WalletConnector.signMessage(provider, account, message);
} catch (error) {
console.error("Signing failed:", error.message);
}
π Summary
Sign Typed Data
signTypedData(provider, typedData, account)
β No
Authentication, contract signatures
Last updated