> For the complete documentation index, see [llms.txt](https://help.enterprise.ledger.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://help.enterprise.ledger.com/help-center-v2/guides/transactions/signing-messages.md).

# Signing messages

How to sign a message from a Ledger Enterprise Account without moving funds, which message standards each network uses, and how to prove control of an address for an audit.

**Role: Operators.**

Signing a message proves control of an address without moving anything. Counterparties, exchanges and applications use it to confirm that an address is yours.

A message signature is a **Request**, governed by its own Rule. An Account that can send cannot necessarily sign messages: an Administrator has to add a **Message Signing Rule**. See [**Creating and editing Accounts**](/help-center-v2/guides/accounts/creating-and-editing-accounts.md).

Message signing is available on Bitcoin Accounts and on Ethereum and EVM Accounts. The **Messages** tab appears on an Account when a Message Signing Rule on it lets you sign messages. The tab lists the signed messages, with their **Date**, **Type**, **Message**, signature and **Status**.

## Signing

1. On the Account page, open the menu next to **Send**.
2. Select **Sign message**.
3. Check the **Address**. On a Bitcoin Account with Dynamic addresses, enter the address to sign with.
4. On an Ethereum or EVM Account, select the **Message standard**.
5. Enter the message, or paste the typed data.
6. Select **Review**.
7. Confirm the details on your Ledger device.

Like any Request, it then collects the approvals its Rule requires.

On Ethereum and EVM Accounts, and on Bitcoin Accounts with a Static address, the **Address** is the Account address and you cannot change it. When the Account has no signed message yet, the **Messages** tab also shows a **Sign message** button.

## Message standards

<table><thead><tr><th width="143.14453125">Standard</th><th width="252.2734375">Shown as</th><th>Networks</th></tr></thead><tbody><tr><td>EIP-191</td><td>Personal message (EIP-191)</td><td>Ethereum and EVM networks</td></tr><tr><td>EIP-712</td><td>Typed data (EIP-712)</td><td>Ethereum and EVM networks</td></tr><tr><td>BIP-137</td><td>BIP-137</td><td>Bitcoin and similar networks</td></tr></tbody></table>

Bitcoin Accounts always use BIP-137, so the form shows no **Message standard** choice.

**EIP-191** and **BIP-137** take plain text, or a hex string. A message made only of hex characters, with or without `0x`, is signed as raw bytes, not as text. For example, "cafe" is signed as two bytes. Any other message is signed as UTF-8 text. The form does not show which reading it used. A hex string must have an even number of characters.

**EIP-712** takes a JSON payload of typed data, in the **Typed data (JSON)** field. If you paste a valid EIP-712 payload into the message field, the standard changes to **Typed data (EIP-712)**. The form checks that the JSON is valid and that it has the basic EIP-712 structure. A payload that fails the full check is rejected at signing. The Request details show the **Domain**, the **Primary type** and the **Message fields** separately, with **Show raw JSON**.

That structure is the point of EIP-712. The device can display the fields individually, rather than a single opaque string.

## Proving control of an address

An auditor or a counterparty can ask you to prove that you control an address, for example in a proof-of-reserve audit. They send a message. You sign it with the address and return the signature.

The form signs the message exactly as you enter it, with its spaces and line breaks. Paste the message as you received it.

1. Sign the message from the address that the auditor names. See [Signing](#signing).
2. When the Request is approved, open the **Messages** tab of the Account.
3. Select the signed message.
4. Copy the **Signed address**, the message and the signature.
5. Send them to the auditor, with the message standard.

The signature shows as **Signature (Base64)** for BIP-137, and as **Signature (Hex)** for EIP-191 and EIP-712. If an EIP-191 or BIP-137 message is made only of hex characters, tell the auditor that it was signed as raw bytes.

### How many signatures an Account needs

Each signature covers one address.

| Account                                | Signatures to cover its funds                |
| -------------------------------------- | -------------------------------------------- |
| Ethereum or EVM Account                | One. Its token Accounts use the same address |
| Bitcoin Account with a Static address  | One, with the static address                 |
| Bitcoin Account with Dynamic addresses | One for each address that holds funds        |

A Dynamic Bitcoin Account holds its funds on many addresses. The **UTXOs** tab of the Account shows the **Address** of each unspent output. Sign once for each different address in that list. Each signature is a separate Request, with its own approvals.

An API user can create the same Requests over the API. See the [API documentation](https://help.enterprise.ledger.com/api-documentation-v2).

## What can go wrong

<table><thead><tr><th width="368.76953125">What you see</th><th>Why</th></tr></thead><tbody><tr><td>Message can't be empty</td><td>No message was entered</td></tr><tr><td>Typed data can't be empty</td><td>No EIP-712 payload was entered</td></tr><tr><td>Hex string must have an even number of characters</td><td>A hex message is malformed</td></tr><tr><td>Message exceeds maximum length</td><td>The message is above the 32 KiB that the interface accepts, or the EIP-712 JSON is above 65,536 characters</td></tr><tr><td>Typed data must be a valid JSON document</td><td>The EIP-712 payload is not valid JSON</td></tr><tr><td>This JSON is not an EIP-712 typed data payload</td><td>The JSON is valid, but not in EIP-712 shape</td></tr><tr><td>No matching rule found</td><td>No Message Signing Rule covers you on this Account</td></tr></tbody></table>

## Related

* [**Ethereum and EVM networks**](/help-center-v2/reference/networks/ethereum.md)
* [**Creating and editing Accounts**](/help-center-v2/guides/accounts/creating-and-editing-accounts.md)
* [**How governance works**](/help-center-v2/concepts/how-governance-works.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://help.enterprise.ledger.com/help-center-v2/guides/transactions/signing-messages.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
