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

# Overview

> Sign-In with Ethereum (EIP-4361) implementation for decentralized authentication

<Card title="Try it Live" icon="play" href="https://playground.tevm.sh?example=primitives/siwe.ts">
  Run SIWE examples in the interactive playground
</Card>

<Tip>
  New to SIWE? Start with [Fundamentals](/primitives/siwe/fundamentals) for guided examples and authentication concepts.
</Tip>

## Type Definition

Sign-In with Ethereum (EIP-4361) implementation for decentralized authentication. Creates structured messages users sign with private keys, proving address ownership without key exposure.

## Authentication Flow

```
┌──────────────┐      ┌─────────────┐      ┌─────────────┐      ┌─────────────┐
│   Frontend   │      │   Wallet    │      │   Backend   │      │   Database  │
└──────────────┘      └─────────────┘      └─────────────┘      └─────────────┘
      │                     │                     │                     │
      │  1. Request Nonce   │                     │                     │
      ├────────────────────────────────────────>  │                     │
      │                     │                     │                     │
      │                     │             Generate nonce │              │
      │                     │             Store for 5min │──────────>  │
      │  2. Get nonce       │                     │                     │
      │  <────────────────────────────────────────┤                     │
      │                     │                     │                     │
      │ 3. Create message   │                     │                     │
      │    with nonce       │                     │                     │
      ├────────────────────>│                     │                     │
      │                     │                     │                     │
      │  4. Sign message    │                     │                     │
      │  <────────────────┤ │                     │                     │
      │                     │ signature           │                     │
      │  5. Verify message  │                     │                     │
      ├────────────────────────────────────────>  │                     │
      │                     │                     │                     │
      │                     │             Check nonce │                │
      │                     │             Verify sig   │──────────>   │
      │                     │             Check valid  │  <──────────┤
      │                     │             Create token │              │
      │  6. Session token   │                     │                     │
      │  <────────────────────────────────────────┤                     │
      │                     │                     │                     │
      └──────────────┘      └─────────────┘      └─────────────┘      └─────────────┘
```

## Message Structure

A SIWE message is a human-readable text format combining user intent with cryptographic proof:

```
example.com wants you to sign in with your Ethereum account:
0x742d35Cc6634C0532925a3b844Bc9e7595f51e3e

Sign in to Example App

URI: https://example.com/login
Version: 1
Chain ID: 1
Nonce: testnonce123
Issued At: 2024-11-06T12:00:00.000Z
Expiration Time: 2024-11-06T13:00:00.000Z
Not Before: 2024-11-06T11:00:00.000Z

Resources:
- https://example.com/api/user
- https://example.com/api/profile
```

Key components:

* **Domain** (RFC 4501): Where the message is being signed for
* **Address**: Which account is signing
* **URI**: What resource is being accessed
* **Statement**: Human-readable context
* **Chain ID**: Which blockchain
* **Nonce**: One-time value, prevents replay attacks
* **Timestamps**: Validity window
* **Resources**: Optional list of what's being granted access to

## Factory

```typescript theme={null}
Siwe(params: MessageParams): Siwe
```

Creates Siwe message instance from parameters.

**Parameters:**

* `params.domain`: RFC 4501 dns authority
* `params.address`: AddressType performing signing
* `params.uri`: RFC 3986 URI
* `params.chainId`: EIP-155 Chain ID
* `params.statement?`: Human-readable assertion (optional)
* `params.expirationTime?`: ISO 8601 expiration (optional)
* `params.notBefore?`: ISO 8601 valid-from time (optional)
* `params.requestId?`: System identifier (optional)
* `params.resources?`: Resource URIs (optional)
* `params.nonce?`: Custom nonce (auto-generated if omitted)
* `params.issuedAt?`: Custom timestamp (current time if omitted)

**Returns:** Siwe message instance

## Static Constructors

### Siwe.create(params)

```typescript theme={null}
create(params: MessageParams): BrandedMessage
```

Create message with defaults. Same as factory.

### Siwe.parse(text)

```typescript theme={null}
parse(text: string): BrandedMessage
```

Parse EIP-4361 formatted string to message.

**Throws:** Error if format invalid

## Static Utilities

### Formatting

#### Siwe.format(message)

```typescript theme={null}
format(message: BrandedMessage): string
```

Format message to EIP-4361 string for signing.

### Validation

#### Siwe.validate(message, options?)

```typescript theme={null}
validate(message: BrandedMessage, options?: { now?: Date }): ValidationResult
```

Validate message structure and timestamps.

**Returns:** `{ valid: true }` or `{ valid: false, error: ValidationError }`

### Signing & Verification

#### Siwe.getMessageHash(message)

```typescript theme={null}
getMessageHash(message: BrandedMessage): Uint8Array
```

Get EIP-191 personal sign message hash (32 bytes).

#### Siwe.verify(message, signature)

```typescript theme={null}
verify(message: BrandedMessage, signature: Signature): boolean
```

Verify signature matches message address.

**Parameters:**

* `signature`: 65-byte signature (r + s + v)

**Returns:** true if valid

#### Siwe.verifyMessage(message, signature, options?)

```typescript theme={null}
verifyMessage(message: BrandedMessage, signature: Signature, options?: { now?: Date }): ValidationResult
```

Combined validation and verification.

### Nonce Generation

#### Siwe.generateNonce(length?)

```typescript theme={null}
generateNonce(length?: number): string
```

Generate cryptographically secure random nonce.

**Parameters:**

* `length`: Nonce length (default 11, min 8)

**Returns:** Base62 alphanumeric string

## Instance Methods

All static utilities available as instance methods:

```typescript theme={null}
const message = Siwe.create({
  domain: "example.com",
  address: userAddress,
  uri: "https://example.com",
  chainId: 1,
});

message.format()           // string
message.validate()         // ValidationResult
message.getMessageHash()   // Uint8Array
message.verify(signature)  // boolean
```

Instance methods delegate to BrandedSiwe namespace functions.

## Types

```typescript theme={null}
type BrandedMessage = {
  domain: string;
  address: AddressType;
  uri: string;
  version: string;
  chainId: number;
  nonce: string;
  issuedAt: string;
  statement?: string;
  expirationTime?: string;
  notBefore?: string;
  requestId?: string;
  resources?: string[];
}

type Signature = Uint8Array;  // 65 bytes: r (32) + s (32) + v (1)

type ValidationResult =
  | { valid: true }
  | { valid: false; error: ValidationError };

type ValidationError =
  | { type: "invalid_domain"; message: string }
  | { type: "invalid_address"; message: string }
  | { type: "invalid_uri"; message: string }
  | { type: "invalid_version"; message: string }
  | { type: "invalid_chain_id"; message: string }
  | { type: "invalid_nonce"; message: string }
  | { type: "invalid_timestamp"; message: string }
  | { type: "expired"; message: string }
  | { type: "not_yet_valid"; message: string }
  | { type: "signature_mismatch"; message: string };
```

See [BrandedSiwe](/primitives/siwe/branded-siwe) for branded type details.

## Implementation

* Delegates to BrandedSiwe namespace
* Extends Object.prototype
* Structured message format per EIP-4361
* Supports optional fields via conditional spreading

## Quick Start

```typescript theme={null}
import { Siwe, Address } from 'tevm';

// Create message
const message = Siwe.create({
  domain: "example.com",
  address: Address("0x..."),
  uri: "https://example.com/login",
  chainId: 1,
  statement: "Sign in to Example App",
});

// Format for wallet signing
const text = message.format();

// User signs with wallet
const signature = await wallet.signMessage(text);

// Validate and verify
const result = Siwe.verifyMessage(message, signature);
if (result.valid) {
  // Authenticated
}
```

## Common Patterns

### Authentication Flow

```typescript theme={null}
// Backend: Generate nonce
const nonce = Siwe.generateNonce();
storeNonce(userId, nonce);

// Frontend: Create and sign message
const message = Siwe.create({
  domain: window.location.host,
  address: userAddress,
  uri: window.location.origin,
  chainId: await provider.getChainId(),
  nonce,
});
const signature = await wallet.signMessage(message.format());

// Backend: Verify
const parsed = Siwe.parse(messageText);
const result = Siwe.verifyMessage(parsed, signature);
if (result.valid && verifyNonce(parsed.nonce)) {
  createSession(parsed.address);
}
```

### Session Management

```typescript theme={null}
const message = Siwe.create({
  domain: "example.com",
  address: userAddress,
  uri: "https://example.com",
  chainId: 1,
  expirationTime: new Date(Date.now() + 3600000).toISOString(),
});

// Validate at session use
const result = message.validate({ now: new Date() });
if (!result.valid) {
  requestReauth();
}
```

## API Documentation

### Constructors

Creating SIWE messages from parameters or text.

[View constructors →](/primitives/siwe/constructors)

### Parsing

Parse EIP-4361 formatted strings to message objects.

[View parsing →](/primitives/siwe/parsing)

### Validation

Validate message structure and timestamps.

[View validation →](/primitives/siwe/validation)

### Signing & Verification

Create hashes and verify signatures with addresses.

[View signing →](/primitives/siwe/signing)

### Utilities

Nonce generation and helper functions.

[View utilities →](/primitives/siwe/utilities)

### Usage Patterns

Real-world authentication and session patterns.

[View patterns →](/primitives/siwe/usage-patterns)

## Quick Reference: Security Checklist

<Tip>
  Always Verify:

  * Domain matches request origin
  * Nonce is fresh and single-use
  * Signature is valid
  * Message not expired
  * Address matches session
  * HTTPS in production
</Tip>

## Related Types

* [Siwe (Effect)](https://voltaire-effect.tevm.sh/primitives/siwe) - Effect.ts integration with Schema validation
* [Address](/primitives/address) - 20-byte Ethereum addresses used in messages
* [Signature](/primitives/signature) - 65-byte signatures (r + s + v) for verification
* [Keccak256](/crypto/keccak256) - 32-byte hashes from message signing

## References

* [EIP-4361: Sign-In with Ethereum](https://eips.ethereum.org/EIPS/eip-4361)
* [EIP-191: Signed Data Standard](https://eips.ethereum.org/EIPS/eip-191)
* [Constructors](/primitives/siwe/constructors)
* [Parsing](/primitives/siwe/parsing)
* [Validation](/primitives/siwe/validation)
* [Signing](/primitives/siwe/signing)
* [Verification](/primitives/siwe/verification)
* [Utilities](/primitives/siwe/utilities)
* [Usage Patterns](/primitives/siwe/usage-patterns)
* [WASM](/primitives/siwe/wasm)
