For dApps & ServicesLedger WalletDiscoverIntegration walkthroughsdApp BrowserWrite a plugin for Clear Signing

Write a plugin for Clear Signing

This page shows how to add a Ledger plugin to a dApp running in the Ledger Wallet dApp browser, so transactions on your contracts display human-readable details on the device instead of raw hex.

A Ledger plugin is a small C application installed alongside the Ethereum device app. When the user signs a transaction whose to address matches one of your plugin’s registered contracts, the Ethereum app delegates the on-screen rendering to your plugin via a defined handler interface (handle_init_contract, handle_provide_parameter, handle_finalize, and others). Source: LedgerHQ/app-plugin-boilerplate and LedgerHQ/ethereum-plugin-sdk.

Before starting, check whether ERC-7730 covers your contracts. ERC-7730 is metadata-only, requires no on-device code, and is the supported path for most use cases. Plugins are reserved for contracts whose data does not fit the ERC-7730 schema.

⚠️

Plugin development requires Ledger’s prior approval. If your dApp does not already have a plugin slot agreed with Ledger, request one before following this guide.

Prerequisites

Steps

1. Build and submit your plugin

Follow the device-app guide How to develop an Ethereum plugin for the full development flow:

  1. Fork app-plugin-boilerplate and implement the SDK handlers for your contracts.
  2. Add functional tests covering every transaction path your plugin parses. They are mandatory for submission.
  3. Submit your plugin to Ledger’s submission process. The plugin name you ship with is the value you will reference from the manifest in the next step.

2. Reference the plugin in your dApp manifest

Once Ledger has accepted your plugin, set its exact name as dapp.nanoApp in your manifest:

{
  "id": "your-dapp-id",
  "name": "Your dApp",
  "url": "https://yourdapp.example",
  "dapp": {
    "nanoApp": "YourPluginName",
    "networks": [
      {
        "currency": "ethereum",
        "chainID": 1,
        "nodeURL": "https://eth-dapps.api.live.ledger.com"
      }
    ]
  },
  "manifestVersion": "2",
  "apiVersion": "^2.0.0",
  "branch": "stable"
}

The nanoApp value must match the plugin name registered with Ledger character-for-character (capitalization included). Use "Ethereum" only if your dApp does not require a plugin.

See the manifest reference for the full list of fields and an end-to-end example.

3. Test the integration end-to-end

  1. Enable Developer mode in Ledger Wallet.
  2. Install the latest Ethereum app and your plugin on the device.
  3. Add your local app using the manifest from step 2.
  4. Sign a transaction on each contract path your plugin handles and confirm the device shows the expected fields.

If a transaction still displays raw hex, see Common pitfalls.

Common pitfalls

  • Plugin not invoked. The Ethereum app only delegates to a plugin when the recipient address is in the plugin’s registered contract list. Double-check the to of the transaction matches one of the contracts declared in your plugin.
  • nanoApp name mismatch. A typo or wrong case in dapp.nanoApp falls back silently to blind signing. Copy the name from the plugin repository’s Makefile.
  • Wrong network. A plugin only loads when the chain matches one of the entries in dapp.networks. Add the chain you are testing on (Ledger Wallet currently supports mainnet, BSC, Arbitrum, Optimism, Base, Fantom, and Polygon).
  • Old Ethereum app. Plugins are pinned to a minimum Ethereum app version. Update the Ethereum app on the device if the plugin fails to load.
  • CI guidelines failing. The Guidelines_enforcer workflow on the boilerplate runs Ledger’s app guidelines; fix every reported rule before submitting (see device-app development requirements).

See also

Ledger
Copyright © Ledger SAS. All rights reserved. Ledger, Ledger Stax, Ledger Flex, Ledger Nano, Ledger Nano S, Ledger OS, Ledger Wallet, [LEDGER] (logo), [L] (logo) are trademarks owned by Ledger SAS.