Auth
Authenticates a user by verifying their BIP322 signature and creates a wallet with JWT tokens
The message that was signed
Sign this message to authenticate with the systemThe BIP322 signature of the message
base64-encoded-signatureThe Bitcoin address that signed the message
bc1p...The public key used for signing
02a1b2c3d4e5f6...User authenticated successfully
1common.successInvalid signature, invalid address, or authentication failed
POST /api/auth/authenticate HTTP/1.1
Host: api.bound.exchange
Content-Type: application/json
Accept: */*
Content-Length: 154
{
"message": "Sign this message to authenticate with the system",
"signature": "base64-encoded-signature",
"address": "bc1p...",
"publicKey": "02a1b2c3d4e5f6..."
}{
"code": "1",
"message": "common.success",
"data": {},
"metaData": {
"totalItems": 1,
"currentPage": 1,
"pageSize": 1,
"totalPages": 1
}
}Refresh token to generate new access token
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...New access token and rotated refresh token generated successfully
No content
Invalid or expired refresh token
POST /api/auth/refresh-token HTTP/1.1
Host: api.bound.exchange
Content-Type: application/json
Accept: */*
Content-Length: 58
{
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}No content
Email address to send OTP to
OTP queued
No content
Email already registered
Rate limit exceeded
POST /api/auth/email-verification/request HTTP/1.1
Host: api.bound.exchange
Content-Type: application/json
Accept: */*
Content-Length: 16
{
"email": "text"
}No content
Required for SRP. Optional for passkey/wallet; validated when present.
Email OTP. Required whenever an email is supplied (any authType).
Referral code (base64url-encoded referrer accountId). Throws if invalid.
Account registered successfully
No content
POST /api/auth/register HTTP/1.1
Host: api.bound.exchange
Content-Type: application/json
Accept: */*
Content-Length: 728
{
"email": "text",
"otp": "text",
"authType": "passkey",
"passkey": {
"challengeId": "text",
"credentialId": "text",
"webauthnPublicKey": "text",
"attestation": "text",
"clientDataJson": "text",
"authenticatorData": "text",
"encryptedBlob": "text",
"deviceName": "text"
},
"srpData": {
"srpSalt": "text",
"srpVerifier": "text",
"encryptedBlob": "text",
"passwordHint": "text"
},
"walletAuth": {
"address": "text",
"chain": "evm",
"publicKey": "text",
"provider": "text",
"challengeId": "text",
"signature": "text",
"encryptedBlob": "text"
},
"wallets": {
"btc": {
"publicKey": "text",
"address": "text",
"message": "text",
"signature": "text"
},
"evm": {
"publicKey": "text",
"message": "text",
"signature": "text"
},
"sol": {
"publicKey": "text",
"message": "text",
"signature": "text"
}
},
"referralCode": "text"
}Account registered successfully
No content
Login successful
No content
POST /api/auth/passkey/login HTTP/1.1
Host: api.bound.exchange
Content-Type: application/json
Accept: */*
Content-Length: 136
{
"credentialId": "text",
"challengeId": "text",
"webauthnAssertion": {
"authenticatorData": "text",
"clientDataJson": "text",
"signature": "text"
}
}Login successful
No content
Client sends email. Server returns salt and serverPublic (B) for SRP-6a authentication.
Account email
Returns sessionId, salt, and serverPublic (B)
No content
POST /api/auth/srp/init HTTP/1.1
Host: api.bound.exchange
Content-Type: application/json
Accept: */*
Content-Length: 16
{
"email": "text"
}Returns sessionId, salt, and serverPublic (B)
No content
Logged out successfully
No content
POST /api/auth/logout HTTP/1.1
Host: api.bound.exchange
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
Logged out successfully
No content
Client sends clientPublic (A) and clientProof (M1). Server verifies and returns serverProof (M2) plus tokens.
Session ID returned by srp/init
Client ephemeral public key A = g^a mod N (base64)
Client proof M1 = H(H(N)⊕H(g) || H(I) || salt || A || B || K) (base64)
Login successful — returns serverProof, tokens, and encryptedBlob
No content
POST /api/auth/srp/verify HTTP/1.1
Host: api.bound.exchange
Content-Type: application/json
Accept: */*
Content-Length: 63
{
"sessionId": "text",
"clientPublic": "text",
"clientProof": "text"
}Login successful — returns serverProof, tokens, and encryptedBlob
No content
Auth wallet address to issue a login nonce for
Returns challengeId, challenge (nonce), expiresAt
No content
GET /api/auth/wallet/challenge?address=text HTTP/1.1
Host: api.bound.exchange
Accept: */*
Returns challengeId, challenge (nonce), expiresAt
No content
Registered auth wallet address
challengeId from GET /auth/wallet/challenge
Wallet signature over the issued server nonce
Login successful — tokens, encryptedBlob, account, wallets
No content
POST /api/auth/wallet/login HTTP/1.1
Host: api.bound.exchange
Content-Type: application/json
Accept: */*
Content-Length: 58
{
"address": "text",
"challengeId": "text",
"signature": "text"
}Login successful — tokens, encryptedBlob, account, wallets
No content
Accepts the pendingToken returned by srp/verify when 2FA is enabled, plus the current TOTP code. Returns the full login response.
OTP verified — returns accessToken, refreshToken, encryptedBlob, account, wallets
No content
Invalid or expired pendingToken, or wrong OTP code
POST /api/auth/2fa/verify HTTP/1.1
Host: api.bound.exchange
Content-Type: application/json
Accept: */*
Content-Length: 2
{}No content
Last updated