Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.xandrlabs.ai/llms.txt

Use this file to discover all available pages before exploring further.

ALX Protocol gives you a deterministic, content-addressed identity layer for Knowledge Blocks (KBs). Every KB you publish on-chain is derived from its canonical content: same payload, same sources, same kbHash — always. This guide takes you from a fresh install to your first on-chain KB publication in six steps.
1

Install @alx/protocol

Add the package using your preferred package manager.
npm install @alx/protocol ethers
ethers is required only for the on-chain publication step. If you only need hashing and CID derivation, @alx/protocol has no peer dependencies.
2

Compute the KB identity

A KB’s identity hash (kbHash) is derived deterministically from a normalized, canonicalized envelope. Import kbHashFromEnvelope and construct your envelope with the four required fields — type, domain, sources, and payload — plus an artifactHash (computed in the next step).
import { kbHashFromEnvelope, artifactHashFromPayload } from "@alx/protocol";

// Define the type-specific payload
const payload = {
  type: "practice" as const,
  rationale: "Rotate signing keys every 90 days to limit exposure.",
  contexts: [{ env: "production" }],
  failureModes: [{ condition: "unsigned_keys_present", severity: "critical" }],
};

// Compute the artifact hash from the payload (keccak256 of its canonical JSON)
const artifactHash = artifactHashFromPayload(payload);

// Construct the canonical envelope
const envelope = {
  type: payload.type,
  domain: "engineering.auth.jwt",
  sources: [] as string[],         // parent kbIds, empty for an original KB
  artifactHash,
  tier: "open" as const,
  payload,
};

// Derive the KB identity hash (domain-separated: keccak256("KB_V1" + JCS(envelope)))
const kbHash = kbHashFromEnvelope(envelope);

console.log("kbHash:", kbHash);
// 0x...
kbHashFromEnvelope applies RFC 8785 (JCS) canonicalization, sorts sources alphabetically, and prepends the KB_V1 domain tag before hashing. Never hash the envelope yourself — use this function to stay conformant.
3

Compute the artifact hash

The artifact hash records the integrity of the full artifact JSON as it will be stored on IPFS. You can derive it directly from the payload using artifactHashFromPayload (already done above), or compute it manually using the sha256 approach if you need to match a pre-serialized artifact file.
import { artifactHashFromPayload } from "@alx/protocol";

// keccak256 of the JCS-canonicalized payload
const artifactHash = artifactHashFromPayload(payload);
The two methods target different use cases. Use artifactHashFromPayload when you’re building the envelope from scratch. Use the sha256 approach when you already have a serialized artifact file and need to reproduce the hash that the registry stores.
4

Derive the CID

The CID is a content-addressed identifier for the canonical envelope on IPFS. Use cidV1FromCanonicalSync for synchronous environments (Node.js, protocol tooling) or cidV1FromCanonical for async contexts such as browsers.
import { canonicalize, cidV1FromCanonicalSync } from "@alx/protocol";

// Canonicalize the envelope with the same normalization used for kbHash
const canonicalJson = canonicalize(envelope);

// Derive a CIDv1 (raw codec 0x55, sha2-256 multihash)
const rootCid = cidV1FromCanonicalSync(canonicalJson);

console.log("rootCid:", rootCid);
// bafkrei...
Pin rootCid to IPFS before calling publishKB. The registry records the CID but does not upload content — retrieval depends on IPFS availability.
5

Publish on-chain

Call publishKB on the ALX registry contract on Base mainnet. You need a funded signer and at least 0.001 ETH to cover the minimum stake.
import { ethers } from "ethers";
import { REGISTRY_ABI } from "@alx/protocol";

const CONTRACT_ADDRESS = "0xD1F216E872a9ed4b90E364825869c2F377155B29";

// Connect to Base mainnet (chain ID 8453)
const provider = new ethers.JsonRpcProvider("https://mainnet.base.org");
const signer = new ethers.Wallet(process.env.PRIVATE_KEY!, provider);

const registry = new ethers.Contract(CONTRACT_ADDRESS, REGISTRY_ABI, signer);

// KB type values:
// 0 = Practice | 1 = Feature | 2 = StateMachine
// 3 = PromptEngineering | 4 = ComplianceChecklist | 5 = Rubric
const kbType = 0;         // Practice
const parentIds: string[] = [];  // bytes32[] — up to 8 parent kbIds
const royaltyBps = 500;   // 5% (basis points, 0–10000)

const tx = await registry.publishKB(
  kbHash,       // bytes32 — KB identity hash
  rootCid,      // string  — IPFS CIDv1 of the canonical envelope
  kbType,       // uint8   — KB type enum value
  parentIds,    // bytes32[] — lineage parents (max 8)
  royaltyBps,   // uint16  — royalty in basis points
  { value: ethers.parseEther("0.001") }  // minimum stake
);

const receipt = await tx.wait();
console.log("Published in block:", receipt.blockNumber);
parentIds is capped at 8 entries. Passing more than 8 will cause the transaction to revert. Each entry must be a 0x-prefixed 32-byte hex string.
6

Verify the result

After the transaction confirms, cross-check the on-chain artifact hash against the hash you computed locally.
import { verifyKBArtifact } from "@alx/protocol";

// Recompute and verify off-chain
const result = await verifyKBArtifact({ artifact, manifest });

console.log("valid:", result.valid);
console.log("kbHash match:", result.kbHash === kbHash);
console.log("artifactHash match:", result.artifactHash === artifactHash);

// Cross-check against what the registry stored
const onChainArtifactHash = await registry.getArtifactHash(kbHash);
const consistent = onChainArtifactHash === artifactHash;

console.log("on-chain consistent:", consistent);
If result.valid is true and consistent is true, your KB is correctly published and verifiable by anyone with the artifact.
Contract details
  • Registry address (Base mainnet): 0xD1F216E872a9ed4b90E364825869c2F377155B29
  • Chain ID: 8453
  • Minimum stake: 0.001 ETH (required with every publishKB call)
The protocol fee is 2% (200 bps). Royalties accumulate in pendingWithdrawals and are withdrawn via a separate pull-based call.

Next steps

Verify an artifact

Recompute and validate KB identity and artifact integrity against on-chain data.

Signed requests

Authenticate protocol interactions with EIP-712 typed signatures.

Lineage and attribution

Understand the KB attribution DAG, parent references, and royalty distribution.