From 9d759e51f3f74ae2ecbf2416d8ee11d3293fb7e0 Mon Sep 17 00:00:00 2001 From: Nuruddin Kabir <105130763+Annoor24@users.noreply.github.com> Date: Sat, 26 Sep 2026 06:25:25 +0100 Subject: [PATCH] docs: add a chain and package compatibility matrix --- docs.json | 1 + package.json | 3 +- reference/compatibility-matrix.mdx | 145 +++++++++++++++++++++++++ scripts/check-compatibility-matrix.mjs | 108 ++++++++++++++++++ 4 files changed, 256 insertions(+), 1 deletion(-) create mode 100644 reference/compatibility-matrix.mdx create mode 100644 scripts/check-compatibility-matrix.mjs diff --git a/docs.json b/docs.json index 2162368..6f1b6b7 100644 --- a/docs.json +++ b/docs.json @@ -98,6 +98,7 @@ "pages": [ "reference/audits", "reference/auditor-guide", + "reference/compatibility-matrix", "reference/error-codes", "reference/security-disclosure", "reference/sep-compatibility", diff --git a/package.json b/package.json index 7571d05..6bb2665 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "scripts": { "check:snippets": "tsx scripts/check-snippets.ts", "check:nav-coverage": "node scripts/check-nav-coverage.mjs", + "check:compatibility-matrix": "node scripts/check-compatibility-matrix.mjs", "check:stellar-testnet": "tsx scripts/check-stellar-testnet-snippets.ts", "generate:stellar-reference": "tsx scripts/generate-stellar-reference.ts", "check:stellar-reference": "tsx scripts/generate-stellar-reference.ts --check --allow-missing", @@ -13,7 +14,7 @@ "test:playground": "playwright test --config scripts/playground/tests/playwright.config.ts", "mint:validate": "mint validate", "mint:broken-links": "mint broken-links", - "test": "npm run check:snippets && npm run check:nav-coverage" + "test": "npm run check:snippets && npm run check:nav-coverage && npm run check:compatibility-matrix" }, "dependencies": { "@solana/web3.js": "^1.95.0", diff --git a/reference/compatibility-matrix.mdx b/reference/compatibility-matrix.mdx new file mode 100644 index 0000000..0c60f4f --- /dev/null +++ b/reference/compatibility-matrix.mdx @@ -0,0 +1,145 @@ +--- +title: "Chain and Package Compatibility Matrix" +description: "Which Wraith SDK entry point, framework packages, contract versions, and deployment IDs belong together on EVM, Stellar, Solana, and CKB" +keywords: "compatibility, matrix, EVM, Stellar, Soroban, Solana, Anchor, CKB, Nervos, viem, stellar-sdk, web3.js, deployments, versions, migration, multi-chain" +--- + +This page answers one question: **which SDK entry point, framework packages, and deployed contracts belong together on each chain?** Use it before starting a multi-chain integration or bumping a dependency, so a version or deployment mismatch surfaces here rather than at runtime. + +Every value below is transcribed from the page that owns it — the generated Stellar reference, the per-chain contracts pages, and the dependency pins in `package.json`. The [sync check](#keeping-this-matrix-in-sync) in CI keeps this page from drifting from those owners. + +## SDK core + +All four chains are served by the same npm package. Only the chain entry point and its optional peer dependency change. + +| Package | Version (pinned by these docs) | Used by | Purpose | +|---|---|---|---| +| `@wraith-protocol/sdk` | `^1.4.5` | All chains | Agent client (root import) plus the four chain entry points | +| `@noble/curves` | direct dependency | EVM, Stellar, Solana, CKB | secp256k1 (EVM, CKB) and ed25519 (Stellar, Solana) curve arithmetic | +| `@noble/hashes` | direct dependency | EVM, Stellar, Solana, CKB | SHA-256, SHA-512, keccak256, blake2b | +| `viem` | direct dependency | EVM, agent client | EVM utilities and address encoding | + +Versions come from this repository's [`package.json`](https://github.com/wraith-protocol/docs/blob/main/package.json); the dependency roles come from [SDK Overview](/sdk/overview#dependencies). + +## Chain and package matrix + +| Chain | `Chain` enum | SDK entry point | Curve | Framework / peer packages | Deployment IDs | Migration notes | +|---|---|---|---|---|---|---| +| EVM (Horizen, Ethereum, Polygon, Base) | `Chain.Horizen`, `Chain.Ethereum`, `Chain.Polygon`, `Chain.Base` | `@wraith-protocol/sdk/chains/evm` | secp256k1 | `viem` (bundled; any signer library works) | [Horizen Testnet table](#evm--horizen-testnet) | [Deployment order and per-chain redeploys](#evm-migration-notes) | +| Stellar | `Chain.Stellar` | `@wraith-protocol/sdk/chains/stellar` | ed25519 | `@stellar/stellar-sdk` `^13.1.0` (optional peer) | [Stellar Testnet table](#stellar--testnet) | [Testnet resets and pending contracts](#stellar-migration-notes) | +| Solana | `Chain.Solana` | `@wraith-protocol/sdk/chains/solana` | ed25519 | `@solana/web3.js` `^1.95.0` (optional peer), Anchor event logs | [Solana table](#solana--devnet) | [PDA and rent model](#solana-migration-notes) | +| CKB | `Chain.CKB` | `@wraith-protocol/sdk/chains/ckb` | secp256k1 | none — native `fetch` RPC plus `@noble/hashes` blake2b | [CKB Testnet table](#ckb--testnet) | [Cell model, no peer dependency](#ckb-migration-notes) | + +The `@stellar/stellar-sdk` and `@solana/web3.js` peer dependencies are only needed when you import their chain module; the CKB module adds none. See [SDK Overview](/sdk/overview#entry-points) for the full export list per entry point. + +--- + +## Deployment IDs + +### EVM — Horizen Testnet + +| Contract | Address | Version | +|---|---|---| +| `ERC5564Announcer` | `0x8AE65c05E7eb48B9bA652781Bc0a3DBA09A484F3` | — | +| `ERC6538Registry` | `0x953E6cEdcdfAe321796e7637d33653F6Ce05c527` | — | +| `WraithSender` | `0x226C5eb4e139D9fa01cc09eA318638b090b12095` | — | +| `WraithNames` | `0x3d46f709a99A3910f52bD292211Eb5D557F882D6` | — | + +`WraithWithdrawer` (EIP-7702 gas sponsorship) is optional and is deployed only on chains that support EIP-7702. These are the addresses currently published on [EVM Contracts](/contracts/evm#deployed-addresses-horizen-testnet); no other EVM network has a published deployment yet. + + + +#### EVM migration notes + +- Deploy order is fixed: announcer → registry → sender (constructor arg: announcer) → names → optional withdrawer. See [Deployment Order](/contracts/evm#deployment-order). +- Adding a new EVM chain means re-running the deploy script on that chain and publishing a new row here; the SDK's `Chain` enum gains a value in the same release. +- `WraithSender` is the only contract with a constructor argument, so a redeploy of the announcer requires redeploying the sender too. + +### Stellar — Testnet + +| Contract | Testnet address | Version | +|---|---|---| +| `stealth-announcer` | `CCJLJ2QRBJAAKIG6ELNQVXLLWMKKWVN5O2FKWUETHZGMPAD4MHK7WVWL` | v2 | +| `stealth-registry` | Pending deployment | v1 | +| `stealth-sender` | Pending deployment | v1 | +| `wraith-names` | `CDEMB3MAE62ZOCCKZPTYSXR5CS5WVENPOU5MDVK4PNKTZXFVDC74AFBV` | v1 | + +Source of truth: `getDeployment("stellar")` via `@wraith-protocol/sdk/chains/stellar`, as published in [Stellar Networks](/reference/stellar-networks#wraith-contract-ids) and the generated section of [Stellar Contracts](/contracts/stellar). Mainnet addresses are still placeholders. + + + +#### Stellar migration notes + +- **Testnet resets roughly quarterly** and wipes all contract state. Re-read the current announcer and names IDs after a reset instead of pinning them in config. See [Stellar Networks → Testnet](/reference/stellar-networks#testnet). +- `stealth-registry` and `stealth-sender` addresses are pending; integrations that need meta-address registration should track `contracts/stellar/MAINNET_READINESS.md` in the contracts repo. +- `stealth-announcer` is on event version **v2**; the SDK's announcement parsing assumes the v2 indexed topics. See [Stellar Event Schemas (v2)](/reference/stellar-event-schemas). +- The decoder-facing differences from EVM (caller auth instead of ECDSA recovery, `getEvents` instead of a subgraph) are tabulated in [Stellar Contracts → Differences from EVM Contracts](/contracts/stellar#differences-from-evm-contracts). + +### Solana — Devnet + +| Program | Program ID | Version | +|---|---|---| +| `wraith-announcer` | Not published in these docs | — | +| `wraith-sender` | Not published in these docs | — | +| `wraith-names` | Not published in these docs | — | + +Program IDs are not yet published in the documentation. Until they are, deploy with `anchor deploy --provider.cluster devnet` and read the IDs from the deploy output; see [Solana Contracts → Deployment](/contracts/solana#deployment). + + + +#### Solana migration notes + +- Names are stored in PDAs rather than contract storage, and accounts need rent-exempt balances; see [Solana Contracts → Differences](/contracts/solana#differences-from-evm-and-stellar-contracts). +- Announcements are parsed from Anchor event logs, so the `@solana/web3.js` peer version must be able to read the deployed program's logs. +- Program upgrades change the program ID's executable data in place; PIN the program ID, not the deployment transaction, in config. + +### CKB — Testnet + +| Script | Identifier | Kind | +|---|---|---| +| `wraith-stealth-lock` | `0xc133817d433f72ea16a2404adaf961524e9572c8378829a21968710d6182e20d` | Code hash (`data2`) | +| `wraith-names-type` | `0xc133817d433f72ea16a2404adaf961524e9572c8378829a21968710d6182e20d` | Code hash (`data2`) | +| Deployment cell dep | `0x9acd640d35eadd893b358dddd415f4061fe81cb249e8ace51a866fee314141b8` | Transaction hash (index 0, `code`) | + +CKB has no separate announcer: the stealth Cell's lock args carry the announcement. The values above are the testnet example published in [CKB Contracts → Deployed Code Hash](/contracts/ckb#deployed-code-hash); confirm them against `getDeployment("ckb")` before mainnet use. + + + +#### CKB migration notes + +- The CKB module has **no optional peer dependency** — RPC calls use native `fetch` and hashing uses the already-bundled `@noble/hashes`. See [CKB Primitives](/sdk/chains/ckb). +- A redeploy produces a **new code hash**, which changes every stealth Cell's `lock.code_hash`. Record the new hash in the SDK's `deployments.ts` as described in [CKB Contracts → Record Deployment Info](/contracts/ckb#record-deployment-info). +- CKB's Cell model has no account layer, so there is nothing analogous to EVM's `createAccount` prerequisite on Stellar. + +--- + +## Known gaps + +| Gap | Chains affected | Tracking | +|---|---|---| +| Mainnet contract addresses not yet published | Stellar | [Stellar Networks → Mainnet](/reference/stellar-networks#mainnet) | +| `stealth-registry` / `stealth-sender` not deployed | Stellar Testnet | [Stellar Networks → Testnet](/reference/stellar-networks#wraith-contract-ids) | +| Program IDs not published in docs | Solana | [Solana Contracts → Deployment](/contracts/solana#deployment) | +| Single published EVM deployment (Horizen Testnet) | EVM | [EVM Contracts → Deployed Addresses](/contracts/evm#deployed-addresses-horizen-testnet) | + +## Keeping this matrix in sync + +The deployment identifiers on this page are checked in CI against the pages that own them: + +```bash +npm run check:compatibility-matrix +``` + +The check extracts every `0x…` address/code hash and `C…` strkey from this page and fails if one of them is not also present in `contracts/evm.mdx`, `contracts/stellar.mdx`, `contracts/solana.mdx`, `contracts/ckb.mdx`, `reference/stellar-networks.mdx`, or the `sdk/chains/*.mdx` primitives pages. After a redeploy: + +1. Update the owning page (or re-run `npm run generate:stellar-reference` for Stellar). +2. Update the matching row here. +3. Run `npm run check:compatibility-matrix` and the full `npm test`. + +## Related + +- [SDK Overview](/sdk/overview) — entry points, `Chain` enum, dependency roles +- [EVM Contracts](/contracts/evm) · [Stellar Contracts](/contracts/stellar) · [Solana Contracts](/contracts/solana) · [CKB Contracts](/contracts/ckb) +- [Stellar Networks](/reference/stellar-networks) — live contract IDs per network +- [Stellar SEP Compatibility](/reference/sep-compatibility) — SEP-level support for Stellar integrations +- [Multichain Agent guide](/guides/multichain-agent) — driving one agent across several chains diff --git a/scripts/check-compatibility-matrix.mjs b/scripts/check-compatibility-matrix.mjs new file mode 100644 index 0000000..33624a7 --- /dev/null +++ b/scripts/check-compatibility-matrix.mjs @@ -0,0 +1,108 @@ +#!/usr/bin/env node +/** + * check-compatibility-matrix.mjs + * + * Verifies that every deployment identifier published in + * reference/compatibility-matrix.mdx is also present in the page that owns it, + * so the matrix cannot drift from the per-chain deployment references. + * + * Deployment identifiers are: + * - 0x-prefixed EVM addresses (40 hex chars) + * - 0x-prefixed CKB code hashes and transaction hashes (64 hex chars) + * - C... Stellar contract strkeys (56 chars, base32) + * + * Run after changing a deployment: + * + * node scripts/check-compatibility-matrix.mjs + * + * Wired into `npm test`, so a matrix row that no longer matches its owning page + * fails the docs build. + */ +import { readFile } from "node:fs/promises"; +import path from "node:path"; +import process from "node:process"; + +const repoRoot = process.cwd(); +const matrixPath = path.join(repoRoot, "reference", "compatibility-matrix.mdx"); + +/** Pages that own the deployment identifiers the matrix transcribes. */ +const sourcePaths = [ + "contracts/evm.mdx", + "contracts/stellar.mdx", + "contracts/solana.mdx", + "contracts/ckb.mdx", + "reference/stellar-networks.mdx", + "sdk/chains/evm.mdx", + "sdk/chains/stellar.mdx", + "sdk/chains/solana.mdx", + "sdk/chains/ckb.mdx", +]; + +const EVM_ADDRESS = /0x[0-9a-fA-F]{40}(?![0-9a-fA-F])/g; +const CKB_HASH = /0x[0-9a-fA-F]{64}(?![0-9a-fA-F])/g; +const STELLAR_STRKEY = /\bC[A-Z2-7]{55}\b/g; + +async function main() { + const matrix = await readFile(matrixPath, "utf8"); + const identifiers = collectIdentifiers(matrix); + + if (identifiers.size === 0) { + fail([ + "No deployment identifiers found in reference/compatibility-matrix.mdx.", + "Expected at least one EVM address, CKB code hash, or Stellar contract strkey.", + ]); + } + + const sources = []; + for (const relative of sourcePaths) { + try { + sources.push({ + relative, + text: await readFile(path.join(repoRoot, relative), "utf8"), + }); + } catch { + // A chain that has no primitives page yet is not a failure on its own; + // the identifiers it owns still have to be found in another source page. + } + } + const haystack = sources.map((source) => source.text).join("\n"); + + const missing = [...identifiers].filter((id) => !haystack.includes(id)).sort(); + + if (missing.length > 0) { + fail([ + "Deployment identifiers in reference/compatibility-matrix.mdx were not found", + "in any of the pages that own them:", + ...missing.map((id) => ` - ${id}`), + "", + `Searched: ${sources.map((source) => source.relative).join(", ")}`, + "Update the owning page (or re-run `npm run generate:stellar-reference`) and", + "the matrix together so the two cannot disagree.", + ]); + } + + console.log( + `Compatibility matrix passed: ${identifiers.size} deployment identifiers ` + + `verified against ${sources.length} source pages.`, + ); +} + +function collectIdentifiers(markdown) { + const ids = new Set(); + for (const pattern of [EVM_ADDRESS, CKB_HASH, STELLAR_STRKEY]) { + for (const match of markdown.matchAll(pattern)) { + ids.add(match[0]); + } + } + return ids; +} + +function fail(lines) { + console.error(["Compatibility matrix check failed.", "", ...lines].join("\n")); + process.exit(1); +} + +main().catch((error) => { + console.error(error); + process.exit(1); +});