@xyo-network/event-kit-cli
Requires Node 26 or newer; the repository pins Node 26.9.0.
The installed binary composes the public Node handshake clients over pinned XL1 Gateway sessions, finalized Statement Graph replay, and the selected public datalake.
Commands
event-kit publisher service publish|show|rotate-key|retire
event-kit publisher key show
event-kit publisher subscription show|challenge|accept
event-kit subscriber service show
event-kit subscriber subscription subscribe|show|revoke
event-kit publisher run --config publisher.json
Discovery commands require --publisher. Exact subscription discovery and the
publisher challenge/accept flow also require independent --subscriber and
--subscription selectors. Reads do not require a seed.
--replay-floor-block <n> selects an explicit trusted authorization bootstrap
boundary and is embedded in durable replay identity. The default is genesis.
With a nonzero floor, the first service publication must set validFromBlock
at or after that floor; this mode does not claim complete pre-floor history.
Writes require --seed-file <path> and optionally --account-index <n>. The
seed file must be a regular, non-symlink file with no group or other permission
bits. Publisher writes require the derived signer to be the publisher Claim
source; subscriber writes require it to be the subscriber Claim source.
Generated writes (service publish, service rotate-key, and subscription subscribe) also require --operation-id <32-lowercase-hex>. Generate a fresh
random operation ID for each new logical mutation and retain it for every retry.
Reusing the same ID with changed semantic input fails closed; an exact retry
returns intentDisposition: "resumed" and republishes or reconciles the same
canonical objects and signed XL1 transaction. Acceptance uses its challenge
hash as the operation ID, while retirement and revocation use the target object
hash, so those commands do not accept a separate flag.
Service publication reads a strict public JSON object:
{
"deliveryMode": "durable",
"sources": [{ "kind": "xl1-finalized", "chainId": "<40 lowercase hex source chain ID>" }],
"maxPositionsPerWake": 32,
"maxSubscriptionLifetimeBlocks": 100000
}
Subscription publication reads a strict, permission-restricted JSON object.
The endpoint, audience, and challengeSecret values are encrypted by the
public client and are never returned by the CLI:
{
"deliveryMode": "durable",
"audience": "my-indexer",
"challengeSecret": "<32-byte unpadded base64url>",
"deploymentId": "my-indexer",
"endpoint": "https://subscriber.example/event-kit/wake",
"source": { "kind": "xl1-finalized", "chainId": "<40 lowercase hex source chain ID>" },
"fromPosition": 0,
"maxPositionsPerWake": 32,
"expiresAtBlock": 100000
}
publisher subscription challenge validates/decrypts the selected finalized
tuple and durably begins its one permitted challenge attempt. It prints only
the public challenge and selector hashes: it performs no HTTP request and never
prints the decrypted target. Convey that challenge to the subscriber through
the operator's chosen private channel. publisher subscription accept then
requires --input <response.json> containing the endpoint proof:
{
"schema": "network.xyo.event.wake.challenge.response",
"challenge": "<challenge object hash>",
"proof": "<32-byte unpadded base64url>"
}
Network and state
Use --network local|sequence|mainnet to choose a read profile. Write commands
delegate to the XL1 publication boundary. Local commands require an explicit
--chain-id; Sequence and Mainnet identities come from the released SDK.
--rpc-url and --datalake-url replace endpoints, never chain identity. Every
session is checked against the selected chain before and after replay.
Mainnet reads are available. Mainnet writes are rejected by the XL1 boundary
before the CLI reads a seed file or constructs a signer/datalake writer; there
is no bypass flag. publisher run --network mainnet only delivers
(D-008). It reads
the seed to sign wakes, opens no signer, datalake writer or publication, and leaves
challenges and acceptance to the Phase 7 host.
--state-dir defaults to ./event-kit-state. Replay checkpoints, publication
journals, mutation intents, publisher encryption-key custody, and challenge
records are isolated under the selected network, exact chain ID, and publisher
address in a private SQLite authority. The CLI rejects legacy filesystem state
rather than silently abandoning encryption custody or publication recovery.
Mutation intents are immutable private records. Publisher service/key
intents retain the generated encryption private key for recovery; subscriber
intents retain the exact grant and ciphertext plus a private-input fingerprint,
never the endpoint or challenge-secret plaintext. Protect and back up this
directory as secret operational state.
Use --json for one machine-readable result containing only selected public
hashes, identities, finalized blocks, and lifecycle evidence.
Resident runtime
publisher run --config publisher.json now composes persistent SQLite state,
real account signing, finalized D-005 discovery/challenge/acceptance/revocation,
bounded HTTPS delivery, and loopback health probes. The source contract supports finalized
XL1, finalized Ethereum, and completed fixed UTC intervals. See the
resident publisher runbook for configuration,
the handshake commands, Vercel Preview credentials,
recovery, and the remaining credentialed qualification gates.
There is one unversioned wire contract. --event-kind, version-suffixed schemas,
and maxBlocksPerWake are rejected; use explicit sources and source positions.
XL1 acceptance height establishes authorization eligibility, while the
subscription's fromPosition establishes where source catch-up begins.
Prepared Best Effort 2.0.0
Service and subscription JSON require deliveryMode: "best-effort", matching
bestEffort: {"refreshIntervalSeconds":30,"maxHintAgeSeconds":300,"maxAttempts":3}
and maxPositionsPerWake: 1. The native existing publish/subscribe commands
continue to use --input, required fresh --operation-id, pinned network and
private --seed-file; mode/policy are exact strict JSON fields, not new wire IDs.
To use a newly reviewed authorization projection while preserving the same SQLite owner/custody directory, all handshake commands support:
--replay-namespace ces-best-effort-v2 --replay-floor-block <H+1>
--replay-start-anchor-block <H> --replay-start-anchor-hash <rootH>
The native reader verifies exact finalized H/rootH, starts empty at H, and reads
authority from H+1. New service/key/grant/subscription/acceptance claims must
finalize after H. Use a new service ID and revision 1, with no legacy supersedes
link or implicit old authority. The corresponding runtime config fields are
authorizationReplayNamespace, authorizationFloorBlock, and
authorizationStartAnchor: {"block":H,"hash":"rootH"}. Keep publisher identity,
seed, state directory and historic keys/checkpoints/intents unchanged.
Best Effort HTTP success returns bounded admissionId, eventHash, wakeId,
acceptedAt, expiresAt; it never claims a durable receiptId. Receiver source
verification and application progress must be observed independently.