### Reference Implementation Example Source: https://github.com/signinwithethereum/siwe/blob/main/packages/spec/erc-4361.md A JavaScript example demonstrating the implementation of Sign-In with Ethereum. ```javascript import { verifyMessage } from "@ethersproject/wallet"; const message = { domain: "localhost:3000", address: "0x0000000000000000000000000000000000000000", statement: "Please sign this message to confirm your identity.", uri: "http://localhost:3000/login", version: "1", chainId: 1, nonce: "3j4n89f3j4n89", issuedAt: "2021-09-30T13:37:00.000Z", }; const formattedMessage = `${message.domain} wants you to sign in with your Ethereum account: ${message.address} ${message.statement} URI: ${message.uri} Version: ${message.version} Chain ID: ${message.chainId} Nonce: ${message.nonce} Issued At: ${message.issuedAt}`; const signature = "0x..."; // Signature from the user // Verify the signature const signerAddress = verifyMessage(formattedMessage, signature); console.log(signerAddress === message.address); // true ``` -------------------------------- ### Install @signinwithethereum/siwe-parser Source: https://github.com/signinwithethereum/siwe/blob/main/packages/siwe-parser/README.md Install the package using npm. ```bash npm install @signinwithethereum/siwe-parser ``` -------------------------------- ### Install @signinwithethereum/siwe Source: https://github.com/signinwithethereum/siwe/blob/main/packages/siwe/README.md Install the package and a required peer dependency like viem or ethers. ```bash npm install @signinwithethereum/siwe ``` ```bash npm install viem # recommended # or npm install ethers # v5 or v6 ``` -------------------------------- ### Quick Start: Create and Verify SIWE Message Source: https://github.com/signinwithethereum/siwe/blob/main/packages/siwe/README.md Set up the configuration, create a SIWE message, prepare it for signing, and verify a signature. Ensure the client has signed the message. ```typescript import { SiweMessage, configure, createConfig } from '@signinwithethereum/siwe' // One-time setup — auto-detects viem or ethers configure(await createConfig('https://eth.llamarpc.com')) // Create a message const message = new SiweMessage({ domain: 'example.com', address: '0x...', statement: 'Sign in to Example', uri: 'https://example.com', version: '1', chainId: 1, nonce: 'abc12345defg78901', issuedAt: new Date().toISOString(), }) // Get the EIP-4361 string to sign const messageString = message.prepareMessage() // Verify a signature (after signing on the client) const { success, data, error } = await message.verify( { signature, domain: 'example.com', nonce: message.nonce }, { suppressExceptions: true }, ) ``` -------------------------------- ### SIWE Message Example with Implicit Scheme Source: https://github.com/signinwithethereum/siwe/blob/main/packages/spec/erc-4361.md An example of a SIWE message where the scheme is implicitly HTTPS, demonstrating the standard format for signing in. ```text example.com wants you to sign in with your Ethereum account: 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 I accept the ExampleOrg Terms of Service: https://example.com/tos URI: https://example.com/login Version: 1 Chain ID: 1 Nonce: 32891756 Issued At: 2021-09-30T16:25:24Z Resources: - ipfs://bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq/ - https://example.com/my-web2-claim.json ``` -------------------------------- ### Configure Verification Backend: Auto-detect Source: https://github.com/signinwithethereum/siwe/blob/main/packages/siwe/README.md Configure the package to automatically detect and use either viem or ethers for message verification. This is the recommended one-time setup. ```typescript import { configure, createConfig } from '@signinwithethereum/siwe' configure(await createConfig('https://eth.llamarpc.com')) ``` -------------------------------- ### SIWE Message Example with Explicit Scheme Source: https://github.com/signinwithethereum/siwe/blob/main/packages/spec/erc-4361.md An example of a SIWE message that explicitly defines the scheme (e.g., 'https://') in the domain, demonstrating how to specify the protocol. ```text https://example.com wants you to sign in with your Ethereum account: 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 I accept the ExampleOrg Terms of Service: https://example.com/tos URI: https://example.com/login Version: 1 Chain ID: 1 Nonce: 32891756 Issued At: 2021-09-30T16:25:24Z Resources: - ipfs://bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq/ - https://example.com/my-web2-claim.json ``` -------------------------------- ### SIWE Message Example with Implicit Scheme and Explicit Port Source: https://github.com/signinwithethereum/siwe/blob/main/packages/spec/erc-4361.md An example of a SIWE message with an implicit HTTPS scheme but an explicit port specified in the domain, showing how to handle non-standard ports. ```text example.com:3388 wants you to sign in with your Ethereum account: 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 I accept the ExampleOrg Terms of Service: https://example.com/tos URI: https://example.com/login Version: 1 Chain ID: 1 Nonce: 32891756 Issued At: 2021-09-30T16:25:24Z Resources: - ipfs://bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq/ - https://example.com/my-web2-claim.json ``` -------------------------------- ### Configure Verification Backend: Viem Source: https://github.com/signinwithethereum/siwe/blob/main/packages/siwe/README.md Configure the package specifically for viem. Ensure you have a viem public client set up. ```typescript import { configure, createViemConfig } from '@signinwithethereum/siwe' import { createPublicClient, http } from 'viem' import { mainnet } from 'viem/chains' const publicClient = createPublicClient({ chain: mainnet, transport: http() }) configure(await createViemConfig({ publicClient })) ``` -------------------------------- ### Configuration Functions Source: https://github.com/signinwithethereum/siwe/blob/main/packages/siwe/README.md Functions to configure the verification backend, either automatically detecting viem or ethers, or explicitly using one of them. ```APIDOC ### `createConfig(rpcUrl)` — auto-detect Detects whether viem or ethers is installed and creates the appropriate config with full EIP-1271 support. ```ts import { configure, createConfig } from '@signinwithethereum/siwe' configure(await createConfig('https://eth.llamarpc.com')) ``` ### `createViemConfig(opts)` — viem ```ts import { configure, createViemConfig } from '@signinwithethereum/siwe' import { createPublicClient, http } from 'viem' import { mainnet } from 'viem/chains' const publicClient = createPublicClient({ chain: mainnet, transport: http() }) configure(await createViemConfig({ publicClient })) ``` ### `createEthersConfig(provider)` — ethers ```ts import { configure, createEthersConfig } from '@signinwithethereum/siwe' import { ethers } from 'ethers' const provider = new ethers.JsonRpcProvider('https://eth.llamarpc.com') configure(createEthersConfig(provider)) ``` ### Per-call config Instead of setting a global config, you can pass `config` in verify options: ```ts const config = await createViemConfig({ publicClient }) await message.verify({ signature, domain, nonce }, { config }) ``` ``` -------------------------------- ### Configure Verification Backend: Ethers Source: https://github.com/signinwithethereum/siwe/blob/main/packages/siwe/README.md Configure the package specifically for ethers. Provide an ethers JsonRpcProvider instance. ```typescript import { configure, createEthersConfig } from '@signinwithethereum/siwe' import { ethers } from 'ethers' const provider = new ethers.JsonRpcProvider('https://eth.llamarpc.com') configure(createEthersConfig(provider)) ``` -------------------------------- ### Informal SIWE Message Template Source: https://github.com/signinwithethereum/siwe/blob/main/packages/spec/erc-4361.md A Bash-like template illustrating the structure of a full SIWE message, useful for understanding field placement and optionality. ```bash ${scheme}:// ${domain} wants you to sign in with your Ethereum 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]} ``` -------------------------------- ### SiweConfig Interface Source: https://github.com/signinwithethereum/siwe/blob/main/packages/siwe/README.md Defines the interface for custom verification backends, allowing users to provide their own implementations for message verification and related utilities. ```APIDOC ### `SiweConfig` Interface for bringing your own verification backend: ```ts interface SiweConfig { verifyMessage: (message: string, signature: string) => string | Promise hashMessage: (message: string) => string getAddress: (address: string) => string checkContractWalletSignature?: ( address: string, message: string, signature: string, chainId: number, ) => Promise } ``` ``` -------------------------------- ### Create SiweMessage from Object or String Source: https://github.com/signinwithethereum/siwe/blob/main/packages/siwe/README.md Instantiate a SiweMessage either by providing its fields as an object or by parsing a raw EIP-4361 formatted string. ```typescript // From object const msg = new SiweMessage({ domain, address, uri, version, chainId, nonce, issuedAt }) // From EIP-4361 string const msg = new SiweMessage(rawMessageString) ``` -------------------------------- ### Per-call Configuration for Verification Source: https://github.com/signinwithethereum/siwe/blob/main/packages/siwe/README.md Override the global configuration for a single verification call by passing a config object directly to the verify options. ```typescript const config = await createViemConfig({ publicClient }) await message.verify({ signature, domain, nonce }, { config }) ``` -------------------------------- ### Utility Functions Source: https://github.com/signinwithethereum/siwe/blob/main/packages/siwe-parser/README.md Provides utility functions for validating Ethereum addresses and ISO8601 dates. ```APIDOC ## Utility Functions ### Description Provides utility functions for validating Ethereum addresses and ISO8601 dates. ### Functions - **isEIP55Address(address: string): boolean** Checks if the provided string is a valid EIP-55 checksummed Ethereum address. Example: `isEIP55Address('0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B') // true` - **isValidISO8601Date(dateString: string): boolean** Checks if the provided string is a valid ISO 8601 formatted date string. Example: `isValidISO8601Date('2024-01-01T00:00:00Z') // true` ``` -------------------------------- ### SiweMessage Class Source: https://github.com/signinwithethereum/siwe/blob/main/packages/siwe/README.md The `SiweMessage` class allows you to create SIWE messages from an object or parse them from an EIP-4361 string. It exposes fields for message components and provides methods for preparing and verifying messages. ```APIDOC ## `SiweMessage` Create from an object or parse from an EIP-4361 string: ```ts // From object const msg = new SiweMessage({ domain, address, uri, version, chainId, nonce, issuedAt }) // From EIP-4361 string const msg = new SiweMessage(rawMessageString) ``` **Fields:** `domain`, `address`, `uri`, `version`, `chainId`, `nonce`, `issuedAt` (required) and `scheme`, `statement`, `expirationTime`, `notBefore`, `requestId`, `resources` (optional). ### `prepareMessage(): string` Returns the EIP-4361 formatted message string, ready for EIP-191 signing. ### `verify(params, opts?): Promise` Verifies a signed message. Returns `{ success, data, error }`. **`params` (VerifyParams):** | Field | Required | Description | |---|---|---| | `signature` | yes | The wallet signature | | `domain` | yes | Expected domain (origin binding) | | `nonce` | yes | Expected nonce (replay protection) | | `scheme` | no | Expected URI scheme | | `uri` | no | Expected URI (required in strict mode) | | `chainId` | no | Expected chain ID (required in strict mode) | | `requestId` | no | Expected request ID | | `time` | no | ISO 8601 time to check against (defaults to now) | **`opts` (VerifyOpts):** | Field | Description | |---|---| | `config` | Per-call `SiweConfig` (overrides global) | | `suppressExceptions` | Return errors in response instead of throwing (default: `false`) | | `strict` | Require `uri` and `chainId` in params | | `verificationFallback` | Custom verification function run alongside EIP-1271 | ``` -------------------------------- ### Utility Functions for SIWE Source: https://github.com/signinwithethereum/siwe/blob/main/packages/siwe-parser/README.md Provides utility functions for validating EIP-55 addresses and ISO 8601 dates. ```typescript import { isEIP55Address, isValidISO8601Date, } from '@signinwithethereum/siwe-parser' isEIP55Address('0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B') // true isValidISO8601Date('2024-01-01T00:00:00Z') // true ``` -------------------------------- ### ParsedMessage Constructor Source: https://github.com/signinwithethereum/siwe/blob/main/packages/siwe-parser/README.md Instantiate a ParsedMessage object by passing a raw SIWE message string. The constructor will throw an error if the message does not conform to the EIP-4361 specification. ```APIDOC ## ParsedMessage Constructor ### Description Instantiate a `ParsedMessage` object by passing a raw SIWE message string. The constructor will throw an error if the message does not conform to the EIP-4361 specification. ### Usage ```typescript import { ParsedMessage } from '@signinwithethereum/siwe-parser' const message = new ParsedMessage(rawMessage) console.log(message.domain) console.log(message.address) console.log(message.uri) console.log(message.version) console.log(message.chainId) console.log(message.nonce) console.log(message.issuedAt) ``` ### Fields | Field | Type | Required | | ---------------- | ---------- | -------- | | `domain` | `string` | Yes | | `address` | `string` | Yes | | `uri` | `string` | Yes | | `version` | `string` | Yes | | `chainId` | `number` | Yes | | `nonce` | `string` | Yes | | `issuedAt` | `string` | Yes | | `scheme` | `string` | No | | `statement` | `string` | No | | `expirationTime` | `string` | No | | `notBefore` | `string` | No | | `requestId` | `string` | No | | `resources` | `string[]` | No | ``` -------------------------------- ### Generate a Cryptographically Secure Nonce Source: https://github.com/signinwithethereum/siwe/blob/main/packages/siwe/README.md Generate a unique and secure nonce for use in SIWE messages to prevent replay attacks. The nonce has 96 bits of entropy and is alphanumeric. ```typescript import { generateNonce } from '@signinwithethereum/siwe' const nonce = generateNonce() ``` -------------------------------- ### Check for EIP-6492 Signature Source: https://github.com/signinwithethereum/siwe/blob/main/packages/siwe/README.md Use `isEIP6492Signature` to determine if a signature originates from a pre-deployed smart contract wallet. ```typescript import { isEIP6492Signature, EIP6492_MAGIC_SUFFIX } from '@signinwithethereum/siwe' if (isEIP6492Signature(sig)) { // Signature is from a pre-deployed smart contract wallet } ``` -------------------------------- ### Parse a SIWE Message Source: https://github.com/signinwithethereum/siwe/blob/main/packages/siwe-parser/README.md Instantiate ParsedMessage with a raw SIWE message string. The constructor will throw an error if the message is not EIP-4361 compliant. Access parsed fields like domain, address, etc. ```typescript import { ParsedMessage } from '@signinwithethereum/siwe-parser' const message = new ParsedMessage(rawMessage) console.log(message.domain) console.log(message.address) console.log(message.uri) console.log(message.version) console.log(message.chainId) console.log(message.nonce) console.log(message.issuedAt) ``` -------------------------------- ### generateNonce Function Source: https://github.com/signinwithethereum/siwe/blob/main/packages/siwe/README.md Generates a cryptographically secure random nonce for use in SIWE messages to prevent replay attacks. ```APIDOC ### `generateNonce(): string` Returns a cryptographically secure random nonce (96 bits of entropy, alphanumeric). ```ts import { generateNonce } from '@signinwithethereum/siwe' const nonce = generateNonce() ``` ``` -------------------------------- ### isUri Function Source: https://github.com/signinwithethereum/siwe/blob/main/packages/siwe-parser/README.md Validates if a given string is a valid URI. ```APIDOC ## isUri Function ### Description Validates if a given string is a valid URI. ### Usage ```typescript import { isUri } from '@signinwithethereum/siwe-parser' isUri('https://example.com') // true ``` ``` -------------------------------- ### Validate a URI Source: https://github.com/signinwithethereum/siwe/blob/main/packages/siwe-parser/README.md Use the isUri function to check if a given string is a valid URI. ```typescript import { isUri } from '@signinwithethereum/siwe-parser' isUri('https://example.com') // true ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.