> ## Documentation Index
> Fetch the complete documentation index at: https://docs.phantom.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Sign-In-With (SIW) standards

> Authenticate users with Sign-In-With standards including SIWS, SIWE, and CAIP-122 supported by Phantom.

Applications that rely on `signMessage` for authenticating users can choose to opt-in to one of the various Sign-In with (SIW) standards. If a message follows one of the supported standards, Phantom will verify required fields at the time of signing.

At the time of this writing, Phantom supports:

* **Sign-In with Solana** ([specification](https://github.com/phantom/sign-in-with-solana))
* **Sign-In with Ethereum** ([EIP-4361](https://eips.ethereum.org/EIPS/eip-4361))
* **Sign-In with X** ([CAIP-122](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-122.md))

The serialized format of SIW messages is as follows:

```
${domain} wants you to sign in with your ${blockchain} account:
${address}

${statement}

URI: ${uri}
Version: ${version}
Chain ID: ${chain-id}
Nonce: ${nonce}
Issued At: ${issued-at}
Expiration Time: ${expiration-time}
Not Before: ${not-before}
Request ID: ${request-id}
Resources:
- ${resources[0]}
- ${resources[1]}
...
- ${resources[n]}
```

| Name              | Type       | Required? | Description                                                                                           |
| ----------------- | ---------- | --------- | ----------------------------------------------------------------------------------------------------- |
| `domain`          | `string`   | true      | The authority that is requesting the signing.                                                         |
| `address`         | `string`   | true      | The blockchain address that is performing the signing.                                                |
| `statement`       | `string`   | false     | A human-readable ASCII assertion that the user will sign. It MUST NOT contain `\\n`.                  |
| `uri`             | `string`   | true      | A URI referring to the resource that is the subject of the signing—that is, the subject of the claim. |
| `version`         | `string`   | true      | The current version of the message.                                                                   |
| `chain-id`        | `string`   | true      | The Chain ID to which the session is bound, and the network where Contract Accounts MUST be resolved. |
| `nonce`           | `string`   | true      | A randomized token to prevent signature replay attacks.                                               |
| `issued-at`       | `string`   | true      | The issuance time.                                                                                    |
| `expiration-time` | `string`   | false     | The time at which the signed authentication message is no longer valid.                               |
| `not-before`      | `string`   | false     | The time at which the signed authentication message starts being valid.                               |
| `request-id`      | `string`   | false     | A system-specific identifier used to uniquely refer to the authentication request.                    |
| `resources`       | `string[]` | false     | A list of URIs the user wishes to have resolved as part of the authentication by the relying party.   |

### Sign-In with Solana

See our [specification and integration guide](https://github.com/phantom/sign-in-with-solana) on GitHub.

### Sign-In with Ethereum

The Sign-In with Ethereum standard is defined by [EIP-4361](https://eips.ethereum.org/EIPS/eip-4361).

#### Examples

signMessage()

```javascript theme={null}
const provider = getProvider(); // see "Detecting the Provider"
const message = `magiceden.io wants you to sign in with your Ethereum account:
0xb9c5714089478a327f09197987f16f9e5d936e8a

Click Sign or Approve only means you have proved this wallet is owned by you.

URI: https://magiceden.io
Version: 1
Chain ID: 1
Nonce: bZQJ0SL6gJ
Issued At: 2022-10-25T16:52:02.748Z
Resources:
- https://foo.com
- https://bar.com`;
const encodedMessage = new TextEncoder().encode(message);
const signedMessage = await provider.signMessage(encodedMessage, "utf8");
```

request()

```javascript theme={null}
const provider = getProvider(); // see "Detecting the Provider"
const message = `magiceden.io wants you to sign in with your Ethereum account:
0xb9c5714089478a327f09197987f16f9e5d936e8a

Click Sign or Approve only means you have proved this wallet is owned by you.

URI: https://magiceden.io
Version: 1
Chain ID: 1
Nonce: bZQJ0SL6gJ
Issued At: 2022-10-25T16:52:02.748Z
Resources:
- https://foo.com
- https://bar.com`;
const encodedMessage = new TextEncoder().encode(message);
const signedMessage = await provider.request({
    method: "signMessage",
    params: {
         message: encodedMessage,
         display: "utf8",
    }
});
```

### Sign-In with X

The Sign-In with X standard is defined by [CAIP-122](https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-122.md). It uses [CAIP-10](https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-10) identifiers for the `address` field and [CAIP-2](https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-2) for `chain-id`.

<Info>
  While CAIP-122 is technically chain-agnostic, only Ethereum and Solana parsing are supported at this time.
</Info>

#### Ethereum example

signMessage()

```javascript theme={null}
const provider = getProvider(); // see "Detecting the Provider"
const message = `magiceden.io wants you to sign in with your Ethereum account:
eip155:1:0xb9c5714089478a327f09197987f16f9e5d936e8a

Click Sign or Approve only means you have proved this wallet is owned by you.

URI: https://magiceden.io
Version: 1
Chain ID: eip155:1
Nonce: bZQJ0SL6gJ
Issued At: 2022-10-25T16:52:02.748Z
Resources:
- https://foo.com
- https://bar.com`;
const encodedMessage = new TextEncoder().encode(message);
const signedMessage = await provider.signMessage(encodedMessage, "utf8");
```

request()

```javascript theme={null}
const provider = getProvider(); // see "Detecting the Provider"
const message = `magiceden.io wants you to sign in with your Ethereum account:
eip155:1:0xb9c5714089478a327f09197987f16f9e5d936e8a

Click Sign or Approve only means you have proved this wallet is owned by you.

URI: https://magiceden.io
Version: 1
Chain ID: eip155:1
Nonce: bZQJ0SL6gJ
Issued At: 2022-10-25T16:52:02.748Z
Resources:
- https://foo.com
- https://bar.com`;
const encodedMessage = new TextEncoder().encode(message);
const signedMessage = await provider.request({
    method: "signMessage",
    params: {
         message: encodedMessage,
         display: "utf8",
    }
});
```

#### Solana example

signMessage()

```javascript theme={null}
const provider = getProvider(); // see "Detecting the Provider"
const message = `magiceden.io wants you to sign in with your Solana account:
solana:mainnet:FYpB58cLw5cwiN763ayB2sFT8HLF2MRUBbbyRgHYiRpK

Click Sign or Approve only means you have proved this wallet is owned by you.

URI: https://magiceden.io
Version: 1
Chain ID: solana:mainnet
Nonce: bZQJ0SL6gJ
Issued At: 2022-10-25T16:52:02.748Z
Resources:
- https://foo.com
- https://bar.com`;
const encodedMessage = new TextEncoder().encode(message);
const signedMessage = await provider.signMessage(encodedMessage, "utf8");
```

request()

```javascript theme={null}
const provider = getProvider(); // see "Detecting the Provider"
const message = `magiceden.io wants you to sign in with your Solana account:
solana:mainnet:FYpB58cLw5cwiN763ayB2sFT8HLF2MRUBbbyRgHYiRpK

Click Sign or Approve only means you have proved this wallet is owned by you.

URI: https://magiceden.io
Version: 1
Chain ID: solana:mainnet
Nonce: bZQJ0SL6gJ
Issued At: 2022-10-25T16:52:02.748Z
Resources:
- https://foo.com
- https://bar.com`;
const encodedMessage = new TextEncoder().encode(message);
const signedMessage = await provider.request({
    method: "signMessage",
    params: {
         message: encodedMessage,
         display: "utf8",
    }
});
```

<Info>
  Phantom uses Ed25519 signatures for Solana message signatures. To verify a message signature, you can use the [tweetnacl](https://www.npmjs.com/package/tweetnacl) npm package.
</Info>
