Documentation
Tokens & Messages: EIP-712 messages

EIP-712 messages

What to do to clear-sign EIP-712 messages for your DApp?

It is possible to clear-sign EIP-712 messages with a Ledger device. The clear-signing is possible on the contracts that are whitelisted in the Ledger Dapps asset repository (opens in a new tab).

To add your contract to the list, you need to open a PR on this repository (see Contributing (opens in a new tab)).

On the Ledger DApps asset repository, we will need to input the contract address and the relevant fields that should be displayed to the users (on the device).

Here is an example of PR (opens in a new tab).

How does it work?

When interacting with a contract, the Ethereum app will be able to retrieve the list of fields to display and segregate them from all the ones it has parsed.

For this simple input data:

{
	"domain": {
		"chainId": 5,
		"name": "Obscure contract name",
		"verifyingContract": "0x41a5d506423e27a67a733454cd597b7fcb65c4d8",
		"version": "1"
	},
	"message": {
		"contents": "Hello, guys!",
		"from": {
			"name": "Alice",
			"wallets": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"
		},
		"to": [
			{
				"name": "Bob",
				"wallets": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"
			},
			{
				"name": "Charlie",
				"wallets": "0x28c6c06298d514db089934071355e5743bf21d60"
			}
		]
	},
	"primaryType": "Mail",
	"types": {
		"EIP712Domain": [
			{ "name": "name", "type": "string" },
			{ "name": "version", "type": "string" },
			{ "name": "chainId", "type": "uint256" },
			{ "name": "verifyingContract", "type": "address" }
		],
		"Mail": [
			{ "name": "from", "type": "Person" },
			{ "name": "to", "type": "Person[]" },
			{ "name": "contents", "type": "string" }
		],
		"Person": [
			{ "name": "name", "type": "string" },
			{ "name": "wallets", "type": "address" }
		]
	}
}

A filter for it would look like this :

{
	"0x41a5d506423e27a67a733454cd597b7fcb65c4d8": {
		"0b1da74afa6dd11245e6bdec1357b737cd7c6c0a": {
			"name": "Mail example",
			"fields": {
				"contents": "Message",
				"from.name": "Sender",
				"to.[].name": "Recipient"
			}
		}
	}
}
  • In the first layer we find the different contracts by their addresses.
  • In the second layer we find the different identifiers in each contract.

An identifier corresponds to the sha224 sum of the value (stripped of all spaces and newlines) of all the types in the input JSON which would look like this :

{"EIP712Domain":[{"name":"name","type":"string"},{"name":"version","type":"string"},{"name":"chainId","type":"uint256"},{"name":"verifyingContract","type":"address"}],"Mail":[{"name":"from","type":"Person"},{"name":"to","type":"Person[]"},{"name":"contents","type":"string"}],"Person":[{"name":"name","type":"string"},{"name":"wallets","type":"address"}]}
  • In the third layer we find the name of the contract (it is already present in the input JSON but some contracts have some obscure names, like OpenSea, here we can give it an easier and more readable one).
  • In the fourth layer we find a list of JSON paths that are accompanied by what we want the title in the UI to be instead of the JSON key for all the fields that match the given path.
Ledger
Copyright © Ledger SAS. All rights reserved. Ledger, Ledger Nano S, Ledger Vault, Bolos are registered trademarks of Ledger SAS