import Web3 from "web3";
import { Magic } from "magic-sdk";
import { recoverPersonalSignature } from "@metamask/eth-sig-util";
const magic = new Magic("YOUR_API_KEY", {
network: "goerli",
});
const web3 = new Web3(magic.rpcProvider);
export const signTypedDataV4Payload = {
domain: {
// Defining the chain aka Rinkeby goerli or Ethereum Main Net
chainId: 5,
// Give a user friendly name to the specific contract you are signing for.
name: "Ether Mail",
// If name isn't enough add verifying contract to make sure you are establishing contracts with the proper entity
verifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
// Just let's you know the latest version. Definitely make sure the field name is correct.
version: "1",
},
// Defining the message signing data content.
message: {
/* - Anything you want. Just a JSON Blob that encodes the data you want to send - No required fields - This is DApp Specific - Be as explicit as possible when building out the message schema. */
contents: "Hello, Bob!",
attachedMoneyInEth: 4.2,
from: {
name: "Cow",
wallets: [
"0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
"0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF",
],
},
to: [
{
name: "Bob",
wallets: [
"0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB",
"0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57",
"0xB0B0b0b0b0b0B000000000000000000000000000",
],
},
],
},
// Refers to the keys of the _types_ object below.
primaryType: "Mail",
types: {
// TODO: Clarify if EIP712Domain refers to the domain the contract is hosted on
EIP712Domain: [
{ name: "name", type: "string" },
{ name: "version", type: "string" },
{ name: "chainId", type: "uint256" },
{ name: "verifyingContract", type: "address" },
],
// Not an EIP712Domain definition
Group: [
{ name: "name", type: "string" },
{ name: "members", type: "Person[]" },
],
// Refer to PrimaryType
Mail: [
{ name: "from", type: "Person" },
{ name: "to", type: "Person[]" },
{ name: "contents", type: "string" },
],
// Not an EIP712Domain definition
Person: [
{ name: "name", type: "string" },
{ name: "wallets", type: "address[]" },
],
},
};
const signAndVerify = async () => {
const params = [account, signTypedDataV3Payload];
const method = "eth_signTypedData_v4";
const signature = await magic.rpcProvider.request({
method,
params,
});
console.log("signature:", signature);
// recover the public address of the signer to verify
const recoveredAddress = recoverTypedSignature({
data: signTypedDataV3Payload,
signature,
version: "V4",
});
console.log(
recoveredAddress.toLocaleLowerCase() === account.toLocaleLowerCase()
? "Signing success!"
: "Signing failed!"
);
};