Skip to main content

Try it Live

Run SIWE examples in the interactive playground

Validation

Message structure and timestamp validation.

validate

Validate SIWE message structure and timestamps.

Signature

Parameters

  • message - BrandedMessage to validate
  • options.now - Current time for timestamp checks (defaults to new Date())

Returns

Success: { valid: true } Failure: { valid: false, error: ValidationError } ValidationError types:
  • invalid_domain - Domain empty or missing
  • invalid_address - Address not 20-byte Uint8Array
  • invalid_uri - URI missing
  • invalid_version - Version not “1”
  • invalid_chain_id - Chain ID not positive integer
  • invalid_nonce - Nonce less than 8 characters
  • invalid_timestamp - Timestamp not valid ISO 8601
  • expired - Current time >= expirationTime
  • not_yet_valid - Current time < notBefore

Validation Rules

Domain:
  • Must be non-empty string
  • RFC 4501 dns authority format
Address:
  • Must be Uint8Array instance
  • Exactly 20 bytes length
  • Valid Ethereum address format
URI:
  • Must be non-empty string
  • RFC 3986 URI format
Version:
  • Must be exactly “1”
  • No other versions supported
Chain ID:
  • Must be positive integer (>= 1)
  • EIP-155 chain identifier
Nonce:
  • Minimum 8 characters
  • Prevents replay attacks
Timestamps:
  • Must be valid ISO 8601 format
  • Parsed with new Date()
  • Checked against options.now or current time
Expiration Check:
  • If expirationTime present: now < expirationTime
  • Returns expired error if past
Not Before Check:
  • If notBefore present: now >= notBefore
  • Returns not_yet_valid error if too early

Example

Error Handling

Timestamp Validation

Check Expiration

Check Not Before

Session Validation

Common Patterns

Pre-Verification Validation

Instance Method

Backend Validation

Clock Skew Handling

Validation Details

Domain Validation:
  • Checks non-empty, non-whitespace
  • Does not validate DNS format (caller responsibility)
Address Validation:
  • Runtime type check: instanceof Uint8Array
  • Length check: length === 20
  • Does not validate checksum
URI Validation:
  • Checks non-empty
  • Does not validate RFC 3986 syntax (caller responsibility)
Version Validation:
  • Strict equality: version === "1"
  • No version coercion
Chain ID Validation:
  • Number.isInteger(chainId)
  • chainId >= 1
  • Rejects floats, negative, zero
Nonce Validation:
  • nonce.length >= 8
  • Does not validate character set
  • Server must verify uniqueness
Timestamp Validation:
  • ISO 8601 format via new Date()
  • Checks isNaN(date.getTime())
  • Time comparisons use >= and <

Performance

  • O(1) complexity
  • No crypto operations
  • Fast structure checks
  • Ideal for pre-filtering before expensive verification

See Also