@cello-protocol/daemon 0.0.16 → 0.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +102 -1
- package/dist/daemon.js.map +1 -1
- package/dist/network-directory-node.d.ts +18 -0
- package/dist/network-directory-node.d.ts.map +1 -1
- package/dist/network-directory-node.js +107 -1
- package/dist/network-directory-node.js.map +1 -1
- package/dist/relay-receipt-store.d.ts +97 -0
- package/dist/relay-receipt-store.d.ts.map +1 -0
- package/dist/relay-receipt-store.js +203 -0
- package/dist/relay-receipt-store.js.map +1 -0
- package/dist/session-assignment-parser.d.ts.map +1 -1
- package/dist/session-assignment-parser.js +7 -0
- package/dist/session-assignment-parser.js.map +1 -1
- package/dist/session-ceremony.d.ts +13 -4
- package/dist/session-ceremony.d.ts.map +1 -1
- package/dist/session-ceremony.js +95 -5
- package/dist/session-ceremony.js.map +1 -1
- package/dist/session-node-manager.d.ts +21 -0
- package/dist/session-node-manager.d.ts.map +1 -1
- package/dist/session-node-manager.js +39 -1
- package/dist/session-node-manager.js.map +1 -1
- package/dist/session-relay-client.d.ts +31 -1
- package/dist/session-relay-client.d.ts.map +1 -1
- package/dist/session-relay-client.js +282 -7
- package/dist/session-relay-client.js.map +1 -1
- package/dist/session-seal-leaf-store.d.ts +54 -0
- package/dist/session-seal-leaf-store.d.ts.map +1 -0
- package/dist/session-seal-leaf-store.js +70 -0
- package/dist/session-seal-leaf-store.js.map +1 -0
- package/package.json +4 -4
package/dist/daemon.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAKH,OAAO,KAAK,EACV,YAAY,EACZ,oBAAoB,EAQrB,MAAM,YAAY,CAAC;AAIpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAM/D,OAAO,EAAoD,KAAK,SAAS,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAKH,OAAO,KAAK,EACV,YAAY,EACZ,oBAAoB,EAQrB,MAAM,YAAY,CAAC;AAIpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAM/D,OAAO,EAAoD,KAAK,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAqB7G,OAAO,KAAK,EAAE,kBAAkB,EAA+C,MAAM,yBAAyB,CAAC;AAM/G,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAqInF,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,SAAS,IAAI,oBAAoB,CAAC;IAClC;;;;OAIG;IACH,qBAAqB,IAAI,kBAAkB,CAAC;IAC5C;;;;;;;;OAQG;IACH,gBAAgB,IAAI,SAAS,GAAG,IAAI,CAAC;IACrC;;;;OAIG;IACH,oBAAoB,IAAI,kBAAkB,CAAC;IAC3C;;;OAGG;IACH,iBAAiB,IAAI,eAAe,CAAC;CACtC;AAyCD,wBAAsB,WAAW,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAg6H7E"}
|
package/dist/daemon.js
CHANGED
|
@@ -51,7 +51,7 @@ import { MAX_CONTENT_BYTES, computeGenesisPrevRoot, buildAgentRevocationTbs } fr
|
|
|
51
51
|
import { resolveCelloEnv, createTransportSelector, isProductionVariant, } from "./transport-composition.js";
|
|
52
52
|
import { selectAdvertisedAddress } from "./transport-selector.js";
|
|
53
53
|
import { parseSessionAssignment, sessionRequestErrorReason } from "./session-assignment-parser.js";
|
|
54
|
-
import { wireSessionCeremonyHandler, wireSessionOfferHandler, wireSealCeremonyHandler, verifyUnilateralCertificate, verifyBilateralSealCertificate } from "./session-ceremony.js";
|
|
54
|
+
import { wireSessionCeremonyHandler, wireSessionOfferHandler, wireSealCeremonyHandler, verifyUnilateralCertificate, verifyBilateralSealCertificate, runAgentRefresh } from "./session-ceremony.js";
|
|
55
55
|
import { reDeriveFrontiers, findInflatedFrontier } from "./seal-frontier-verify.js";
|
|
56
56
|
import { LocalAutoNatStub } from "@cello-protocol/transport";
|
|
57
57
|
import { startHttpManifestPoll } from "./http-manifest-poll.js";
|
|
@@ -387,12 +387,42 @@ export async function startDaemon(config) {
|
|
|
387
387
|
if (!kp || !endpoint || !endpoint.peer_id || !endpoint.multiaddrs || endpoint.multiaddrs.length === 0) {
|
|
388
388
|
return undefined;
|
|
389
389
|
}
|
|
390
|
+
// FED-OPTIONB-SETUP-001 (Option B): when the directory included the per-node relay-assignment
|
|
391
|
+
// signature, carry the assignment so the client presents it to its chosen relay (replacing the
|
|
392
|
+
// directory→relay dial). Built only for relay-mode assignments that carry relay_directory_signature;
|
|
393
|
+
// absent ⇒ the client skips client_record_assignment (direct/legacy/pre-M8B).
|
|
394
|
+
const relayDirSig = assignment.relay_directory_signature;
|
|
395
|
+
// FED-OPTIONB-SETUP-001 (fallback-finder #1/#5): a relay-mode assignment MUST carry a
|
|
396
|
+
// relay_directory_signature — the directory always signs one. If it is absent or malformed (the
|
|
397
|
+
// parser dropped it to undefined) for a relay-mode session, the session silently degrades to "no
|
|
398
|
+
// relay witness" and looks indistinguishable from a legitimate direct-mode session. Warn LOUD so the
|
|
399
|
+
// missing/corrupt witness has a named cause (this is the only diagnosable signal on a PURE RECEIVER,
|
|
400
|
+
// which never submits and so never surfaces relay_unavailable). Unwitnessed is an allowed sovereign-
|
|
401
|
+
// redundancy state, but it must not be invisible.
|
|
402
|
+
if (assignment.transport_mode === "relay" && !relayDirSig) {
|
|
403
|
+
logger.warn("session.relay.assignment.signature.missing", {
|
|
404
|
+
agentName,
|
|
405
|
+
sessionId: Buffer.from(assignment.session_id).toString("hex").slice(0, 16),
|
|
406
|
+
reason: "relay_mode_assignment_without_directory_signature",
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
const carry = relayDirSig
|
|
410
|
+
? {
|
|
411
|
+
participantA: assignment.participant_a.pubkey,
|
|
412
|
+
participantB: assignment.participant_b.pubkey,
|
|
413
|
+
sessionTimestamp: assignment.session_timestamp,
|
|
414
|
+
initiatorSessionPeerId: assignment.initiator_session_peer_id,
|
|
415
|
+
counterpartySessionPeerId: assignment.counterparty_session_peer_id,
|
|
416
|
+
assignmentSignature: relayDirSig,
|
|
417
|
+
}
|
|
418
|
+
: undefined;
|
|
390
419
|
return {
|
|
391
420
|
relayPeerId: endpoint.peer_id,
|
|
392
421
|
relayAddrs: endpoint.multiaddrs,
|
|
393
422
|
keyProvider: kp,
|
|
394
423
|
senderPubkey: await kp.getPublicKey(),
|
|
395
424
|
sessionIdBytes: assignment.session_id,
|
|
425
|
+
assignment: carry,
|
|
396
426
|
};
|
|
397
427
|
};
|
|
398
428
|
// Stub: all connections marked as 'unverified' until connection validation is wired
|
|
@@ -1776,6 +1806,60 @@ export async function startDaemon(config) {
|
|
|
1776
1806
|
void attemptSealUpgrade(signaling, agentName, agentPubkeyHex, sidHex, frame);
|
|
1777
1807
|
});
|
|
1778
1808
|
}
|
|
1809
|
+
// ─── M8B DOD-REFRESH-1: cello_refresh_shares — proactive share refresh / epoch rollover ───
|
|
1810
|
+
handlers.set("cello_refresh_shares", async (params, connectionId) => {
|
|
1811
|
+
const connState = perConnectionState.get(connectionId);
|
|
1812
|
+
const agentName = params?.name ?? connState?.currentAgent;
|
|
1813
|
+
if (!agentName) {
|
|
1814
|
+
return { ok: false, reason: "no_current_agent", guidance: "Select an agent with cello_use_agent, or pass { name }." };
|
|
1815
|
+
}
|
|
1816
|
+
const loaded = loadedAgents.find((a) => a.name === agentName);
|
|
1817
|
+
if (!loaded) {
|
|
1818
|
+
return { ok: false, reason: "agent_not_found", guidance: `No agent named '${agentName}'. Create + register it first.` };
|
|
1819
|
+
}
|
|
1820
|
+
// The refresh ceremony reaches the consortium over the agent's signaling node — ensure it is up.
|
|
1821
|
+
const entry = getAgentSignaling(agentName, loaded.keyProvider, loaded.pubkey);
|
|
1822
|
+
const connected = await waitForSignalingConnected(entry.signaling, 15_000);
|
|
1823
|
+
if (!connected) {
|
|
1824
|
+
return { ok: false, reason: "directory_unreachable", guidance: "The agent's directory signaling is not connected; start the agent and retry." };
|
|
1825
|
+
}
|
|
1826
|
+
const result = await runAgentRefresh({
|
|
1827
|
+
agentName,
|
|
1828
|
+
persistence: getPersistence(agentName),
|
|
1829
|
+
agentPubkeyHex: loaded.pubkey,
|
|
1830
|
+
getNode: entry.getNode,
|
|
1831
|
+
getDirectoryEndpoint: async () => (directoryEndpointResolver ? (await directoryEndpointResolver()) ?? null : null),
|
|
1832
|
+
getConsortiumEndpoints: resolveConsortiumRoster,
|
|
1833
|
+
signaling: entry.signaling,
|
|
1834
|
+
logger,
|
|
1835
|
+
});
|
|
1836
|
+
if (!result.ok) {
|
|
1837
|
+
return { ok: false, reason: result.reason, guidance: "Share refresh did not complete — see the daemon log (refresh.ceremony.*) for the cause." };
|
|
1838
|
+
}
|
|
1839
|
+
return { ok: true, epoch: result.toEpochN, primary_pubkey: result.primaryPubkey, verifying_shares_digest: result.verifyingSharesDigest };
|
|
1840
|
+
});
|
|
1841
|
+
// ─── M8B DOD-RELAYSIG-1: cello_get_relay_receipts — the agent's stored relay ordering receipts ───
|
|
1842
|
+
handlers.set("cello_get_relay_receipts", async (params, connectionId) => {
|
|
1843
|
+
const connState = perConnectionState.get(connectionId);
|
|
1844
|
+
const agentName = params?.name ?? connState?.currentAgent;
|
|
1845
|
+
if (!agentName) {
|
|
1846
|
+
return { ok: false, reason: "no_current_agent", guidance: "Select an agent with cello_use_agent, or pass { name }." };
|
|
1847
|
+
}
|
|
1848
|
+
const loaded = loadedAgents.find((a) => a.name === agentName);
|
|
1849
|
+
if (!loaded) {
|
|
1850
|
+
return { ok: false, reason: "agent_not_found", guidance: `No agent named '${agentName}'.` };
|
|
1851
|
+
}
|
|
1852
|
+
const sessionIdHex = typeof params?.session_id === "string" ? params.session_id : undefined;
|
|
1853
|
+
const receipts = sessionNodeManager.getRelayReceipts(loaded.pubkey, sessionIdHex).map((r) => ({
|
|
1854
|
+
hash_hex: r.hashHex,
|
|
1855
|
+
session_id: r.sessionIdHex,
|
|
1856
|
+
relay_id: r.relayId,
|
|
1857
|
+
sequence_number: r.sequenceNumber,
|
|
1858
|
+
timestamp: r.timestamp,
|
|
1859
|
+
signature_hex: r.signatureHex,
|
|
1860
|
+
}));
|
|
1861
|
+
return { ok: true, receipts };
|
|
1862
|
+
});
|
|
1779
1863
|
// ─── MCP-001: cello_status (per-connection perspective) ───
|
|
1780
1864
|
handlers.set("cello_status", async (_params, connectionId) => {
|
|
1781
1865
|
return {
|
|
@@ -2082,11 +2166,28 @@ export async function startDaemon(config) {
|
|
|
2082
2166
|
let resolveUni;
|
|
2083
2167
|
const uniP = new Promise((r) => { resolveUni = r; });
|
|
2084
2168
|
pendingUnilateralWaiters.set(sessionId, resolveUni);
|
|
2169
|
+
// FED-OPTIONB-SEAL-001 (Option B): carry the full leaf chain (both parties) + the relay receipts so
|
|
2170
|
+
// the directory rebuilds + verifies the tree OFFLINE — no directory→relay getSealLeaves dial. The
|
|
2171
|
+
// store is keyed by the agent's K_local pubkey (the same key the relay client recorded under).
|
|
2172
|
+
const sealAgentKp = keyProviders.get(record.agent_name);
|
|
2173
|
+
const sealAgentPubkeyHex = sealAgentKp ? Buffer.from(await sealAgentKp.getPublicKey()).toString("hex") : "";
|
|
2174
|
+
const sealCarry = sealAgentPubkeyHex ? sessionNodeManager.getSealCarry(sealAgentPubkeyHex, sessionId) : [];
|
|
2175
|
+
const seal_leaves = sealCarry.map((l) => ({
|
|
2176
|
+
sequence_number: l.sequenceNumber,
|
|
2177
|
+
leaf_kind: l.leafKind,
|
|
2178
|
+
structure2_cbor: l.structure2Cbor,
|
|
2179
|
+
structure1_cbor: l.structure1Cbor,
|
|
2180
|
+
// Relay receipt (present only for the present party's OWN leaves — the seq-pinning teeth).
|
|
2181
|
+
relay_id: l.relayId,
|
|
2182
|
+
relay_timestamp: l.relayTimestamp,
|
|
2183
|
+
relay_signature: l.relaySignatureHex ? new Uint8Array(Buffer.from(l.relaySignatureHex, "hex")) : undefined,
|
|
2184
|
+
}));
|
|
2085
2185
|
const sent = await sendOver(record.agent_name, {
|
|
2086
2186
|
type: "seal_unilateral",
|
|
2087
2187
|
session_id: new Uint8Array(Buffer.from(sessionId, "hex")),
|
|
2088
2188
|
reported_root: new Uint8Array(Buffer.from(submit.reportedRootHex, "hex")),
|
|
2089
2189
|
reported_seq: submit.sequenceNumber,
|
|
2190
|
+
seal_leaves,
|
|
2090
2191
|
});
|
|
2091
2192
|
if (!sent.ok) {
|
|
2092
2193
|
pendingUnilateralWaiters.delete(sessionId);
|