Api
General API
Network information and public data
The General API (App Service) provides basic application-level operations.
Endpoints
Get Networks
Retrieve all available networks supported by the Hydra node.
Method: GetNetworks
Parameters: None
Response:
| Field | Type | Description |
|---|---|---|
networks | Network[] | Array of supported networks |
Network Object:
| Field | Type | Description |
|---|---|---|
protocol | int32 | Protocol type (0=Bitcoin, 1=EVM) |
chain_id | string | Chain identifier |
name | string | Human-readable network name |
Example Request:
Rust
use hydra_api::app_service_client::AppServiceClient;
use hydra_api::GetNetworksRequest;
use tonic::transport::Channel;
let channel = Channel::from_static("http://localhost:5001")
.connect()
.await?;
let mut client = AppServiceClient::new(channel);
let request = tonic::Request::new(GetNetworksRequest {});
let response = client.get_networks(request).await?;
for network in response.into_inner().networks {
println!("{} - Protocol: {}, Chain: {}",
network.name, network.protocol, network.chain_id);
}
Go
import (
pb "github.com/hydra/hydra-go/proto"
)
client := pb.NewAppServiceClient(conn)
req := &pb.GetNetworksRequest{}
resp, err := client.GetNetworks(context.Background(), req)
if err != nil {
log.Fatal(err)
}
for _, network := range resp.Networks {
fmt.Printf("%s - Protocol: %d, Chain: %s\n",
network.Name, network.Protocol, network.ChainId)
}
TypeScript
import { AppServiceClient } from './proto/AppServiceClientPb'
import { GetNetworksRequest } from './proto/app_pb'
const client = new AppServiceClient('http://localhost:5001')
const request = new GetNetworksRequest()
const response = await client.getNetworks(request, {})
const networks = response.getNetworksList()
networks.forEach(network => {
console.log(`${network.getName()} - Protocol: ${network.getProtocol()}, Chain: ${network.getChainId()}`)
})
Example Response:
{
"networks": [
{
"protocol": 0,
"chain_id": "0",
"name": "Bitcoin"
},
{
"protocol": 0,
"chain_id": "1",
"name": "Bitcoin Testnet"
},
{
"protocol": 1,
"chain_id": "1",
"name": "Ethereum"
},
{
"protocol": 1,
"chain_id": "11155111",
"name": "Sepolia"
}
]
}
Get Public Key
Get the public key of the Hydra node.
Method: GetPublicKey
Parameters:
| Name | Type | Required | Description |
|---|---|---|---|
network | Network | YES | Network to get public key for |
Response:
| Field | Type | Description |
|---|---|---|
public_key | string | Node's public key (hex encoded) |
Example Request:
Rust
let request = tonic::Request::new(GetPublicKeyRequest {
network: Some(Network {
protocol: 0,
chain_id: "0".to_string(),
name: "Bitcoin".to_string(),
}),
});
let response = client.get_public_key(request).await?;
let pubkey = response.into_inner().public_key;
println!("Node public key: {}", pubkey);
Go
req := &pb.GetPublicKeyRequest{
Network: &pb.Network{
Protocol: 0,
ChainId: "0",
Name: "Bitcoin",
},
}
resp, err := client.GetPublicKey(context.Background(), req)
if err != nil {
log.Fatal(err)
}
pubkey := resp.PublicKey
fmt.Printf("Node public key: %s\n", pubkey)
TypeScript
const request = new GetPublicKeyRequest()
request.setNetwork({
protocol: 0,
chainId: '0',
name: 'Bitcoin'
})
const response = await client.getPublicKey(request, {})
const pubkey = response.getPublicKey()
console.log('Node public key:', pubkey)
Example Response:
{
"public_key": "02abc123def456789..."
}
Common Workflows
Initialize application and discover networks
Rust
use std::collections::HashMap;
async fn initialize_app(
client: &mut AppServiceClient<Channel>
) -> Result<HashMap<String, (Network, String)>, Box<dyn std::error::Error>> {
// Get available networks
let request = tonic::Request::new(GetNetworksRequest {});
let response = client.get_networks(request).await?;
let networks = response.into_inner().networks;
println!("Available networks:");
let mut network_map = HashMap::new();
for network in networks {
println!("- {}", network.name);
// Get node public key for each network
let pubkey_req = tonic::Request::new(GetPublicKeyRequest {
network: Some(network.clone()),
});
let pubkey_resp = client.get_public_key(pubkey_req).await?;
let public_key = pubkey_resp.into_inner().public_key;
network_map.insert(network.name.clone(), (network, public_key));
}
Ok(network_map)
}
// Usage
let networks = initialize_app(&mut client).await?;
if let Some((_, pubkey)) = networks.get("Bitcoin") {
println!("Bitcoin node ID: {}", pubkey);
}
Go
func initializeApp(client pb.AppServiceClient) (map[string]struct {
Network *pb.Network
PublicKey string
}, error) {
// Get available networks
networksReq := &pb.GetNetworksRequest{}
networksResp, err := client.GetNetworks(context.Background(), networksReq)
if err != nil {
return nil, err
}
fmt.Println("Available networks:")
networkMap := make(map[string]struct {
Network *pb.Network
PublicKey string
})
for _, network := range networksResp.Networks {
fmt.Printf("- %s\n", network.Name)
// Get node public key for each network
pubkeyReq := &pb.GetPublicKeyRequest{
Network: network,
}
pubkeyResp, err := client.GetPublicKey(context.Background(), pubkeyReq)
if err != nil {
return nil, err
}
networkMap[network.Name] = struct {
Network *pb.Network
PublicKey string
}{
Network: network,
PublicKey: pubkeyResp.PublicKey,
}
}
return networkMap, nil
}
// Usage
networks, err := initializeApp(client)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Bitcoin node ID: %s\n", networks["Bitcoin"].PublicKey)
TypeScript
async function initializeApp() {
const client = new AppServiceClient('http://localhost:5001')
// Get available networks
const networksReq = new GetNetworksRequest()
const networksResp = await client.getNetworks(networksReq, {})
const networks = networksResp.getNetworksList()
console.log('Available networks:')
const networkMap = {}
for (const network of networks) {
console.log(`- ${network.getName()}`)
// Get node public key for each network
const pubkeyReq = new GetPublicKeyRequest()
pubkeyReq.setNetwork(network)
const pubkeyResp = await client.getPublicKey(pubkeyReq, {})
networkMap[network.getName()] = {
network,
publicKey: pubkeyResp.getPublicKey()
}
}
return networkMap
}
// Usage
const networks = await initializeApp()
console.log('Bitcoin node ID:', networks['Bitcoin'].publicKey)
Find network by name
Rust
async fn get_network_by_name(
client: &mut AppServiceClient<Channel>,
network_name: &str
) -> Result<Option<Network>, Box<dyn std::error::Error>> {
let request = tonic::Request::new(GetNetworksRequest {});
let response = client.get_networks(request).await?;
let networks = response.into_inner().networks;
Ok(networks.into_iter().find(|n| n.name == network_name))
}
// Usage
let bitcoin = get_network_by_name(&mut client, "Bitcoin").await?;
if let Some(network) = bitcoin {
println!("Bitcoin chain ID: {}", network.chain_id);
}
Go
func getNetworkByName(
client pb.AppServiceClient,
networkName string,
) (*pb.Network, error) {
req := &pb.GetNetworksRequest{}
resp, err := client.GetNetworks(context.Background(), req)
if err != nil {
return nil, err
}
for _, network := range resp.Networks {
if network.Name == networkName {
return network, nil
}
}
return nil, nil
}
// Usage
bitcoin, err := getNetworkByName(client, "Bitcoin")
if err != nil {
log.Fatal(err)
}
if bitcoin != nil {
fmt.Printf("Bitcoin chain ID: %s\n", bitcoin.ChainId)
}
TypeScript
async function getNetworkByName(
client: AppServiceClient,
networkName: string
): Promise<Network | null> {
const request = new GetNetworksRequest()
const response = await client.getNetworks(request, {})
const networks = response.getNetworksList()
return networks.find(n => n.getName() === networkName) || null
}
// Usage
const bitcoin = await getNetworkByName(client, 'Bitcoin')
if (bitcoin) {
console.log('Bitcoin chain ID:', bitcoin.getChainId())
}
Protocol Types
| Value | Description | Networks |
|---|---|---|
0 | Bitcoin-based | Bitcoin Mainnet, Bitcoin Testnet, Bitcoin Regtest |
1 | EVM-based | Ethereum, Polygon, Arbitrum, Optimism, Sepolia, etc. |
Chain IDs
Bitcoin Networks (Protocol 0)
| Chain ID | Network |
|---|---|
0 | Bitcoin Mainnet |
1 | Bitcoin Testnet |
2 | Bitcoin Regtest |
EVM Networks (Protocol 1)
| Chain ID | Network |
|---|---|
1 | Ethereum Mainnet |
11155111 | Sepolia Testnet |
137 | Polygon |
42161 | Arbitrum One |
10 | Optimism |
Best Practices
- Cache network list - Networks rarely change, cache for application lifetime
- Validate network parameters - Check protocol and chain_id before operations
- Store public keys - Cache node public keys to avoid repeated calls
- Handle network additions - Be prepared for new networks to be added