Conway

Authentication

Authenticate with Conway Domains using Sign-In with Ethereum (SIWE) or Sign-In with Solana (SIWS).

Conway Domains uses wallet-based authentication. There are no usernames, passwords, or API keys. You authenticate by signing a message with your Ethereum or Solana wallet, and receive a JWT for subsequent requests.

Sign-In with Ethereum (SIWE)

1. Get a Nonce

curl -X POST https://domain.conway.tech/auth/nonce
{ "nonce": "a1b2c3d4e5f6" }

Nonces expire after 5 minutes.

2. Sign and Verify

Construct a SIWE message with the nonce, sign it with your wallet, and submit:

curl -X POST https://domain.conway.tech/auth/verify \
  -H "Content-Type: application/json" \
  -d '{
    "message": "<SIWE message string>",
    "signature": "0x..."
  }'
{
  "access_token": "eyJ...",
  "refresh_token": "eyJ..."
}

3. Use the Access Token

Include the access token in the Authorization header for all authenticated requests:

curl https://domain.conway.tech/domains \
  -H "Authorization: Bearer eyJ..."

4. Refresh

Access tokens are short-lived. Use the refresh token to get a new one:

curl -X POST https://domain.conway.tech/auth/refresh \
  -H "Content-Type: application/json" \
  -d '{ "refresh_token": "eyJ..." }'
{ "access_token": "eyJ..." }

Sign-In with Solana (SIWS)

The same flow is available for Solana wallets at /auth/solana/:

# Get nonce
curl -X POST https://domain.conway.tech/auth/solana/nonce

# Verify signature
curl -X POST https://domain.conway.tech/auth/solana/verify \
  -H "Content-Type: application/json" \
  -d '{ "message": "<SIWS message>", "signature": "..." }'

Returns the same access_token and refresh_token format.

Get Current User

curl https://domain.conway.tech/auth/me \
  -H "Authorization: Bearer eyJ..."
{
  "id": "usr_abc123",
  "wallet_address": "0x...",
  "wallet_type": "evm",
  "email": null,
  "name": null,
  "role": "user"
}

Payment Wallet Matching

When making x402 payments (domain registration, renewal), the payment signer must match the authenticated wallet address. The API verifies this on every paid request to prevent one wallet from paying on behalf of another.