Manual Implementation

Craft ERC-7730 metadata files manually for complex contracts and EIP-712 messages when the builder tool is not enough.

What You’ll Build

A JSON metadata file that transforms this:

RAW TRANSACTION

0x23b872dd000000000000000000000000…
000000000000000000000000a0b86991…
000000000000000000000000000001f4

WITH YOUR METADATA
Swap 0.5 ETH for USDC
Protocol: Uniswap V3
Min. received: 1,245 USDC
Clear Signing showing readable transaction details on Ledger device

Your metadata enables users to verify exactly what they’re signing

When Manual Creation Fits

Choose manual creation when:
  • • You want one JSON to cover multiple deployments or contract variants
  • • You need EIP-712 or other structured messages
  • • Your display logic relies on nested paths, byte slices, or conditional rules
  • • You plan to reuse enums, constants, or includes across contracts
Stick to the JSON Builder if:
  • • You target a single contract deployment
  • • Function signatures decode cleanly (no nested tuples or calldata slicing)
  • • Parameter formatting is minimal
  • • You just need a quick start (< 10 minutes)
  • • No custom logic needed

Prerequisites

  • Contract ABI or EIP-712 schema for every interaction you plan to support
  • Chain IDs and contract addresses the participating wallets should recognise
  • A clear list of user-facing fields each signing device must display

Workflow at a Glance

  1. Map the context to every contract address or typed-data schema you need to support.
  2. Add metadata that introduces the protocol and stores shared values (tokens, enums, constants).
  3. Configure the display rules so calldata becomes readable labels and amounts for signers.
  4. Run local validation, then package and submit the finished JSON to the registry.

Step 1: Define the Context

Describe the contracts or typed data the metadata covers. For this walkthrough we use Tether (USDT) deployments on Ethereum, Polygon, and Arbitrum.

{
  "$schema": "https://github.com/LedgerHQ/clear-signing-erc7730-registry/blob/master/specs/erc7730-v1.schema.json",
  "context": {
    "$id": "Tether USD",
    "contract": {
      "abi": "https://api.etherscan.io/api?module=contract&action=getabi&address=0xdac17f958d2ee523a2206206994597c13d831ec7",
      "deployments": [
        { "chainId": 1, "address": "0xdAC17F958D2ee523a2206206994597C13D831ec7" },
        { "chainId": 137, "address": "0xc2132D05D31c914a87C6611C10748AEb04B58e8F" },
        { "chainId": 42161, "address": "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9" }
      ]
    }
  }
}

Working with EIP-712? Swap the contract block for an eip712 definition; see the Context section reference for the full schema.

Step 2: Add Protocol Metadata

This section introduces the protocol to users and holds reusable values for future steps.

"metadata": {
  "owner": "Tether",
  "info": {
    "legalName": "Tether Limited",
    "url": "https://tether.to/",
    "deploymentDate": "2017-11-28T12:41:21Z"
  },
  "token": {
    "ticker": "USDT",
    "name": "Tether USD",
    "decimals": 6
  }
}

Need enums, constants, or shared definitions? Jump to the Metadata section reference for every available key.

Step 3: Design the Display Rules

Map contract parameters to clear labels so signers immediately understand the action they approve.

"display": {
  "formats": {
    "transfer(address,uint256)": {
      "intent": "Send",
      "fields": [
        { "path": "_to", "label": "Recipient", "format": "addressOrName" },
        {
          "path": "_value",
          "label": "Amount",
          "format": "tokenAmount",
          "params": { "tokenPath": "@.to" }
        }
      ],
      "required": ["_to", "_value"],
      "excluded": []
    }
  }
}

You can key each entry in display.formats by declaration, canonical signature, or raw selector—choose the form your tooling already emits:

"transfer(address _to,uint256 _value)": { },   // Solidity declaration
"transfer(address,uint256)": { },              // Canonical signature
"0xa9059cbb": { }                             // Function selector
⚠️

Every function parameter must be shown or added to excluded. Validation fails if a field is left unaccounted for.

Browse the full list of format types, path syntax, array helpers, and advanced patterns in the Format reference and Path system guide.

Need to reuse the same display logic across multiple contracts? Extract shared snippets into a helper file and include it:

{
  "$schema": "../../specs/erc7730-v1.schema.json",
  "includes": "common-swap.json",
  "context": {
    "contract": {
      "deployments": [{ "chainId": 324, "address": "0x6fd4383cB451173D5f9304F041C7BCBf27d561fF" }]
    }
  }
}

Included files can expose reusable snippets under display.definitions:

{
  "display": {
    "definitions": {
      "sendAmount": {
        "label": "Amount to Send",
        "format": "tokenAmount",
        "params": { "tokenPath": "desc.srcToken" }
      }
    },
    "formats": {
      "swap(...)": {
        "intent": "Swap",
        "fields": [
          { "path": "desc.amount", "$ref": "$.display.definitions.sendAmount" }
        ]
      }
    }
  }
}

If the including file redeclares the same key, its version wins. Use this to override only the pieces that differ per chain.

Step 4: Validate and Iterate

  • Use the Validate & Submit guide to run schema checks and complete the registry submission workflow.
  • Expand coverage by adding more functions to display.formats or additional deployments to context.
  • When you need advanced features such as shared includes, enums, or domain separators, jump into the specification so the manual file stays lean and maintainable.

Final JSON

Combine the sections above into your final .json file:

{
  "$schema": "https://github.com/LedgerHQ/clear-signing-erc7730-registry/blob/master/specs/erc7730-v1.schema.json",
  "context": {
    "$id": "Tether USD",
    "contract": {
      "abi": "https://api.etherscan.io/api?module=contract&action=getabi&address=0xdac17f958d2ee523a2206206994597c13d831ec7",
      "deployments": [
        { "chainId": 1, "address": "0xdAC17F958D2ee523a2206206994597C13D831ec7" },
        { "chainId": 137, "address": "0xc2132D05D31c914a87C6611C10748AEb04B58e8F" },
        { "chainId": 42161, "address": "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9" }
      ]
    }
  },
  "metadata": {
    "owner": "Tether",
    "info": {
      "legalName": "Tether Limited",
      "url": "https://tether.to/",
      "deploymentDate": "2017-11-28T12:41:21Z"
    },
    "token": {
      "ticker": "USDT",
      "name": "Tether USD",
      "decimals": 6
    }
  },
  "display": {
    "formats": {
      "transfer(address,uint256)": {
        "intent": "Send",
        "fields": [
          { "path": "_to", "label": "Recipient", "format": "addressOrName" },
          {
            "path": "_value",
            "label": "Amount",
            "format": "tokenAmount",
            "params": { "tokenPath": "@.to" }
          }
        ],
        "required": ["_to", "_value"],
        "excluded": []
      }
    }
  }
}

Complete Examples

{
  "$schema": "https://github.com/LedgerHQ/clear-signing-erc7730-registry/blob/master/specs/erc7730-v1.schema.json",
  "context": {
    "contract": {
      "abi": "https://api.etherscan.io/api?module=contract&action=getabi&address=0xdac17f958d2ee523a2206206994597c13d831ec7",
      "deployments": [
        { "chainId": 1, "address": "0xdAC17F958D2ee523a2206206994597C13D831ec7" },
        { "chainId": 137, "address": "0xc2132D05D31c914a87C6611C10748AEb04B58e8F" },
        { "chainId": 42161, "address": "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9" }
      ]
    }
  },
  "metadata": {
    "owner": "Tether",
    "info": {
      "legalName": "Tether Limited",
      "url": "https://tether.to/",
      "deploymentDate": "2017-11-28T12:41:21Z"
    }
  },
  "display": {
    "formats": {
      "transfer(address,uint256)": {
        "intent": "Send",
        "fields": [
          { "path": "_to", "label": "To", "format": "addressOrName" },
          { "path": "_value", "label": "Amount", "format": "tokenAmount", "params": { "tokenPath": "@.to" } }
        ],
        "required": ["_to", "_value"],
        "excluded": []
      }
    }
  }
}

Go Deeper

Next Steps

Ledger
Copyright © Ledger SAS. All rights reserved. Ledger, Ledger Stax, Ledger Nano S, Ledger Vault, Bolos are trademarks owned by Ledger SAS