Wallet-as-a-Service (WaaS) Integration Guide
This guide details how to integrate with the Rach Finance Wallet-as-a-Service (WaaS) API. This API allows businesses to generate non-custodial HD wallets for their customers, derive addresses on multiple blockchains, and execute transfers.
Base URL: https://payments-api-dev-966260606560.europe-west2.run.app/api/v1
Authentication
All requests require a valid API Key in the header:
X-API-Key: <your_business_api_key>- Restriction: This API is available for Business Accounts only.
1. Create Customer Wallet
Creates a new HD Wallet (BIP-44) for a specific customer ID.
- Endpoint:
POST /wallet/customers - Description: Generates a master seed for the customer. One wallet covers all 9 supported networks.
Request
{
"customer_id": "cust_12345",
"word_count": 12
}word_count is optional: 12 or 24 (default: 12).
Response
{
"customer_id": "cust_12345",
"wallet_id": 1,
"mnemonic": ["word1", "word2", "...", "word12"],
"created_at": "2024-01-01T12:00:00Z"
}Critical:
mnemonicis returned once only. Store it encrypted immediately — it cannot be retrieved again.
2. Derive Address
Derives a new blockchain address for a customer wallet at a specific index.
- Endpoint:
POST /wallet/:customerID/derive - Description: Generates a deposit address for a supported network.
Request
{
"network": "ETH",
"index": 0,
"is_testnet": false,
"enable_monitoring": true
}Networks: BTC, BCH, LTC, ETH, BSC, POL, TRX, SOL, XRP
Response
{
"customer_id": "cust_12345",
"network": "ETH",
"address": "0x71C...",
"index": 0,
"derivation_path": "m/44'/60'/0'/0/0",
"is_testnet": false,
"monitored": true
}3. List Addresses
Lists all derived addresses for a customer.
- Endpoint:
GET /wallet/:customerID/addresses
Response
{
"customer_id": "cust_12345",
"addresses": [
{
"network": "ETH",
"address": "0x71C...",
"index": 0,
"monitored": true
}
],
"total": 1
}4. Get Seed Phrase
Retrieve the mnemonic seed phrase for a customer (sensitive — requires strong access controls).
- Endpoint:
GET /wallet/:customerID/seed
Response
{
"customer_id": "cust_12345",
"mnemonic": ["word1", "word2", "..."],
"word_count": 12
}5. Estimate Gas (EVM only — no auth required)
Estimate the gas fee for an EVM transaction. Supports ETH, BSC, POL only.
- Endpoint:
POST /wallet/estimate-gas - Authentication: None — public endpoint, safe for client-side use.
Request
{
"network": "ETH",
"currency": "USDT",
"from_address": "0x...",
"to_address": "0x...",
"amount": "50000000"
}Amount is in base units (see the Transfer section for the decimal reference table).
Response
{
"gas_limit": "65000",
"gas_price": "20000000000",
"estimated_fee": "0.0013",
"estimated_fee_usd": "3.90",
"currency": "ETH"
}6. Execute Transfer
Send crypto from a customer's derived wallet.
- Endpoint:
POST /wallet/:customerID/transfer
Amount Units
The API accepts both human-readable decimals ("2.5") and pre-converted base-unit integers ("2500000000000000000"). The server converts decimal input automatically using the correct precision for each network and currency.
| Network | Currency | Decimals | Example: 50 units (decimal) | Example: 50 units (base unit) |
|---|---|---|---|---|
| ETH | ETH | 18 | "50" | "50000000000000000000" |
| ETH | USDT, USDC | 6 | "50" | "50000000" |
| BSC | BNB | 18 | "50" | "50000000000000000000" |
| BSC | USDT, USDC | 18 | "50" | "50000000000000000000" |
| POL | POL | 18 | "50" | "50000000000000000000" |
| POL | USDT, USDC | 6 | "50" | "50000000" |
| TRX | TRX | 6 | "50" | "50000000" |
| TRX | USDT | 6 | "50" | "50000000" |
| SOL | SOL | 9 | "50" | "50000000000" |
| SOL | USDC | 6 | "50" | "50000000" |
| BTC, LTC, BCH | BTC/LTC/BCH | 8 | "50" | "5000000000" |
| XRP | XRP | 6 | "50" | "50000000" |
BSC USDT/USDC use 18 decimals (Binance-pegged tokens). POL USDT/USDC use 6 decimals (Polygon PoS bridged tokens — same as ETH).
Request
{
"network": "ETH",
"currency": "USDT",
"to_address": "0xRecipient...",
"amount": "50000000",
"index": 0
}Response
{
"tx_hash": "0x...",
"from_address": "0xSenderWallet...",
"to_address": "0xRecipient...",
"amount": "50000000",
"currency": "USDT",
"network": "ETH",
"gas_fee": "1050000000000000",
"status": "pending",
"timestamp": "2024-01-01T12:05:00Z"
}All amounts in response are in base units. status: "pending" means broadcast — track confirmation via webhooks.
7. Handle Deposit Webhooks
Rach fires two events per deposit. Configure your webhook URL in the dashboard (Settings → Webhooks).
Event Flow
customer sends crypto
↓
wallet.deposit.detected → safe_to_credit: false → show "pending" to customer
↓ (seconds to minutes depending on network)
wallet.deposit.confirmed → safe_to_credit: true → credit customer accountHandler
app.post('/webhooks/rach', express.raw({ type: '*/*' }), async (req, res) => {
// Always verify signature first
const sig = req.headers['x-webhook-signature'];
const expected = crypto
.createHmac('sha256', process.env.RACH_WEBHOOK_SECRET)
.update(req.body)
.digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
return res.status(401).end();
}
const { event, data } = JSON.parse(req.body);
if (event === 'wallet.deposit.detected') {
// Mark deposit as pending — do not credit yet
await db.deposits.upsert({
customerId: data.customer_id,
network: data.network,
amount: data.amount,
currency: data.currency,
status: 'pending',
});
}
// safe_to_credit is the definitive signal — check it explicitly
if (event === 'wallet.deposit.confirmed' && data.safe_to_credit === true) {
await db.deposits.update(
{ customerId: data.customer_id, network: data.network, status: 'pending' },
{ txHash: data.tx_hash, status: 'confirmed' }
);
await wallet.credit(data.customer_id, data.amount, data.currency);
}
res.sendStatus(200); // must respond 200 within 10s
});Never credit on
wallet.deposit.detected— it fires before the network confirmation threshold is met andsafe_to_creditwill befalse.
8. Configure Fee Collection (optional)
Enable Rach to collect a percentage fee from customer transfers and send it directly on-chain to your own addresses. Configure this once during onboarding using your API key.
- Endpoint:
POST /wallet/fees
Request
{
"fee_percent": "0.01",
"is_enabled": true,
"fee_addresses": {
"ETH": "0xYourEthAddress...",
"BSC": "0xYourBscAddress...",
"POL": "0xYourPolAddress...",
"TRX": "TYourTronAddress...",
"SOL": "YourSolanaAddress...",
"BTC": "bc1YourBtcAddress...",
"XRP": "rYourXrpAddress..."
}
}fee_percent is a decimal string: "0.01" = 1%, "0.005" = 0.5%. Maximum is "0.5" (50%).
Fees are only collected for networks where you provide an address. You can update addresses at any time via PUT /wallet/fees/addresses.
Response
{
"fee_percent": "0.01",
"is_enabled": true,
"fee_addresses": { "ETH": "0x...", "POL": "0x..." }
}9. Get Transaction History
Retrieve transaction history for a customer wallet.
- Endpoint:
GET /wallet/:customerID/transactions?page=1&limit=20&network=ETH
Response
{
"customer_id": "cust_12345",
"transactions": [
{
"tx_hash": "0x...",
"amount": "50000000",
"currency": "USDT",
"type": "transfer",
"status": "confirmed",
"created_at": "2024-01-01T12:05:00Z"
}
],
"total": 10
}