Authentication Guide

This comprehensive guide covers the complete authentication system for the radFi backend API, including JWT tokens, BIP322 signature verification, error handling, and frontend integration.

Overview

The authentication system uses BIP322 signature verification combined with JWT tokens to provide secure, stateless authentication. Users authenticate by signing a message with their Bitcoin wallet, and the system returns JWT access and refresh tokens for subsequent API calls.

Key Features

  • BIP322 Signature Verification: Users sign messages with their Bitcoin wallet

  • JWT Token System: Access tokens (10 minutes) and refresh tokens (7 days)

  • Stateless Authentication: No server-side session storage required

  • Comprehensive Error Handling: 8 specific error codes for different failure scenarios

  • Wallet Integration: Automatic wallet creation during authentication

Authentication Flow

1

User Authentication (Initial)

Frontend signs a message with BIP322 and sends the signature and related data to the backend. The backend verifies the BIP322 signature, creates or finds the wallet, generates JWT access and refresh tokens, and returns them to the client.

Request sent from client to API:

  • POST /api/auth/authenticate with body:

    • message

    • signature

    • address

    • publicKey

Response includes:

  • accessToken (expires in 10 minutes)

  • refreshToken (expires in 7 days)

  • tradingAddress

  • wallet object

2

Protected API Calls

For protected endpoints, the frontend includes the access token in the Authorization header:

Authorization: Bearer

The backend validates the JWT and, if valid, processes the request (e.g., creating transactions).

3

Token Refresh (When Access Token Expires)

When the access token expires, the client sends the refresh token to obtain a new access token:

  • POST /api/auth/refresh-token with body:

    • refreshToken

On success, the backend returns a new accessToken (and wallet info).

API Endpoints

Public Endpoints (No Authentication Required)

Method
Endpoint
Description

POST

/api/auth/authenticate

Initial authentication with BIP322 signature

POST

/api/auth/refresh-token

Refresh expired access token

POST

/api/wallets

Create new wallet

GET

/api/wallets

List wallets

GET

/api/wallets/details/:id

Get wallet details

Protected Endpoints (JWT Required)

Method
Endpoint
Description

POST

/api/transactions

Create transaction

POST

/api/transactions/sign

Sign transaction

POST

/api/etch/commit-tx

POST

/api/etch/submit-etching

Submit rune etching

POST

/api/etch/build-get-reward-tx

POST

/api/etch/sign-reward-tx

POST

/api/diamond-hand/request-claim-rewards

Claim diamond hand rewards

POST

/api/diamond-hand/sign

POST

/api/vm-transactions

Create VM transaction

POST

/api/vm-transactions/sign

Create VM transaction

POST

/api/refunds

Create refund

POST

/api/refunds/sign

Create refund

Error Codes

Error Code Structure

All authentication errors follow the pattern 4xxx where:

  • 4 indicates authentication/authorization errors

  • xxx is a sequential number for specific error types

Error Response Format

Error Codes Reference

Code
Error Type
Description
HTTP Status

4002

Invalid Token

JWT token is malformed or cannot be parsed

401 Unauthorized

4003

Token Expired

JWT token has passed its expiration time

401 Unauthorized

4004

Token Not Found

No Authorization header or Bearer token provided

401 Unauthorized

4005

Invalid Refresh Token

Refresh token is invalid, expired, or wrong type

400 Bad Request

4006

User Not Found

JWT is valid but user doesn't exist in database

401 Unauthorized

4007

Signature Verification Failed

BIP322 signature verification process fails

400 Bad Request

4008

Wallet Creation Failed

Wallet creation fails during authentication

400 Bad Request

4009

Invalid Standard Taproot Address

Address doesn't match expected taproot format

400 Bad Request

Detailed Error Descriptions

4002 - Invalid Token

  • Message: auth.invalidToken

  • Details: Invalid or malformed JWT token

  • When: JWT token is malformed or cannot be parsed

  • HTTP Status: 401 Unauthorized

4003 - Token Expired

  • Message: auth.tokenExpired

  • Details: JWT token has expired

  • When: JWT token has passed its expiration time

  • HTTP Status: 401 Unauthorized

4004 - Token Not Found

  • Message: auth.tokenNotFound

  • Details: JWT token not provided in request

  • When: No Authorization header or Bearer token provided

  • HTTP Status: 401 Unauthorized

4005 - Invalid Refresh Token

  • Message: auth.invalidRefreshToken

  • Details: Invalid or expired refresh token

  • When: Refresh token is invalid, expired, or wrong type

  • HTTP Status: 400 Bad Request

4006 - User Not Found

  • Message: auth.userNotFound

  • Details: User not found for the provided token

  • When: JWT is valid but user doesn't exist in database

  • HTTP Status: 401 Unauthorized

4007 - Signature Verification Failed

  • Message: auth.signatureVerificationFailed

  • Details: BIP322 signature verification failed

  • When: BIP322 signature verification process fails

  • HTTP Status: 400 Bad Request

4008 - Wallet Creation Failed

  • Message: auth.walletCreationFailed

  • Details: Failed to create wallet during authentication

  • When: Wallet creation fails during authentication process

  • HTTP Status: 400 Bad Request

4009 - Invalid Standard Taproot Address

  • Message: auth.invalidStandardTaprootAddress

  • Details: Address is not a valid standard taproot address

  • When: Address doesn't match the expected taproot format

  • HTTP Status: 400 Bad Request

Frontend Implementation

Header Format

All protected API calls require the following header:

Authentication APIs

API: Initial Authentication

Endpoint: POST /api/auth/authenticate Purpose: Get initial JWT tokens after BIP322 signature verification

Request Body example:

Response (Success 200) example:

Response (Error 400) example:

API: Refresh Access Token

Endpoint: POST /api/auth/refresh-token Purpose: Get new access token when current one expires

Request Body example:

Response (Success 200) example:

Response (Error 400) example:

cURL Examples

Testing

Test Scripts

Use the provided test scripts to verify the authentication system:

Test Coverage

The test suite covers:

  • ✅ Authentication endpoint functionality

  • ✅ JWT token validation

  • ✅ Protected API access

  • ✅ Error code verification

  • ✅ Token refresh functionality

  • ✅ Multiple authentication scenarios

Reference Tables

Endpoint Summary

Category
Endpoint
Auth Required
Description

Auth

POST /api/auth/authenticate

No

Initial authentication

Auth

POST /api/auth/refresh-token

No

Refresh access token

Wallet

POST /api/wallets

No

Create wallet

Wallet

GET /api/wallets

No

List wallets

Wallet

GET /api/wallets/details/:id

No

Wallet details

Diamond Hand

POST /api/diamond-hand/request-claim-rewards

Yes

Claim rewards

Transaction

POST /api/transactions

Yes

Create transaction

Transaction

POST /api/transactions/sign

Yes

Sign transaction

VM Transaction

POST /api/vm-transactions

Yes

Create VM transaction

Refund

POST /api/refunds

Yes

Create refund

Etch

POST /api/etch/submit-etching

Yes

Submit rune etching

Error Code Quick Reference

Code
Type
HTTP Status
Action

4002

Invalid Token

401

Redirect to login

4003

Token Expired

401

Refresh token

4004

Token Not Found

401

Redirect to login

4005

Invalid Refresh Token

400

Redirect to login

4006

User Not Found

401

Redirect to login

4007

Signature Verification Failed

400

Show error message

4008

Wallet Creation Failed

400

Show error message

4009

Invalid Taproot Address

400

Show error message

Token Lifecycle

Token Type
Expiration
Purpose
Storage

Access Token

10 minutes

API authentication

localStorage

Refresh Token

7 days

Token renewal

localStorage

Summary

The authentication system provides:

  • 8 specific error codes covering all major authentication failure scenarios

  • JWT Token Issues: 4002, 4003, 4004, 4005, 4006

  • Signature Verification: 4007

  • Wallet Operations: 4008, 4009

All error codes are actively used in the codebase and provide clear, actionable feedback for both developers and end users. The system is designed to be secure, stateless, and easy to integrate with frontend applications.

Last updated