Authentication
x402 uses wallet-native authentication — no passwords, no API keys. Identity is established by signing a message with your wallet private key.
Supported Standards
| Standard | Chain | Status |
|---|---|---|
| SIWE — Sign-In with Ethereum | EVM chains | Available |
| SIWC — Sign-In with Cosmos | Cosmos chains | Available |
| SIWS — Sign-In with Solana | Solana | Coming soon |
How It Works
1. Request a Nonce
Start by requesting a one-time nonce tied to your wallet address. This prevents replay attacks.
GET /auth/nonce?address=0xYourAddress{
"nonce": "f3a1b8c9d2e4",
"expires_in": 300
}2. Sign the Message
Construct a sign-in message and sign it with your wallet:
x402 Gateway wants you to sign in.
Address: 0xYourAddress
Nonce: f3a1b8c9d2e4
Issued At: 2024-06-01T12:00:00ZMost wallet libraries provide a signMessage or personal_sign method:
// Ethereum (ethers.js)
const signature = await signer.signMessage(message);
// Cosmos (cosmjs)
const { signature } = await client.signArbitrary(chainId, address, message);3. Exchange for a JWT
Send the signed message to the login endpoint:
POST /auth/login
Content-Type: application/json
{
"address": "0xYourAddress",
"signature": "0x4a3b...",
"message": "x402 Gateway wants you to sign in.\n\nAddress: 0x...",
"chain": "ethereum"
}Response:
{
"token": "eyJhbGciOiJIUzI1NiJ9...",
"refresh_token": "dGhpcyBpcyBhIHJlZnJlc2g...",
"expires_at": "2024-06-01T13:00:00Z"
}4. Use the JWT
Include the JWT in the Authorization header for all API requests:
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...Token Refresh
JWTs expire after 1 hour. Use your refresh token to get a new one without re-signing:
POST /auth/refresh
Content-Type: application/json
{
"refresh_token": "dGhpcyBpcyBhIHJlZnJlc2g..."
}{
"token": "eyJhbGciOiJIUzI1NiJ9...",
"expires_at": "2024-06-01T14:00:00Z"
}INFO
Refresh tokens are single-use — a new refresh token is issued with each refresh response.
Token Revocation
Log out by revoking your token:
POST /auth/logout
Authorization: Bearer <your-token>All active tokens for the session are invalidated immediately.
Error Responses
| Status | Code | Description |
|---|---|---|
401 | INVALID_SIGNATURE | Signature does not match the address |
401 | EXPIRED_NONCE | Nonce has expired, request a new one |
401 | INVALID_TOKEN | JWT is invalid or malformed |
401 | EXPIRED_TOKEN | JWT has expired, refresh or re-login |
403 | REVOKED_TOKEN | Token has been revoked |
Security Considerations
- Nonces expire after 5 minutes — request one just before signing
- Refresh tokens are single-use and invalidated after use
- All tokens are invalidated on logout
- Never expose your JWT in client-side code or URLs
- The gateway never stores or has access to your private key