LibertyNetLibertyNet 开发者
尚未翻译本页还没有翻译成简体中文,所以你看到的是英文原文。不是因为它不重要——只是还没有人写。欢迎贡献翻译。 帮忙翻译这一页

Nodes and discovery

How nodes announce themselves, what capabilities mean, and the difference between registered and online.

The registry is a directory, not a gatekeeper. It records what nodes claim about themselves. It does not vouch for any of it — that part is your job, and it is cheap.

Reading it needs no key and no account. 已实现

A node record

json
{
  "did": "did:svrp:df9d4b9f390bc49b2210eca81ca3c54c4d63b37b739442a21e28f2ed5b8aa02d",
  "public_key": "df9d4b9f390bc49b2210eca81ca3c54c4d63b37b739442a21e28f2ed5b8aa02d",
  "endpoint": "172.20.10.5:55785",
  "capabilities": ["inference", "health:ready"],
  "region": "asia-southeast",
  "status": "active",
  "last_seen": "2026-07-31T16:33:08Z",
  "first_seen": "2026-07-28T11:49:46Z",
  "signature": null
}
FieldWhat it actually tells you
did · public_keyThe identity claim. Verify it — this is the one thing you can check for yourself.
endpointWhere the node says it can be reached. Often a private address; the registry does not test reachability.
capabilitiesFree-form strings the node chose. Advertising is not proof of ability.
regionSelf-reported. May be null.
statusNearly meaningless — see below.
last_seenThe only field that goes stale. This is your freshness signal.
first_seenWhen the registry first heard from it.

Registered ≠ online

警告

status: "active" does not mean the node is running.

A node that was unplugged a week ago is still "active" in this table. Nothing sets it back. The field describes an administrative state, not a live one.

The only field that decays is last_seen. A node refreshes it by heart-beating; when the node stops, the timestamp stops moving and that is how you know.

typescript
// Wrong — includes nodes that vanished a week ago
const nodes = await ln.discovery.all();

// Right — verified AND heard from recently
const nodes = await ln.discovery.online();               // default: 10 minutes
const strict = await ln.discovery.online({ freshnessMs: 60_000 });

Choosing a freshness window is a real decision. Ten minutes is a reasonable default for "probably still there". If you are about to send work somewhere and care about latency, use a much tighter window — and be ready for the node to have gone anyway, because a timestamp is a description of the past.

Capabilities

Capabilities are free-form strings a node chooses for itself.

CapabilitySeen on the live network?
inferenceYes
health:readyYes — a liveness marker rather than a service
storage · verification · proof · solver · oracleDeclared in the spec; not yet observed in the wild
注意

Advertising a capability is a claim, not a credential. Nothing in the registry verifies that a node advertising inference can actually perform inference, or will do it correctly. Treat capabilities as a filter for who to try, never as a guarantee about what you will get back. Verify results on their own merits.

typescript
const workers = await ln.discovery.byCapability("inference", {
  region: "asia-southeast",
  freshnessMs: 120_000,
});

Registration and heartbeats

Nodes call these themselves — ln-node handles it. They are documented because self-hosted and experimental nodes need the exact contract.

EndpointPurpose
POST /api/v1/register 已实现Announce identity, endpoint, capabilities.
POST /api/v1/heartbeat 已实现Refresh last_seen.
警告

Signature verification on registration currently runs in grace mode: a malformed signature is recorded rather than rejected during the beta. Do not build anything on the assumption that a record's presence in the table implies a checked signature. Verify id-binding yourself — which costs one hash and works regardless of what the registry did.

Auditing instead of filtering

discovery.all() and online() drop records that fail verification, because a caller who must remember to check a flag is a caller who will forget.

When you specifically want to see the failures — monitoring, security work — ask for them:

typescript
const { total, verified, rejected } = await ln.discovery.audit();

if (rejected.length) {
  // Not a nuisance to skip quietly. Report it.
  console.error(`${rejected.length} records failed id-binding`, rejected.map((n) => n.did));
}

As of the last live check, 27 of 27 records on the production registry verified. If that ever stops being true, something is wrong that is worth knowing about immediately — which is why the SDK ships a live test asserting it.

Endpoints are not guarantees

endpoint is where a node says it can be reached. In practice many are private addresses (172.20.10.5:55785 above), reachable only inside their own network. The registry does not probe them.

Plan for: unreachable endpoints, addresses that changed since registration, and nodes behind NAT that can dial out but not receive. Discovery tells you a node exists and what it claims — connectivity is a separate problem.

Next: binding

How a node and an operator agree to work together, in four signatures.