For the complete documentation index, see llms.txt. This page is also available as Markdown.

Auth

Authenticate user with BIP322 signature verification

post

Authenticates a user by verifying their BIP322 signature and creates a wallet with JWT tokens

Body
messagestringRequired

The message that was signed

Example: Sign this message to authenticate with the system
signaturestringRequired

The BIP322 signature of the message

Example: base64-encoded-signature
addressstringRequired

The Bitcoin address that signed the message

Example: bc1p...
publicKeystringRequired

The public key used for signing

Example: 02a1b2c3d4e5f6...
Responses
200

User authenticated successfully

application/json
codestringRequiredExample: 1
messagestringRequiredExample: common.success
dataobjectRequired
post/api/auth/authenticate
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 access token using refresh token

post
Body
refreshTokenstringRequired

Refresh token to generate new access token

Example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Responses
200

New access token and rotated refresh token generated successfully

No content

post/api/auth/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

Get WebAuthn challenge for passkey registration or login

get
Responses
200Success

No content

get/api/auth/webauthn/challenge
GET /api/auth/webauthn/challenge HTTP/1.1
Host: api.bound.exchange
Accept: */*
200Success

No content

Request email OTP for registration — sends a 6-digit code to the given email address

post
Body
emailstringRequired

Email address to send OTP to

Responses
200

OTP queued

No content

post/api/auth/email-verification/request
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

Register a new bound wallet account

post
Body
emailstringOptional

Required for SRP. Optional for passkey/wallet; validated when present.

otpstringOptional

Email OTP. Required whenever an email is supplied (any authType).

authTypestring · enumRequiredPossible values:
referralCodestringOptional

Referral code (base64url-encoded referrer accountId). Throws if invalid.

Responses
201

Account registered successfully

No content

post/api/auth/register
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"
}
201

Account registered successfully

No content

Login with passkey or password

post
Body
credentialIdstringRequired
challengeIdstringRequired
Responses
200

Login successful

No content

post/api/auth/passkey/login
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"
  }
}
200

Login successful

No content

SRP step 1 — get salt and server public key

post

Client sends email. Server returns salt and serverPublic (B) for SRP-6a authentication.

Body
emailstringRequired

Account email

Responses
200

Returns sessionId, salt, and serverPublic (B)

No content

post/api/auth/srp/init
POST /api/auth/srp/init HTTP/1.1
Host: api.bound.exchange
Content-Type: application/json
Accept: */*
Content-Length: 16

{
  "email": "text"
}
200

Returns sessionId, salt, and serverPublic (B)

No content

Logout — revoke current session and refresh token

post
Authorizations
AuthorizationstringRequired
Bearer authentication header of the form Bearer <token>.
Responses
200

Logged out successfully

No content

post/api/auth/logout
POST /api/auth/logout HTTP/1.1
Host: api.bound.exchange
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
200

Logged out successfully

No content

SRP step 2 — verify client proof and complete login

post

Client sends clientPublic (A) and clientProof (M1). Server verifies and returns serverProof (M2) plus tokens.

Body
sessionIdstringRequired

Session ID returned by srp/init

clientPublicstringRequired

Client ephemeral public key A = g^a mod N (base64)

clientProofstringRequired

Client proof M1 = H(H(N)⊕H(g) || H(I) || salt || A || B || K) (base64)

Responses
200

Login successful — returns serverProof, tokens, and encryptedBlob

No content

post/api/auth/srp/verify
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"
}
200

Login successful — returns serverProof, tokens, and encryptedBlob

No content

Wallet auth — issue a fresh login nonce for an auth wallet address

get
Query parameters
addressstringRequired

Auth wallet address to issue a login nonce for

Responses
200

Returns challengeId, challenge (nonce), expiresAt

No content

get/api/auth/wallet/challenge
GET /api/auth/wallet/challenge?address=text HTTP/1.1
Host: api.bound.exchange
Accept: */*
200

Returns challengeId, challenge (nonce), expiresAt

No content

Wallet auth — log in by signing the issued nonce

post
Body
addressstringRequired

Registered auth wallet address

challengeIdstringRequired

challengeId from GET /auth/wallet/challenge

signaturestringRequired

Wallet signature over the issued server nonce

Responses
200

Login successful — tokens, encryptedBlob, account, wallets

No content

post/api/auth/wallet/login
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"
}
200

Login successful — tokens, encryptedBlob, account, wallets

No content

2FA TOTP verify — exchange pending token + OTP code for full JWT pair

post

Accepts the pendingToken returned by srp/verify when 2FA is enabled, plus the current TOTP code. Returns the full login response.

Body
object · TotpVerifyDtoOptional
Responses
200

OTP verified — returns accessToken, refreshToken, encryptedBlob, account, wallets

No content

post/api/auth/2fa/verify
POST /api/auth/2fa/verify HTTP/1.1
Host: api.bound.exchange
Content-Type: application/json
Accept: */*
Content-Length: 2

{}

No content

Last updated