Sign-In-With (SIW) Standards

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:

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]}
NameTypeRequired?Description

domain

string

The authority that is requesting the signing.

address

string

The blockchain address that is performing the signing.

statement

string

A human-readable ASCII assertion that the user will sign. It MUST NOT contain \n.

uri

string

A URI referring to the resource that is the subject of the signing (i.e. the subject of the claim).

version

string

The current version of the message.

chain-id

string

The Chain ID to which the session is bound, and the network where Contract Accounts MUST be resolved.

nonce

string

A randomized token to prevent signature replay attacks.

issued-at

string

The issuance time.

expiration-time

string

The time at which the signed authentication message is no longer valid.

not-before

string

The time at which the signed authentication message starts being valid.

request-id

string

A system-specific identifier used to uniquely refer to the authentication request.

resources

string[]

A list of uris the user wishes to have resolved as part of the authentication by the relying party.

Sign In With Solana

Please refer to our specification and integration guide on GitHub.

Sign In With Ethereum

The Sign In With Ethereum standard is defined by EIP-4361.

Example

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");

Sign In With X

The Sign In With X standard is defined by CAIP-122. It uses CAIP-10 identifiers for the address field and CAIP-2 for chain-id.

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

Ethereum Example

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");java

Solana Example

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");

Last updated