# Going Down the EIP-712 Rabbit Hole

By [Miguel Piedrafita](https://paragraph.com/@miguel.build) · 2021-08-19

---

![](https://storage.googleapis.com/papyrus_images/4e945fb9d400d5efedb3dcf58c08dc40f76d8360f7926d32671b09e273617505.jpg)

I spent way too much time figuring out how to generate and validate typed data signatures so you don't have to.

* * *

For [a project I’m working on](https://sonarwave.xyz), I need users to sign some data with their wallet. Normally, I’d just use personal signatures, but in this case, the data has a specific format, and I wanted to get the wallet signature prompt looking a little bit nicer than usual.

The World of Ethereum Signatures
--------------------------------

When signing some data with an Ethereum wallet, there are multiple signature types you can choose from. You can use the “regular” one, which will sign any string (this is what’s used to sign transactions); you can use personal signatures, which add a prefix to the signed message; or you can use typed data signatures, which allow you to define a format for the message the user will sign (and display it nicely on the signature prompt).

Let’s Type some Data
--------------------

For this project, I decided to go with typed data signatures (or EIP-712 signatures). To start, you need to define your `types` (the structure the message will be using) and your `domain` (some information about your app).

    // Let's assume we're signing an email message
    const message = {
        from: {
            name: 'Miguel Piedrafita',
            wallet: '0xE340b00B6B622C136fFA5CFf130eC8edCdDCb39D'
        },
        to: {
            name: 'Alex Masmej',
            wallet: '0xD3e9D60e4E4De615124D5239219F32946d10151D'
        },
        contents: 'We need more NFTs.'
    };
    
    // Our domain will include details about our app
    const domain = {
        name: 'Ether Mail',
        version: '1',
    };
    
    // Here we define the different types our message uses
    const types = {
        Person: [
            { name: 'name', type: 'string' },
            { name: 'wallet', type: 'address' }
        ],
        Mail: [
            { name: 'from', type: 'Person' },
            { name: 'to', type: 'Person' },
            { name: 'contents', type: 'string' }
        ]
    };
    

Once we have our `domain` and `types`, we can use the `ethers.js` library to get our signature.

    import { ethers } from 'ethers'
    
    const web3 = new ethers.providers.Web3Provider(provider)
    
    const signature = await web3.getSigner._signTypedData(
        domain, types, message,
    )
    

The Verificathon
----------------

Now we just need a way of verifying the signature in our server. For this, we’ll need the signature we just generated and the wallet address of the signer, as well as our `domain` and `types` from the last step.

    import { verifyTypedData } from 'ethers/lib/utils'
    
    export const verifySignature = (signature, message, address): boolean => {
        return verifyTypedData(
            domain, types, message, signature,
        ).toLowerCase() === address.toLowerCase()
    }
    

In Summary
----------

This took me quite a while to figure out (+2h 😅), so I thought I’d write it down for the next person that decides to go down this rabbit hole. Hopefully, it’ll help!

---

*Originally published on [Miguel Piedrafita](https://paragraph.com/@miguel.build/going-down-the-eip-712-rabbit-hole)*
