Api

Watch-Only Node API

Read-only access to Lightning node data

The Watch-Only Node API provides read-only access to Lightning Network node information without requiring node control.

Endpoints


Get Node ID

Get the node ID for a specific network.

Service: WatchOnlyNodeServiceMethod: GetNodeId

Parameters:

NameTypeRequiredDescription
networkNetworkYESNetwork to get node ID for

Response:

FieldTypeDescription
node_idstringLightning node public key

Example Request:

TypeScript
const nodeId = await hydraGrpcClient.getNodeId({
  protocol: Protocol.BITCOIN,
  id: '0a03cf40' // Bitcoin Signet
})
Rust
let request = tonic::Request::new(GetNodeIdRequest {
    network: Some(Network {
        protocol: Protocol::Bitcoin as i32,
        id: "0a03cf40".to_string(),
    }),
});

let response = client.get_node_id(request).await?;
let node_id = response.into_inner().node_id;

Get Channels

Get all channels for a network.

Service: WatchOnlyNodeServiceMethod: GetChannels

Parameters:

NameTypeRequiredDescription
networkNetworkYESNetwork to query channels for

Response:

FieldTypeDescription
channelsChannel[]Array of channel objects

Channel Object:

FieldTypeDescription
idstringChannel identifier
counterpartystringCounterparty node ID
statusChannelStatusChannel status
asset_channelsmap<string, AssetChannel>Asset-specific channel data

Example Request:

TypeScript
const channels = await hydraGrpcClient.getChannels({
  protocol: Protocol.BITCOIN,
  id: '0a03cf40'
})

channels.forEach(ch => {
  console.log(`Channel ${ch.id} with ${ch.counterparty}`)
})
Rust
let request = tonic::Request::new(GetChannelsRequest {
    network: Some(Network {
        protocol: Protocol::Bitcoin as i32,
        id: "0a03cf40".to_string(),
    }),
});

let response = client.get_channels(request).await?;
let channels = response.into_inner().channels;

for channel in channels {
    println!("Channel {} with {}", channel.id, channel.counterparty);
}

Get Channels With Counterparty

Get all channels with a specific counterparty node.

Service: WatchOnlyNodeServiceMethod: GetChannelsWithCounterparty

Parameters:

NameTypeRequiredDescription
networkNetworkYESNetwork to query
counterparty_node_idstringYESCounterparty node public key

Response:

FieldTypeDescription
channelsChannel[]Channels with this counterparty

Example Request:

TypeScript
const channels = await hydraGrpcClient.getChannelsWithCounterparty({
  network: {
    protocol: Protocol.BITCOIN,
    id: '0a03cf40'
  },
  counterpartyNodeId: '02abc123...'
})
Rust
let request = tonic::Request::new(GetChannelsWithCounterpartyRequest {
    network: Some(Network {
        protocol: Protocol::Bitcoin as i32,
        id: "0a03cf40".to_string(),
    }),
    counterparty_node_id: "02abc123...".to_string(),
});

let response = client.get_channels_with_counterparty(request).await?;
let channels = response.into_inner().channels;

Get Channel

Get detailed information about a specific channel.

Service: WatchOnlyNodeServiceMethod: GetChannel

Parameters:

NameTypeRequiredDescription
networkNetworkYESNetwork the channel is on
channel_idstringYESChannel identifier

Response:

FieldTypeDescription
channelChannelDetailed channel information

Example Request:

TypeScript
const channel = await hydraGrpcClient.getChannel({
  network: {
    protocol: Protocol.BITCOIN,
    id: '0a03cf40'
  },
  channelId: 'ch_abc123'
})

console.log(`Channel status: ${channel.status}`)
console.log(`Counterparty: ${channel.counterparty}`)
Rust
let request = tonic::Request::new(GetChannelRequest {
    network: Some(Network {
        protocol: Protocol::Bitcoin as i32,
        id: "0a03cf40".to_string(),
    }),
    channel_id: "ch_abc123".to_string(),
});

let response = client.get_channel(request).await?;
let channel = response.into_inner().channel;

Get Payments

Get payment history for a network.

Service: WatchOnlyNodeServiceMethod: GetPayments

Parameters:

NameTypeRequiredDescription
networkNetworkYESNetwork to query payments for

Response:

FieldTypeDescription
paymentsPayment[]Array of payment objects

Payment Object:

FieldTypeDescription
idstringPayment identifier
directionPaymentDirectionINCOMING or OUTGOING
statusPaymentStatusPayment status
amountmap<string, DecimalString>Asset amounts
timestampTimestampPayment timestamp

Example Request:

TypeScript
const payments = await hydraGrpcClient.getPayments({
  protocol: Protocol.BITCOIN,
  id: '0a03cf40'
})

payments.forEach(payment => {
  console.log(`${payment.direction} payment: ${payment.id}`)
})
Rust
let request = tonic::Request::new(GetPaymentsRequest {
    network: Some(Network {
        protocol: Protocol::Bitcoin as i32,
        id: "0a03cf40".to_string(),
    }),
});

let response = client.get_payments(request).await?;
let payments = response.into_inner().payments;

for payment in payments {
    println!("{:?} payment: {}", payment.direction, payment.id);
}

Common Patterns

Monitor channel status

Rust
async fn get_active_channels(
    client: &mut WatchOnlyNodeServiceClient<Channel>,
    network: Network,
) -> Result<Vec<Channel>, Box<dyn std::error::Error>> {
    let channels = client
        .get_channels(GetChannelsRequest {
            network: Some(network),
        })
        .await?
        .into_inner()
        .channels;

    Ok(channels
        .into_iter()
        .filter(|ch| ch.status == ChannelStatus::Active as i32)
        .collect())
}

Find channel with peer

Rust
async fn find_channel_with_peer(
    client: &mut WatchOnlyNodeServiceClient<Channel>,
    network: Network,
    peer_id: String,
) -> Result<Option<Channel>, Box<dyn std::error::Error>> {
    let channels = client
        .get_channels_with_counterparty(GetChannelsWithCounterpartyRequest {
            network: Some(network),
            counterparty_node_id: peer_id,
        })
        .await?
        .into_inner()
        .channels;

    Ok(channels.into_iter().next())
}

Error Handling

Error CodeDescriptionSolution
INVALID_ARGUMENTInvalid network or channel IDVerify parameters
NOT_FOUNDChannel or payment not foundCheck ID is correct
UNAVAILABLEService temporarily unavailableRetry with backoff

Best Practices

  1. Read-only monitoring - Use this for monitoring without control
  2. Cache channel list - Channels don't change frequently
  3. Filter by status - Focus on active channels for routing
  4. Track payments - Monitor for payment reconciliation

← Back to API Reference | Next: Events & Subscriptions →


Copyright © 2025