Links

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]}
Name
Type
Required?
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

Sign In With Ethereum

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

Example

signMessage()
request()
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");
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. 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

signMessage()
request()
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
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()
request()
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");
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",
});