> For the complete documentation index, see [llms.txt](https://docs.developers.thundercore.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.developers.thundercore.com/develop-on-tt-wallet/signing-messages.md).

# Signing Messages

## Summary

In the EVM-compatible blockchain world, signing messages can be used to prove ownership of a specific address. When signing a message with our private key, we don’t require interacting with the ThunderCore network. It can be implemented completely offline. Hence the purpose of this section is to describe how to use the signing messages in TT Wallet.

## Signing Data with TT Wallet

Now TT Wallet currently support three signing methods:

* `eth_signTypedData_v3`
* `eth_signTypedData_v4`
* `personal_sign`

If you’d like to know the differences between these signature methods, you can [visit this website](https://docs.metamask.io/guide/signing-data.html#signing-data-with-metamask).

## Sign Typed Data v3 and Sign Typed Data v4

`signTypedData_v3` and `signTypedData_v4` currently represent the latest version of the [EIP-721 spec](https://eips.ethereum.org/EIPS/eip-712), making it the most secure methods and cheap-to-verify messages on-chain or off-chain.

Here's an example how it works:

```javascript
const msgParams = {
  types: {
    EIP712Domain: [
      { name: "name", type: "string" },
      { name: "version", type: "string" },
      { name: "chainId", type: "uint256" },
      { name: "verifyingContract", type: "address" },
    ],
    Person: [
      { name: "name", type: "string" },
      { name: "wallet", type: "address" },
    ],
    Mail: [
      { name: "from", type: "Person" },
      { name: "to", type: "Person" },
      { name: "contents", type: "string" },
    ],
  },
  primaryType: "Mail",
  domain: {
    name: "Ether Mail",
    version: "1",
    chainId: 1,
    verifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
  },
  message: {
    from: { name: "Cow", wallet: "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826" },
    to: { name: "Bob", wallet: "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB" },
    contents: "Hello, Bob!",
  },
};

const from = window.ethereum.selectedAddress;

const params = [from, JSON.stringify(msgParams)];
const method = "eth_signTypedData_v3"; // Or eth_signTypedData_v4

window.ethereum.sendAsync(
  {
    method,
    params,
    from,
  },
  (err, result) => {
    if (err) return console.dir(err);
    if (result.error) {
      alert(result.error.message);
    }
    if (result.result) {
      console.log("TYPED SIGNED:" + JSON.stringify(result.result));
    }
  }
);
```

## Personal\_sign

`personal_sign` is similar to `eth_sign` which is specified by [the Ethereum RPCs#eth\_sign](https://eth.wiki/json-rpc/API#eth_sign), but has better security, see [Technical Reference](https://github.com/ethereum/go-ethereum/pull/2940) for details.

Most of the code is the same as above, here are the differences:

```javascript
const params = [JSON.stringify(msgParams), from];

const method = "personal_sign";
```
