BRNX Web — Frontend Architecture

Stack: React 18 · React Router v6 · Redux Toolkit · Axios · Tailwind CSS · react-hot-toast Base API URL: https://beta-brnx-api.borderless.world Auth storage: sessionStorage (keys: brnx_access_token, brnx_refresh_token, brnx_status, brnx_country, brnx_email, brnx_user_name, brnx_quote_permissions)


1. High-Level Architecture

[Diagram]

2. Application Entry Flow

[Diagram]

3. Authentication & Token Flow

[Diagram]

3a. Silent Token Refresh (401 Interceptor)

[Diagram]

4. Route Guard Decision Tree

[Diagram]

5. Receiver User Journey

[Diagram]

6. Sender User Journey

[Diagram]

7. KYB Onboarding Flow

[Diagram]

8. API Call Mapping — Page by Page

Auth Pages

Page Trigger API Function Method Endpoint
Login.jsx Form submit loginUser POST /web/v1/auth/login
Login.jsx After login getUserFeaturePermissions GET /web/v1/role-feature-mappings/user/:userId
Login.jsx After login getUser GET /web/v1/user/get/:userId
ForgotPassword.jsx Step 1 send OTP sendOtp POST /web/v1/auth/send-otp
ForgotPassword.jsx Step 2 reset forgotPasswordSubmit POST /web/v1/auth/forgot-password
SetPassword.jsx Form submit setPassword POST /web/v1/auth/change-password
utils/api.js 401 response interceptor POST /web/v1/auth/refresh-token

Onboarding / KYB

Page Trigger API Function Method Endpoint
KYB/index.jsx Country selected getRequiredDocuments GET /web/v1/kyc/required-documents
KYB/index.jsx Each doc upload uploadKycFile POST /web/v1/kyc (multipart)

Receiver Pages

Page Trigger API Function Method Endpoint
Overview.jsx Page load getInvoices GET /web/v1/payment-requests?fromUserId=
Overview.jsx Page load getBanks GET /web/v1/bank?userId=
Overview.jsx Page load listSenders GET /web/v1/user/list?type=sender
AddBank.jsx Form submit createBank POST /web/v1/bank
CreateInvoice.jsx Page load listSenders GET /web/v1/user/list?type=sender
CreateInvoice.jsx File selected uploadInvoiceDocument POST /web/v1/kyc/upload
CreateInvoice.jsx Form submit createInvoice POST /web/v1/payment-requests
InvoiceDetail.jsx Page load getInvoiceById GET /web/v1/payment-requests?id=
Transactions.jsx Page load getTransactions GET /web/v1/transactions
TransactionDetail.jsx Page load getTransactionById GET /web/v1/transactions?transactionId=
Senders.jsx Page load listSenders GET /web/v1/user/list?type=sender
CreateSender.jsx Form submit createUser POST /web/v1/user/create
SenderDetail.jsx Page load getUser GET /web/v1/user/get/:userId
SenderDetail.jsx Page load getSenderInvoices GET /web/v1/payment-requests?toUserId=
Treasury.jsx (Receiver) Page load getVaultBalance GET /web/v1/vault/balance?userId=
Treasury.jsx (Receiver) Page load / filter getVaultLedger GET /web/v1/vault/ledger?userId=&page=&limit=

Sender Pages

Page Trigger API Function Method Endpoint
Invoices.jsx Page load getSenderInvoices GET /web/v1/payment-requests?toUserId=
Invoices.jsx Page load getVaultBalance GET /web/v1/vault/balance?userId=
PayInvoice.jsx Page load getInvoiceById GET /web/v1/payment-requests?id=
PayInvoice.jsx Page load getVaultBalance GET /web/v1/vault/balance?userId=
PayInvoice.jsx Page load getUser receiver GET /web/v1/user/get/:userId
PayInvoice.jsx Page load getBanks receiver GET /web/v1/bank?userId=
PayInvoice.jsx Step 1 seed rate createQuote POST /web/v1/quote
PayInvoice.jsx Confirm wallet path createWalletTransfer POST /web/v1/transactions/wallet-transfer
PayInvoice.jsx Confirm onramp path createTransaction POST /web/v1/transactions
Transactions.jsx Page load getTransactions GET /web/v1/transactions
TransactionDetail.jsx Page load getTransactionById GET /web/v1/transactions?transactionId=
CreateTransaction.jsx Page load listReceivers GET /web/v1/user/list?type=receiver
CreateTransaction.jsx Page load getVaultBalance GET /web/v1/vault/balance?userId=
CreateTransaction.jsx Receiver selected getBanks receiver GET /web/v1/bank?userId=
CreateTransaction.jsx Step 1 quote createQuote POST /web/v1/quote
CreateTransaction.jsx Confirm createTransaction POST /web/v1/transactions
Treasury.jsx (Sender) Page load getVaultBalance GET /web/v1/vault/balance?userId=
Treasury.jsx (Sender) Page load getVaultLedger GET /web/v1/vault/ledger?userId=&page=&limit=
FundWallet.jsx Page load seed rate createQuote POST /web/v1/quote
FundWallet.jsx Amount changed debounced createQuote POST /web/v1/quote
FundWallet.jsx Confirm createTransaction POST /web/v1/transactions
FundWallet.jsx Polling after txn created getTransactionById GET /web/v1/transactions?transactionId=

Account Pages

Page Trigger API Function Method Endpoint
ChangePassword.jsx Step 1 request OTP sendOtp POST /web/v1/auth/send-otp
ChangePassword.jsx Step 2 submit changePassword POST /web/v1/auth/change-password

Shared Components

Component Trigger API Function Method Endpoint
AppShell.jsx Mount if userName missing getUser GET /web/v1/user/get/:userId

9. Complete API Endpoint Reference (30 Endpoints)

# Endpoint Method Used By
1 /web/v1/auth/login POST Login.jsx
2 /web/v1/auth/refresh-token POST utils/api.js interceptor automatic
3 /web/v1/auth/change-password POST SetPassword.jsx, ChangePassword.jsx
4 /web/v1/auth/send-otp POST ForgotPassword.jsx, ChangePassword.jsx
5 /web/v1/auth/verify-otp POST Available in services not wired to UI
6 /web/v1/auth/forgot-password POST ForgotPassword.jsx
7 /web/v1/user/get/:userId GET Login.jsx, AppShell.jsx, SenderDetail.jsx, PayInvoice.jsx
8 /web/v1/user/create POST CreateSender.jsx
9 /web/v1/user/list?type=sender GET Overview.jsx, CreateInvoice.jsx, Senders.jsx
10 /web/v1/user/list?type=receiver GET CreateTransaction.jsx
11 /web/v1/role-feature-mappings/user/:userId GET Login.jsx
12 /web/v1/kyc/required-documents GET KYB/index.jsx
13 /web/v1/kyc POST multipart KYB/index.jsx
14 /web/v1/kyc/upload POST multipart CreateInvoice.jsx
15 /web/v1/kyc/documents GET Available in services not wired to UI
16 /web/v1/supported-currency GET Available in services not wired to UI
17 /web/v1/bank POST AddBank.jsx
18 /web/v1/bank?userId= GET Overview.jsx, PayInvoice.jsx, CreateTransaction.jsx
19 /web/v1/vault/balance?userId= GET Invoices.jsx, Treasury pages, PayInvoice.jsx, CreateTransaction.jsx, FundWallet.jsx
20 /web/v1/vault/ledger?userId= GET Receiver Treasury, Sender Treasury
21 /web/v1/payment-requests?fromUserId= GET Receiver Overview.jsx
22 /web/v1/payment-requests?toUserId= GET Sender Invoices.jsx, Receiver SenderDetail.jsx
23 /web/v1/payment-requests?id= GET PayInvoice.jsx, Receiver InvoiceDetail.jsx
24 /web/v1/payment-requests/details GET InvoiceDocLink.jsx on-demand signed URL
25 /web/v1/payment-requests POST CreateInvoice.jsx
26 /web/v1/quote POST PayInvoice.jsx, CreateTransaction.jsx, FundWallet.jsx
27 /web/v1/transactions GET Receiver/Sender Transactions.jsx
28 /web/v1/transactions?transactionId= GET TransactionDetail.jsx, FundWallet.jsx polling
29 /web/v1/transactions POST PayInvoice.jsx, CreateTransaction.jsx, FundWallet.jsx
30 /web/v1/transactions/wallet-transfer POST PayInvoice.jsx USDC wallet balance sufficient

10. Redux State Shape

[Diagram]

11. Component Hierarchy

[Diagram]

12. Pay Invoice — Detailed Sequence

[Diagram]

13. Data Flow Architecture

[Diagram]

Key Architecture Patterns

[!NOTE] No global data store — all remote data is fetched locally in each page component via useState + useEffect. Only auth state lives in Redux.

[!IMPORTANT] sessionStorage persistence — tab-scoped. All tokens and user metadata are cleared on logout or when the 401 refresh flow fails.

[!TIP] Interceptor pattern in utils/api.js handles token refresh transparently for all authenticated requests. Pages never see 401 errors from expired access tokens.

[!NOTE] Role-based routing — Receiver and Sender have completely separate page trees (/receiver/* vs /sender/*), guarded by RequireRole. They share only Account pages and UI primitives.

[!WARNING] Two unused endpoints in services/api.js (getRequiredDocuments endpoint for KYC documents and getSupportedCurrency) are available but not yet wired to any UI page.