Getting Started
This page is for client-side developers who already have a Hydra App running (see the Setup Guide). It covers what services exist, how to call them, and the few primitive types that show up everywhere.
Want a runnable bot template instead? Skip to the Bot Quickstart.
Available services
Hydra App exposes one gRPC server with the following services. Each has its own dedicated reference page:
| Service | RPC count | What it does | Reference |
|---|---|---|---|
AppService | 12 | Networks, public key, preimages, archive retention, invites/referral | General API |
WalletService | 8 | Deposit addresses, balances, transactions, rescan | Wallet API |
PricingService | 2 | Asset → fiat price | Pricing API |
ClientService | 12 | Build, sign, broadcast on-chain transactions; allowances and token permits | Client API |
AssetService | 4 | Asset metadata, add tokens | Asset API |
BlockchainService | 9 | Read-only chain queries, raw broadcasts, allowances, permit terms | Blockchain API |
SignerService | 5 | Sign / verify messages, sign or sign-and-broadcast transactions | Signer API |
OrderbookService | 25 | Markets, orders, trades, fee tiers, market events | Orderbook API |
SwapService | 7 | Swap and SimpleSwap (auto-channel-setup swap) | Swap API |
NodeService | 47 | Channels, payments, invoices, allowances, peer whitelist / blacklist, watchtower | Node API |
LiquidityService | 10 | Service-backed channel liquidity, releases, lease extensions, lease discovery | Lease API |
WatchOnlyNodeService | 8 | Read-only channel and payment queries | Watch-Only Node API |
EventService | 3 | Subscribe to client, node, and on-chain HTLC event streams | Events API |
PreimageService | 2 | Settle a revealed preimage — channel legs and on-chain HTLC legs | HTLC & Preimage API |
HtlcService | 18 | On-chain HTLC lock / claim / refund / verify / watch + external-signer tx builders | HTLC & Preimage API |
172 RPCs in total. The count a given build actually serves is whatever rpc.discover returns — that is authoritative, and this table is a summary of it.
JSON-RPC namespaces match the service names lowercased:
app,wallet,pricing,client,asset,blockchain,signer,orderbook,swap,node,liquidity,watchOnlyNode,event,preimage,htlc.
Connecting
Hydra App listens on the port set by settings.server_port in your config (default 5003). Connect with any gRPC client:
import { AppServiceClient } from './proto/AppServiceClientPb'
const client = new AppServiceClient('http://localhost:5003')
No client-side authentication. Hydra App handles auth with the upstream Hydranet services on your behalf — derived from the seed you configured at setup. Your client connects to the local app over plain gRPC with no API keys, no headers, no auth handshake. If you find yourself looking for a "Bearer token" or "API key" parameter, you're looking at the wrong layer — it's all transparent to clients.
Your first call: list active networks
AppService.GetNetworks requires no parameters and confirms the app is up.
import { GetNetworksRequest } from './proto/app_pb'
const response = await client.getNetworks(new GetNetworksRequest(), {})
for (const n of response.getNetworksList()) {
console.log(`protocol=${n.getProtocol()} id=${n.getId()}`)
}
// → protocol=1 id=0a03cf40 (Bitcoin Signet)
// → protocol=2 id=11155111 (Ethereum Sepolia)
// → protocol=2 id=421614 (Arbitrum Sepolia)
Key concepts
Network
Identifies a blockchain. Two fields only:
| Field | Type | Notes |
|---|---|---|
protocol | Protocol enum | PROTOCOL_BITCOIN = 1, PROTOCOL_EVM = 2, PROTOCOL_TRON = 3 |
id | string | Magic bytes (hex) for Bitcoin, decimal chain ID for EVM and Tron |
Older example code may use
chain_idandname— those fields no longer exist. See the Setup Guide's network identifier table.
DecimalString
All monetary amounts are passed as strings to preserve precision. The string is in the asset's human-readable unit, not its smallest unit.
| Asset | "0.1" means | "100" means |
|---|---|---|
| BTC | 0.1 BTC (10,000,000 sats) | 100 BTC |
| ETH | 0.1 ETH (10¹⁷ wei) | 100 ETH |
| USDC | 0.1 USDC | 100 USDC |
| HDN | 0.1 HDN | 100 HDN |
So { value: "0.1" } always means "one-tenth of one whole asset" — never "0.1 satoshis" or "0.1 wei".
Asset and asset IDs
| Field | Description |
|---|---|
id | Unique identifier on the network — the protocol's zero address for a native asset, erc20:0x… / trc20:T… for a token. See Asset ID formats |
name | Human-readable, e.g. "Bitcoin" |
symbol | Ticker, e.g. "BTC", "USDC" |
decimals | Smallest-unit decimal places — informational only; you don't apply this when filling DecimalString |
A ticker is never an asset id.
"BTC"is asymbol; the id is the zero address.
Amount (for sends)
Used by client.SendTransaction, client.CreateSendTransaction, etc. A oneof:
| Variant | Payload | Meaning |
|---|---|---|
exact | { amount: DecimalString } | Send exactly this amount |
all | {} | Send all available balance (UTXO sweep / EVM full transfer) |
FeeOption
How a transaction's fee is selected. It is a oneof message, not an enum — exactly one arm is set:
| Arm | Payload | Meaning |
|---|---|---|
low / medium / high | (empty) | Use the network's estimate at that priority |
custom | { fee_rate: FeeRate } | Your own rate — FeeRate is { max_fee_per_unit, priority_fee_per_unit }, both U256String per unit (sat/vbyte or wei per gas) |
const feeOption = { medium: {} } // ✅
const feeOption = { custom: { feeRate: { maxFeePerUnit: { value: '5' },
priorityFeePerUnit: { value: '0' } } } } // ✅
There is no
FeeOption.MEDIUMconstant and nopriorityfield. See Common Patterns → Fee structures for the full shape, andblockchain.GetFeeEstimatesfor current numbers.
The two transaction flows
ClientService exposes two parallel ways to make an on-chain transaction. Pick the one that fits your signing model.
One-shot (Hydra App signs and broadcasts)
SendTransaction → txid
SendTokenTransaction → txid
BumpTransaction → txid
SetTokenAllowance → txid
Use this when Hydra App holds the private key (most bots).
Build → sign → finalize (you sign externally)
CreateSendTransaction → TransactionRequest
↓ sign with signer.SignTransaction
SignedTransactionRequest
↓
FinalizeAndBroadcastTransaction → txid
Use this when you want to inspect the transaction before signing, or when the signing key lives in an external HSM / hardware wallet.
For raw transactions you've already signed entirely outside Hydra (e.g. PSBT workflows), use
blockchain.BroadcastRawTransactioninstead.
The two trading flows
SwapService has two ways to trade:
| RPC | When to use |
|---|---|
Swap | You already have offchain balance in both the sending and receiving currencies. Fast — just submits the order. |
SimpleSwap | You don't have balance yet. Hydra App sets up the necessary channels (open / deposit / lease) before submitting the order. Charges on-chain fees. |
A bot starting from cold will almost always use SimpleSwap for the first trade and Swap thereafter.
The two ways to get inbound liquidity
A new node has zero channels. Two options:
| Option | RPC | When to use |
|---|---|---|
| Self-funded | node.OpenChannel | You have on-chain balance and a willing peer. You pay the funding tx. |
| Service-backed lease | liquidity.RequestChannelLiquidity | The liquidity service provisions a channel for you. You pay a service fee instead of doing the funding yourself. |
For bots, the lease flow is usually simpler — see the Lease API.
Streaming RPCs
Three subscriptions a bot will care about:
| Stream | RPC | Use |
|---|---|---|
| Client events | event.SubscribeClientEvents | On-chain: sync, blocks, wallet transactions, balance updates |
| Node events | event.SubscribeNodeEvents | Off-chain: channel and payment lifecycle, peers, watchtowers |
| Market events | orderbook.SubscribeMarketEvents | Orderbook updates for a market (use for live prices, fills) |
Subscribe before you act. If you place an order before subscribing to the market stream, you can miss the fill notification. Same for
SimpleSwap— subscribe toSubscribeSimpleSwapsbefore callingSimpleSwap.
Error handling at a glance
Hydra App returns standard gRPC status codes. For a bot, the practical mental model:
| Status | Meaning | Retry? |
|---|---|---|
OK | Success | n/a |
INVALID_ARGUMENT | Your request is malformed | No — fix and resubmit |
FAILED_PRECONDITION | State doesn't allow this (e.g. channel not active) | Maybe — wait for state change |
RESOURCE_EXHAUSTED | Liquidity / capacity unavailable | Maybe — back off and retry |
UNAVAILABLE | Network blip or upstream outage | Yes — exponential backoff |
DEADLINE_EXCEEDED | Your deadline fired | Yes if idempotent |
INTERNAL / UNKNOWN | App bug | Log and surface; don't retry blindly |
Idempotency caveat:
Send*andOpen*RPCs are not idempotent — a retry afterDEADLINE_EXCEEDEDmay broadcast twice. Verify first (wallet.GetTransactions,watchOnlyNode.GetPaymentsByHash,SubscribeNodeEvents), or, for order placement, setclient_order_idand let the orderbook deduplicate. Per-RPC rules: Errors → Idempotency & Retry Safety.
See 40-errors.md for the full code list and per-RPC error mappings.
Next steps
- Bot Quickstart — runnable trading-bot template
- Common Patterns — fees, amounts, helper functions
- Browser & gRPC-Web Specifics — for browser clients only: manual framing, fetch-based streaming, CORS
- Service references: App · Wallet · Pricing · Client · Asset · Blockchain · Signer · Orderbook · Swap · Node · Lease · Watch-Only Node · Events · HTLC & Preimage