Summary
Add a new @didcid/cl-hive package that provides a TypeScript client for interacting with the CLN node's REST API (clnrest plugin). This is the foundational package that enables Archon services to programmatically use the Lightning node deployed in #57.
Motivation
The cl-hive Docker container (#57) is running, but no Archon service can talk to it. This package bridges that gap — it wraps the clnrest API with a typed TypeScript client that other packages and services can depend on.
This is a prerequisite for:
Design
CLN REST API (clnrest)
The cl-hive container exposes clnrest on port 3001 (bound to localhost). Authentication uses CLN runes — bearer tokens with macaroon-like caveats. The API maps 1:1 to CLN's JSON-RPC commands via HTTP POST.
Package Scope
Wrap the subset of clnrest endpoints that Archon needs, not the entire CLN API. Start minimal, expand as needed.
Core (needed for L402 and basic operations):
getinfo — node pubkey, alias, network, block height, peers
invoice — create a Lightning invoice (amount, label, description)
listinvoices — check invoice status by payment_hash or label
waitinvoice — wait for invoice payment (long-poll)
pay — pay a BOLT11 invoice
keysend — send a keysend payment (for TLV-encoded data)
Identity:
getinfo pubkey extraction for DID binding
Utility:
listnodes — peer info
listfunds — on-chain and channel balances
listchannels — channel state
Package Structure
Following the @didcid/cipher / @didcid/ipfs pattern:
packages/cl-hive/
├── package.json
├── tsconfig.json
├── rollup.cjs.config.js
└── src/
├── index.ts # public API re-exports
├── types.ts # ClnConfig, Invoice, Payment, NodeInfo, etc.
├── errors.ts # ClnError, ClnConnectionError, ClnAuthError, RuneError
├── cl-hive-client.ts # main client class
└── rune.ts # rune handling utilities
Client API
import { ClnClient } from '@didcid/cl-hive';
const cln = new ClnClient({
restUrl: 'http://localhost:3001',
rune: process.env.ARCHON_CLN_RUNE,
});
// Node identity
const info = await cln.getInfo();
// info.id = "02abc...def" (node pubkey)
// Create invoice
const invoice = await cln.createInvoice({
amountMsat: 1000000, // 1000 sats
label: 'did-registration-001',
description: 'DID registration on BTC:mainnet',
});
// invoice.bolt11, invoice.paymentHash, invoice.expiresAt
// Check payment
const status = await cln.getInvoice(invoice.paymentHash);
// status.status = 'paid' | 'unpaid' | 'expired'
// Wait for payment
const paid = await cln.waitForInvoice(invoice.label);
// paid.preimage, paid.amountReceivedMsat
// Pay an invoice
const payment = await cln.pay(bolt11String);
// Balances
const funds = await cln.listFunds();
Authentication
clnrest uses runes for auth, passed via HTTP header:
The rune should be created with appropriate restrictions (e.g., read-only for monitoring, invoice-only for L402). The client accepts the rune via ClnConfig and attaches it to every request.
Configuration
New env vars:
ARCHON_CLN_REST_URL=http://localhost:3001
ARCHON_CLN_RUNE=<rune-string>
For Docker deployments, the gatekeeper/keymaster services would reach CLN at http://cln-mainnet-node:3001.
Dependencies
axios (already in monorepo) — HTTP client for clnrest API
@didcid/common — error types
No new external dependencies required.
Tests
tests/cl-hive/
├── helper.ts # mock clnrest responses
├── cl-hive-client.test.ts # client methods with nock-mocked API
├── rune.test.ts # rune handling
└── errors.test.ts # error mapping from CLN API errors
Use nock (already a dev dependency) to mock the clnrest HTTP API.
Monorepo Integration
| File |
Change |
packages/cl-hive/ |
New package (all files above) |
package.json (root) |
Add @didcid/cl-hive to build script (after @didcid/common) |
tsconfig.json (root) |
Add @didcid/cl-hive path mappings |
jest.config.js |
Add @didcid/cl-hive moduleNameMapper |
sample.env |
Add ARCHON_CLN_REST_URL, ARCHON_CLN_RUNE |
docker-compose.yml |
Pass CLN env vars to gatekeeper/keymaster services |
Blocked By
None — cl-hive Docker service is already running (#57).
Enables
Summary
Add a new
@didcid/cl-hivepackage that provides a TypeScript client for interacting with the CLN node's REST API (clnrest plugin). This is the foundational package that enables Archon services to programmatically use the Lightning node deployed in #57.Motivation
The cl-hive Docker container (#57) is running, but no Archon service can talk to it. This package bridges that gap — it wraps the clnrest API with a typed TypeScript client that other packages and services can depend on.
This is a prerequisite for:
Design
CLN REST API (clnrest)
The cl-hive container exposes clnrest on port 3001 (bound to localhost). Authentication uses CLN runes — bearer tokens with macaroon-like caveats. The API maps 1:1 to CLN's JSON-RPC commands via HTTP POST.
Package Scope
Wrap the subset of clnrest endpoints that Archon needs, not the entire CLN API. Start minimal, expand as needed.
Core (needed for L402 and basic operations):
getinfo— node pubkey, alias, network, block height, peersinvoice— create a Lightning invoice (amount, label, description)listinvoices— check invoice status by payment_hash or labelwaitinvoice— wait for invoice payment (long-poll)pay— pay a BOLT11 invoicekeysend— send a keysend payment (for TLV-encoded data)Identity:
getinfopubkey extraction for DID bindingUtility:
listnodes— peer infolistfunds— on-chain and channel balanceslistchannels— channel statePackage Structure
Following the
@didcid/cipher/@didcid/ipfspattern:Client API
Authentication
clnrest uses runes for auth, passed via HTTP header:
The rune should be created with appropriate restrictions (e.g., read-only for monitoring, invoice-only for L402). The client accepts the rune via
ClnConfigand attaches it to every request.Configuration
New env vars:
For Docker deployments, the gatekeeper/keymaster services would reach CLN at
http://cln-mainnet-node:3001.Dependencies
axios(already in monorepo) — HTTP client for clnrest API@didcid/common— error typesNo new external dependencies required.
Tests
Use
nock(already a dev dependency) to mock the clnrest HTTP API.Monorepo Integration
packages/cl-hive/package.json(root)@didcid/cl-hiveto build script (after@didcid/common)tsconfig.json(root)@didcid/cl-hivepath mappingsjest.config.js@didcid/cl-hivemoduleNameMappersample.envARCHON_CLN_REST_URL,ARCHON_CLN_RUNEdocker-compose.ymlBlocked By
None — cl-hive Docker service is already running (#57).
Enables
@didcid/l402depends on this for Lightning invoice operations