Skip to content

Wallet Service Integration Guide

Complete guide to integrating Rach Wallet-as-a-Service into your application.

Overview

Build enterprise-grade wallet infrastructure for your users without managing blockchain complexity. This guide covers creating wallets, deriving addresses, and managing balances across 8 blockchain networks including Bitcoin, Ethereum, and more.

Supported Networks: Bitcoin (BTC), Bitcoin Cash (BCH), Litecoin (LTC), BSC, Ethereum, Polygon, Tron, Solana

Quick Start

The wallet service uses HD (Hierarchical Deterministic) wallets. You create a wallet once, then derive addresses for different networks as needed.


Integration Flow


Step 1: Create HD Wallet for Customer

When a user needs cryptocurrency functionality, create an HD wallet:

javascript
// JavaScript / Node.js
const axios = require('axios');

async function createWalletForUser(userId) {
  try {
    const response = await axios.post(
      'https://payments-api-dev-966260606560.europe-west2.run.app/api/v1/wallet/customer/create',
      {
        customer_id: userId,
        word_count: 12  // Optional: 12 or 24, defaults to 12
      },
      {
        headers: {
          'X-API-Key': process.env.RACH_API_KEY,
          'Content-Type': 'application/json'
        }
      }
    );
    
    return response.data;
  } catch (error) {
    console.error('Wallet creation failed:', error.response?.data);
    throw error;
  }
}

// Usage - Create HD wallet
const wallet = await createWalletForUser('user_12345');
console.log('Wallet ID:', wallet.wallet_id);
console.log('Mnemonic (SAVE SECURELY):', wallet.mnemonic);
python
# Python
import requests
import os

def create_wallet_for_user(user_id):
    """Create an HD wallet for a user"""
    url = 'https://payments-api-dev-966260606560.europe-west2.run.app/api/v1/wallet/customer/create'
    
    payload = {
        'customer_id': user_id,
        'word_count': 12  # Optional: 12 or 24
    }
    
    headers = {
        'X-API-Key': os.getenv('RACH_API_KEY'),
        'Content-Type': 'application/json'
    }
    
    try:
        response = requests.post(url, json=payload, headers=headers)
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as e:
        print(f'Wallet creation failed: {e}')
        raise

# Usage - Create HD wallet
wallet = create_wallet_for_user('user_12345')
print(f"Wallet ID: {wallet['wallet_id']}")
print(f"Mnemonic: {wallet['mnemonic']}")  # Save securely!
go
// Go
package main

import (
    "bytes"
    "encoding/json"
    "net/http"
    "os"
)

type WalletRequest struct {
    CustomerID string `json:"customer_id"`
    WordCount  int    `json:"word_count,omitempty"`
}

type WalletResponse struct {
    CustomerID string   `json:"customer_id"`
    WalletID   uint     `json:"wallet_id"`
    Mnemonic   []string `json:"mnemonic"`
    CreatedAt  string   `json:"created_at"`
}

func createWalletForUser(customerID string) (*WalletResponse, error) {
    apiKey := os.Getenv("RACH_API_KEY")
    
    payload := WalletRequest{
        CustomerID: customerID,
        WordCount:  12,  // Optional
    }
    
    body, _ := json.Marshal(payload)
    
    req, _ := http.NewRequest(
        "POST",
        "https://payments-api-dev-966260606560.europe-west2.run.app/api/v1/wallet/customer/create",
        bytes.NewBuffer(body),
    )
    
    req.Header.Set("X-API-Key", apiKey)
    req.Header.Set("Content-Type", "application/json")
    
    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()
    
    var wallet WalletResponse
    json.NewDecoder(resp.Body).Decode(&wallet)
    
    return &wallet, nil
}
php
// PHP
<?php

function createWalletForUser($userId) {
    $apiKey = getenv('RACH_API_KEY');
    
    $payload = [
        'customer_id' => $userId,
        'word_count' => 12  // Optional
    ];
    
    $ch = curl_init('https://payments-api-dev-966260606560.europe-west2.run.app/api/v1/wallet/customer/create');
    
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'X-API-Key: ' . $apiKey,
        'Content-Type: application/json'
    ]);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    if ($httpCode !== 200) {
        throw new Exception('Wallet creation failed');
    }
    
    return json_decode($response, true);
}

// Usage - Create HD wallet
$wallet = createWalletForUser('user_12345');
echo "Wallet ID: " . $wallet['wallet_id'] . "\n";
print_r($wallet['mnemonic']);  // Save securely!
?>

Response:

json
{
  "customer_id": "user_12345",
  "wallet_id": 123,
  "mnemonic": [
    "abandon", "ability", "able", "about", "above", "absent",
    "absorb", "abstract", "absurd", "abuse", "access", "accident"
  ],
  "created_at": "2025-12-22T04:00:00Z"
}

Security Warning

The mnemonic is ONLY returned once during wallet creation. You must save it securely or display it to the user to back up. It can NEVER be retrieved again - even with authorization.


Step 2: Derive Addresses for Networks

After creating the HD wallet, derive addresses for specific blockchain networks:

javascript
async function deriveAddress(customerId, network, index = 0) {
  const response = await axios.post(
    `https://payments-api-dev-966260606560.europe-west2.run.app/api/v1/wallet/customer/${customerId}/derive`,
    {
      network: network,  // BTC, ETH, BSC, POL, TRX, SOL, etc.
      index: index,      // Address index (0, 1, 2, ...)
      testnet: false     // Use testnet addresses?
    },
    {
      headers: {
        'X-API-Key': process.env.RACH_API_KEY,
        'Content-Type': 'application/json'
      }
    }
  );
  
  return response.data;
}

// Derive Bitcoin address
const btcAddr = await deriveAddress('user_12345', 'BTC', 0);
console.log('BTC Address:', btcAddr.address);
console.log('Derivation Path:', btcAddr.derivation_path);

// Derive Ethereum address  
const ethAddr = await deriveAddress('user_12345', 'ETH', 0);
console.log('ETH Address:', ethAddr.address);

// Derive BSC address (same as ETH for EVM)
const bscAddr = await deriveAddress('user_12345', 'BSC', 0);
console.log('BSC Address:', bscAddr.address);
python
def derive_address(customer_id, network, index=0, testnet=False):
    """Derive an address for a specific network"""
    url = f'https://payments-api-dev-966260606560.europe-west2.run.app/api/v1/wallet/customer/{customer_id}/derive'
    
    payload = {
        'network': network,
        'index': index,
        'testnet': testnet
    }
    
    headers = {
        'X-API-Key': os.getenv('RACH_API_KEY'),
        'Content-Type': 'application/json'
    }
    
    response = requests.post(url, json=payload, headers=headers)
    response.raise_for_status()
    return response.json()

# Derive addresses for different networks
btc_addr = derive_address('user_12345', 'BTC')
eth_addr = derive_address('user_12345', 'ETH')
bsc_addr = derive_address('user_12345', 'BSC')

print(f"Bitcoin: {btc_addr['address']}")
print(f"Ethereum: {eth_addr['address']}")
print(f"BSC: {bsc_addr['address']}")
php
function deriveAddress($customerId, $network, $index = 0) {
    $apiKey = getenv('RACH_API_KEY');
    
    $payload = [
        'network' => $network,
        'index' => $index,
        'testnet' => false
    ];
    
    $url = "https://payments-api-dev-966260606560.europe-west2.run.app/api/v1/wallet/customer/{$customerId}/derive";
    
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'X-API-Key: ' . $apiKey,
        'Content-Type: application/json'
    ]);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    
    $response = curl_exec($ch);
    curl_close($ch);
    
    return json_decode($response, true);
}

// Derive addresses
$btcAddr = deriveAddress('user_12345', 'BTC');
$ethAddr = deriveAddress('user_12345', 'ETH');

echo "Bitcoin: " . $btcAddr['address'] . "\n";
echo "Ethereum: " . $ethAddr['address'] . "\n";

Response:

json
{
  "customer_id": "user_12345",
  "network": "BTC",
  "address": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
  "index": 0,
  "derivation_path": "m/84'/0'/0'/0/0",
  "is_testnet": false
}

Step 3: Display Deposit Addresses

Show users their deposit addresses for each network:

html
<div class="wallet-addresses">
  <h3>Your Deposit Addresses</h3>
  
  <div class="address-list">
    <!-- Loop through addresses array -->
    <div class="address-card" v-for="addr in addresses" :key="addr.network">
      <div class="network-badge">{{ addr.network }}</div>
      <div class="address-field">
        <input type="text" :value="addr.address" readonly />
        <button @click="copyAddress(addr.address)">Copy</button>
      </div>
      <div class="qr-code">
        <img :src="`/api/qr?address=${addr.address}`" alt="QR Code" />
      </div>
    </div>
  </div>
</div>

Step 4: List All Addresses

Query all derived addresses for a customer:

bash
curl https://payments-api-dev-966260606560.europe-west2.run.app/api/v1/wallet/customer/user_12345/addresses \
  -H "X-API-Key: YOUR_API_KEY"

Response:

json
{
  "customer_id": "user_12345",
  "addresses": [
    {
      "network": "BTC",
      "address": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
      "index": 0,
      "derivation_path": "m/84'/0'/0'/0/0"
    },
    {
      "network": "ETH",
      "address": "0x8B3192f2f0f0D7E4F5C3A1B9E2D7A6C5B4D3E2F1",
      "index": 0,
      "derivation_path": "m/44'/60'/0'/0/0"
    }
  ],
  "total": 2
}

Step 5: Transfer/Withdraw Funds

Send crypto from a customer wallet:

javascript
async function transferFunds(customerId, network, currency, toAddress, amount) {
  const response = await axios.post(
    `https://payments-api-dev-966260606560.europe-west2.run.app/api/v1/wallet/customer/${customerId}/transfer`,
    {
      network: network,      // BTC, ETH, BSC, etc.
      currency: currency,    // BTC, ETH, USDT, etc.
      to_address: toAddress,
      amount: amount,        // In smallest unit (satoshis, wei, etc.)
      index: 0               // Which address to send from
    },
    {
      headers: {
        'X-API-Key': process.env.RACH_API_KEY,
        'Content-Type': 'application/json'
      }
    }
  );
  
  return response.data;
}

// Send 0.01 BTC
const tx = await transferFunds('user_12345', 'BTC', 'BTC', 'bc1q...', '1000000');
console.log('Transaction Hash:', tx.txn_hash);
console.log('Gas Fee:', tx.gas_fee);

Complete Integration Example

javascript
// 1. Create HD wallet on user signup
const wallet = await createWalletForUser('user_12345');

// 2. Save wallet ID to your database
await db.users.update(userId, {
  wallet_id: wallet.wallet_id,
  // Optionally save encrypted mnemonic
});

// 3. Derive addresses for networks you support
const networks = ['BTC', 'ETH', 'BSC', 'TRX'];
const addresses = await Promise.all(
  networks.map(network => deriveAddress('user_12345', network, 0))
);

// 4. Save addresses to your database
await db.addresses.insertMany(addresses.map(addr => ({
  user_id: userId,
  network: addr.network,
  address: addr.address,
  index: addr.index
})));

// 5. Display addresses to user
return {
  wallet_id: wallet.wallet_id,
  addresses: addresses.map(a => ({
    network: a.network,
    address: a.address
  }))
};

API Endpoints Summary

EndpointMethodPurpose
/api/v1/wallet/customer/createPOSTCreate HD wallet
/api/v1/wallet/customer/:id/derivePOSTDerive address for network
/api/v1/wallet/customer/:id/addressesGETList all addresses
/api/v1/wallet/customer/:id/transferPOSTSend funds
/api/v1/wallet/customer/:id/seedGETGet mnemonic (secure)
/api/v1/wallet/customer/:id/transactionsGETGet transaction history
/api/v1/wallet/customer/:id/export-keyPOSTExport private key (secure)
/api/v1/wallet/customer/estimate-gasPOSTEstimate transfer fees

Best Practices

Wallet Management

  • ✅ Create wallet once per user
  • ✅ Save wallet_id in your database
  • ✅ Securely store or display mnemonic to user once
  • ✅ Derive addresses on-demand per network
  • ✅ Use index parameter for multiple addresses per network
  • ✅ Enable testnet mode during development

Next Steps

Built with ❤️ by Rach Finance