@xyo-network/event-kit-cli
v1.0.1
Published
Node 24+ CLI for Event Kit handshakes and a persistent source-aware event publisher
Readme
@xyo-network/event-kit-cli
Requires Node 24 or newer; Node 24.14.1 is the verified baseline.
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.jsonDiscovery 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:
{
"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:
{
"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.
--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.
