Wallets API

Create and manage HD master wallets across multiple blockchains. Master wallets are the parent of all child addresses on a chain/network.

Authentication:

  • HMAC-only for POST /wallets
  • Dual-auth (JWT or HMAC) for all reads and balance lookups

Base path: /api/v1/wallets


Create master wallet

POST /api/v1/wallets

Auth: HMAC-only.

Request body

Field Type Required Description
chain string Yes ethereum, polygon, tron, base, bsc, solana, bitcoin, aptos
network string Yes mainnet, sepolia, amoy, shasta, etc. — see supported networks
label string No Friendly name

Example

curl -X POST https://api.hasapay.com/api/v1/wallets \
  -H "X-API-Key: $API_KEY" \
  -H "X-Signature: $SIG" \
  -H "X-Timestamp: $TS" \
  -H "X-Request-ID: $RID" \
  -H "Content-Type: application/json" \
  -d '{
    "chain": "ethereum",
    "network": "sepolia",
    "label": "Main ETH Wallet"
  }'

Response

{
  "data": {
    "id": "uuid",
    "organization_id": "uuid",
    "chain": "ethereum",
    "network": "sepolia",
    "address": "0xd502b72b8D969D60D1094174b1457C73671eb9d8",
    "label": "Main ETH Wallet",
    "is_active": true,
    "child_count": 0,
    "created_at": "2026-06-09T10:00:00Z",
    "updated_at": "2026-06-09T10:00:00Z"
  }
}

Only one master wallet per (organization, chain, network). Retrying create returns the existing wallet, not an error.


List master wallets

GET /api/v1/wallets

Auth: Dual-auth.

Query params

Param Default Description
include_balances false Inline current balances per wallet

Response

{
  "data": [
    {
      "id": "uuid",
      "chain": "ethereum",
      "network": "sepolia",
      "address": "0xd502b72b...",
      "label": "Main ETH Wallet",
      "is_active": true,
      "child_count": 5,
      "balances": [
        {
          "asset_id": "uuid",
          "token_symbol": "ETH",
          "balance": "0.5",
          "balance_raw": "500000000000000000",
          "is_stale": false,
          "last_synced": "2026-06-09T10:30:00Z"
        }
      ],
      "created_at": "2026-06-09T10:00:00Z"
    }
  ],
  "count": 3
}

Get master wallet

GET /api/v1/wallets/:walletId

Auth: Dual-auth.

Query params

Param Default Description
include_balances false Inline balances

Returns a single wallet in the same shape as the list rows.


Get single-token balance

GET /api/v1/wallets/:walletId/balance

Auth: Dual-auth.

Query params

Param Required Description
chain Yes Chain of the asset
network Yes Network of the asset
token Yes Token symbol (e.g. USDC)
token_address No Contract address for ambiguous symbols (e.g. multiple USDCs on a chain)

Response

{
  "data": {
    "chain": "ethereum",
    "network": "sepolia",
    "token_symbol": "USDC",
    "balance": "1000.00",
    "balance_raw": "1000000000",
    "pending_in": "0",
    "pending_in_raw": "0",
    "pending_out": "0",
    "pending_out_raw": "0"
  }
}

pending_in is the sum of unconfirmed deposits; pending_out is the sum of unconfirmed withdrawals/sweeps. Both let you display a "pending balance" without waiting for confirmations.


Get all balances for a wallet

GET /api/v1/wallets/:walletId/balances

Auth: Dual-auth.

Returns every token balance the wallet holds on its chain/network.

{
  "data": [
    {
      "asset_id": "uuid",
      "chain": "ethereum",
      "network": "sepolia",
      "token_symbol": "ETH",
      "token_decimals": 18,
      "balance": "0.5",
      "balance_raw": "500000000000000000",
      "is_stale": false,
      "last_synced": "2026-06-09T10:30:00Z"
    },
    {
      "asset_id": "uuid",
      "chain": "ethereum",
      "network": "sepolia",
      "token_symbol": "USDC",
      "token_decimals": 6,
      "balance": "1000.00",
      "balance_raw": "1000000000",
      "is_stale": false,
      "last_synced": "2026-06-09T10:30:00Z"
    }
  ]
}

Supported chains and networks

Chain Mainnet Testnet
ethereum mainnet sepolia
polygon mainnet amoy
bsc mainnet testnet
base mainnet sepolia
tron mainnet shasta

Solana, Bitcoin, and Aptos are scaffolded but not generally available.


Errors

Code Cause
WALLET_NOT_FOUND No wallet with that ID on this org
WALLET_ALREADY_EXISTS Returned existing — see note under create
INVALID_CHAIN Unsupported chain string
INVALID_NETWORK Unsupported network for this chain