Skip to content

B2B — Wallet Provisioning & User Management

These endpoints are authenticated with your API Key (X-API-Key header).
Base URL: https://rach-caas-api-dx75yvdhaq-nw.a.run.app


Provision User SCW Address

Creates a non-custodial ERC-4337 Smart Contract Wallet (SCW) for a customer. The wallet address is derived offline using a deterministic cryptographic salt tied to the customer's phone number — no gas, no blockchain transaction is required at this stage.

Safe to call multiple times: returns ALREADY_EXISTS with the same wallet address if the customer already has a wallet.

POST /v1/users/provision

Request

http
POST /v1/users/provision
X-API-Key: rach_sk_live_xxxxxxxxxxxxxxxx
Content-Type: application/json

{
  "phone_number": "+2250700000001"
}
FieldTypeRequiredDescription
phone_numberstringCustomer's phone number in E.164 format (e.g. +2250700000001)

Response 200 OK

json
{
  "wallet_address": "0xA1b2c3d4e5f6...",
  "blind_index": "3f8a1c...",
  "status": "CREATED",
  "created_at": "2026-06-25T12:00:00Z"
}
FieldDescription
wallet_addressThe customer's deterministic Polygon SCW address
blind_indexOpaque privacy-preserving reference to this user (used in dashboard APIs)
statusCREATED or ALREADY_EXISTS

Error Codes

StatusMeaning
400Invalid phone number format (must be E.164)
401Invalid or missing API key
500Factory address computation failed

Get Customer USDC Balance

Returns the live on-chain USDC balance for a customer's SCW, read directly from Polygon via eth_call. No caching — always reflects settled state.

GET /v1/users/balance?phone_number={phone}

Request

http
GET /v1/users/balance?phone_number=%2B2250700000001
X-API-Key: rach_sk_live_xxxxxxxxxxxxxxxx

URL-encode the + sign as %2B in query strings.

ParameterTypeRequiredDescription
phone_numberstring (query)Customer E.164 phone (URL-encoded)

Response 200 OK

json
{
  "wallet_address": "0xA1b2c3d4e5f6...",
  "balance_usdc": "12.500000"
}

Error Codes

StatusMeaning
400Missing phone_number parameter
401Invalid or missing API key
404Wallet not provisioned for this phone number

Fund Customer SCW (On-Ramp)

Credits a customer's SCW with USDC on Polygon PoS by triggering an ERC-20 transfer from the Rach treasury EOA. Debits your internal USDC balance atomically. Returns 402 if your treasury balance is insufficient.

Idempotent: supply a stable deposit_id to safely retry without double-crediting.

POST /v1/users/fund

Request

http
POST /v1/users/fund
X-API-Key: rach_sk_live_xxxxxxxxxxxxxxxx
Content-Type: application/json

{
  "phone_number": "+2250700000001",
  "deposit_id": "dep_001_20240601",
  "local_fiat_amount": "11000.00",
  "stablecoin_amount": "19.62",
  "target_token": "USDC"
}
FieldTypeRequiredDescription
phone_numberstringCustomer E.164 phone number
deposit_idstringYour unique idempotency key for this deposit (e.g. dep_001_20240601)
local_fiat_amountstringOriginal fiat amount collected (e.g. "11000.00")
stablecoin_amountstringUSDC amount to credit (e.g. "19.62")
target_tokenstring"USDC" or "USDT"

Response 202 Accepted

json
{
  "deposit_id": "dep_001_20240601",
  "status": "QUEUED",
  "message": "Deposit queued for on-chain settlement",
  "created_at": "2026-06-25T12:05:00Z"
}

Status progresses: QUEUEDSETTLED

Error Codes

StatusMeaning
400Invalid payload or missing fields
401Invalid or missing API key
402Insufficient tenant USDC balance — top up via /v1/dashboard/treasury/topup
404Customer wallet not provisioned — call /v1/users/provision first
409Duplicate deposit_id — already processed

Initiate Off-Ramp Withdrawal

Sweeps USDC from a customer's SCW back to the Rach treasury via an ERC-4337 UserOperation. Once USDC is confirmed on-chain (CRYPTO_RECEIVED), Rach disburses local fiat to the customer via the specified mobile money network.

POST /v1/users/withdraw

Request

http
POST /v1/users/withdraw
X-API-Key: rach_sk_live_xxxxxxxxxxxxxxxx
Content-Type: application/json

{
  "phone": "+2250700000002",
  "amount": "0.500000",
  "token": "USDC",
  "payout_mobile": "+2250700000002",
  "payout_network": "orange_money",
  "idempotency_key": "wdrl_ref_001"
}
FieldTypeRequiredDescription
phonestringCustomer E.164 phone number (SCW owner)
amountstringUSDC amount to withdraw (e.g. "0.500000")
payout_mobilestringMobile number for local fiat disbursement
payout_networkstringMobile money network (e.g. orange_money, wave, mtn_momo)
tokenstringDefaults to "USDC"
idempotency_keystringRecommended for safe retries

Response 202 Accepted

json
{
  "withdrawal_id": "wdrl_abc123",
  "status": "PENDING",
  "message": "Withdrawal initiated. USDC sweep submitted on-chain."
}

Withdrawal lifecycle: PENDINGSUBMITTEDCRYPTO_RECEIVEDCOMPLETED

Monitor progress: GET /v1/dashboard/withdrawals/{id}

Error Codes

StatusMeaning
400Invalid payload or phone format
401Invalid or missing API key
404Customer wallet not found
500Failed to create withdrawal record or enqueue task

Update Customer Phone Number

Migrates a customer's identity to a new phone number while preserving their exact SCW address, on-chain USDC balance, and full transaction history. Use when a customer loses their SIM or changes their number.

Only the phone lookup index is updated — the wallet address is immutable.

POST /v1/users/update-phone

Request

http
POST /v1/users/update-phone
X-API-Key: rach_sk_live_xxxxxxxxxxxxxxxx
Content-Type: application/json

{
  "old_phone_number": "+2250700000001",
  "new_phone_number": "+2250700000099"
}
FieldTypeRequiredDescription
old_phone_numberstringExisting registered phone number
new_phone_numberstringNew phone number to map to the same SCW

Response 200 OK

Returns the same schema as Provision User SCW, with the existing wallet_address and updated blind_index.

Error Codes

StatusMeaning
400Invalid phone format (must be E.164)
401Invalid or missing API key
404Original phone number not found
409New phone number already registered to another wallet

Rach Payments API