ccip-router 0.1.0

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.
Files changed (97) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +528 -0
  3. package/contracts/AttestationIndex.sol +125 -0
  4. package/contracts/NodeRegistry.sol +85 -0
  5. package/dist/attestation/eip712.d.ts +50 -0
  6. package/dist/attestation/eip712.d.ts.map +1 -0
  7. package/dist/attestation/eip712.js +31 -0
  8. package/dist/attestation/eip712.js.map +1 -0
  9. package/dist/attestation/ocp.d.ts +9 -0
  10. package/dist/attestation/ocp.d.ts.map +1 -0
  11. package/dist/attestation/ocp.js +11 -0
  12. package/dist/attestation/ocp.js.map +1 -0
  13. package/dist/attestation/withWyriwe.d.ts +11 -0
  14. package/dist/attestation/withWyriwe.d.ts.map +1 -0
  15. package/dist/attestation/withWyriwe.js +92 -0
  16. package/dist/attestation/withWyriwe.js.map +1 -0
  17. package/dist/chain/abi.d.ts +178 -0
  18. package/dist/chain/abi.d.ts.map +1 -0
  19. package/dist/chain/abi.js +94 -0
  20. package/dist/chain/abi.js.map +1 -0
  21. package/dist/chain/client.d.ts +16762 -0
  22. package/dist/chain/client.d.ts.map +1 -0
  23. package/dist/chain/client.js +21 -0
  24. package/dist/chain/client.js.map +1 -0
  25. package/dist/chain/publish.d.ts +26 -0
  26. package/dist/chain/publish.d.ts.map +1 -0
  27. package/dist/chain/publish.js +66 -0
  28. package/dist/chain/publish.js.map +1 -0
  29. package/dist/chain/register.d.ts +9 -0
  30. package/dist/chain/register.d.ts.map +1 -0
  31. package/dist/chain/register.js +20 -0
  32. package/dist/chain/register.js.map +1 -0
  33. package/dist/crypto/hash.d.ts +3 -0
  34. package/dist/crypto/hash.d.ts.map +1 -0
  35. package/dist/crypto/hash.js +12 -0
  36. package/dist/crypto/hash.js.map +1 -0
  37. package/dist/crypto/index.d.ts +3 -0
  38. package/dist/crypto/index.d.ts.map +1 -0
  39. package/dist/crypto/index.js +3 -0
  40. package/dist/crypto/index.js.map +1 -0
  41. package/dist/crypto/sign.d.ts +6 -0
  42. package/dist/crypto/sign.d.ts.map +1 -0
  43. package/dist/crypto/sign.js +60 -0
  44. package/dist/crypto/sign.js.map +1 -0
  45. package/dist/db/index.d.ts +5 -0
  46. package/dist/db/index.d.ts.map +1 -0
  47. package/dist/db/index.js +13 -0
  48. package/dist/db/index.js.map +1 -0
  49. package/dist/db/schema.d.ts +6 -0
  50. package/dist/db/schema.d.ts.map +1 -0
  51. package/dist/db/schema.js +41 -0
  52. package/dist/db/schema.js.map +1 -0
  53. package/dist/db/sqlite.d.ts +19 -0
  54. package/dist/db/sqlite.d.ts.map +1 -0
  55. package/dist/db/sqlite.js +196 -0
  56. package/dist/db/sqlite.js.map +1 -0
  57. package/dist/db/types.d.ts +34 -0
  58. package/dist/db/types.d.ts.map +1 -0
  59. package/dist/db/types.js +5 -0
  60. package/dist/db/types.js.map +1 -0
  61. package/dist/gateway/__tests__/eip3668.test.d.ts +2 -0
  62. package/dist/gateway/__tests__/eip3668.test.d.ts.map +1 -0
  63. package/dist/gateway/__tests__/eip3668.test.js +31 -0
  64. package/dist/gateway/__tests__/eip3668.test.js.map +1 -0
  65. package/dist/gateway/eip3668.d.ts +14 -0
  66. package/dist/gateway/eip3668.d.ts.map +1 -0
  67. package/dist/gateway/eip3668.js +28 -0
  68. package/dist/gateway/eip3668.js.map +1 -0
  69. package/dist/lib.d.ts +12 -0
  70. package/dist/lib.d.ts.map +1 -0
  71. package/dist/lib.js +8 -0
  72. package/dist/lib.js.map +1 -0
  73. package/dist/mesh/cron.d.ts +4 -0
  74. package/dist/mesh/cron.d.ts.map +1 -0
  75. package/dist/mesh/cron.js +22 -0
  76. package/dist/mesh/cron.js.map +1 -0
  77. package/dist/mesh/records.d.ts +4 -0
  78. package/dist/mesh/records.d.ts.map +1 -0
  79. package/dist/mesh/records.js +47 -0
  80. package/dist/mesh/records.js.map +1 -0
  81. package/dist/mesh/sync.d.ts +5 -0
  82. package/dist/mesh/sync.d.ts.map +1 -0
  83. package/dist/mesh/sync.js +154 -0
  84. package/dist/mesh/sync.js.map +1 -0
  85. package/dist/mesh/vni.d.ts +14 -0
  86. package/dist/mesh/vni.d.ts.map +1 -0
  87. package/dist/mesh/vni.js +52 -0
  88. package/dist/mesh/vni.js.map +1 -0
  89. package/dist/router/CcipRouter.d.ts +26 -0
  90. package/dist/router/CcipRouter.d.ts.map +1 -0
  91. package/dist/router/CcipRouter.js +85 -0
  92. package/dist/router/CcipRouter.js.map +1 -0
  93. package/dist/router/index.d.ts +3 -0
  94. package/dist/router/index.d.ts.map +1 -0
  95. package/dist/router/index.js +2 -0
  96. package/dist/router/index.js.map +1 -0
  97. package/package.json +63 -0
@@ -0,0 +1,154 @@
1
+ import { recoverRecordSigner } from '../crypto/index.js';
2
+ import { fetchPeerVni, verifyVni } from './vni.js';
3
+ // Manual sync trigger — used by the admin dashboard "Sync now" button.
4
+ export async function syncAll(config, db) {
5
+ const peers = await db.getPeers();
6
+ const results = await Promise.allSettled(peers.map(async (peer) => {
7
+ const update = await syncPeer(peer, config.syncNamespace, db, config.autoDiscover);
8
+ await db.upsertPeer({ ...peer, ...update });
9
+ }));
10
+ return results.filter((r) => r.status === 'fulfilled').length;
11
+ }
12
+ const SUPPORTED_PROTOCOL = 1;
13
+ // Pull all new records from a single peer, paginating until cursor is null.
14
+ // Optionally runs peer gossip (auto-discovery) after syncing.
15
+ export async function syncPeer(peer, namespace, db, autoDiscover = true) {
16
+ let cursor = undefined;
17
+ let inserted = 0;
18
+ let rejected = 0;
19
+ let discoveredSigner = null;
20
+ try {
21
+ do {
22
+ const url = buildRecordsUrl(peer.url, namespace, peer.lastSyncAt, cursor);
23
+ const body = await fetchRecords(url);
24
+ if (body.protocol !== SUPPORTED_PROTOCOL) {
25
+ console.warn(`[sync] ${peer.url} speaks protocol ${body.protocol} — skipping`);
26
+ return { healthy: false, nodeVersion: body.node_version ?? peer.nodeVersion };
27
+ }
28
+ for (const record of body.records) {
29
+ const result = await validateAndInsert(record, db, peer.signerAddress);
30
+ if (result.inserted) {
31
+ inserted++;
32
+ if (result.signer && !discoveredSigner)
33
+ discoveredSigner = result.signer;
34
+ }
35
+ else {
36
+ rejected++;
37
+ }
38
+ }
39
+ cursor = body.cursor ?? undefined;
40
+ } while (cursor !== undefined);
41
+ if (inserted > 0 || rejected > 0) {
42
+ console.log(`[sync] ${peer.url} — +${inserted} inserted, ${rejected} rejected`);
43
+ }
44
+ // Fetch /vni — authoritative signed identity (preferred over health signerAddress)
45
+ const vni = await fetchPeerVni(peer.url);
46
+ const vniSigner = vni ? await verifyVni(vni) : null;
47
+ // Fetch /health for nodeVersion fallback
48
+ const health = await fetchPeerHealth(peer.url);
49
+ // Auto-discovery: pull peer's known peers and add any new ones
50
+ if (autoDiscover)
51
+ await discoverPeers(peer, db);
52
+ return {
53
+ healthy: true,
54
+ lastSyncAt: Math.floor(Date.now() / 1000),
55
+ nodeVersion: vni?.version ?? health?.version ?? peer.nodeVersion,
56
+ signerAddress: vniSigner ?? discoveredSigner ?? health?.signerAddress ?? peer.signerAddress,
57
+ };
58
+ }
59
+ catch (err) {
60
+ console.warn(`[sync] ${peer.url} unreachable — ${String(err)}`);
61
+ return { healthy: false };
62
+ }
63
+ }
64
+ // Validate a single record's signature then insert.
65
+ // Signer pinning: if the peer's signer address is already known, reject any
66
+ // record signed by a different key — prevents a compromised peer from injecting
67
+ // records on behalf of another node.
68
+ async function validateAndInsert(record, db, knownSigner) {
69
+ if (record.signature === '0x') {
70
+ console.warn(`[sync] unsigned record ${record.inputHash} — accepted (dry-run peer)`);
71
+ await db.insertRecord(record);
72
+ return { inserted: true, signer: null };
73
+ }
74
+ let signer;
75
+ try {
76
+ signer = await recoverRecordSigner(record);
77
+ }
78
+ catch {
79
+ console.warn(`[sync] malformed signature on ${record.inputHash} — rejected`);
80
+ return { inserted: false, signer: null };
81
+ }
82
+ if (knownSigner && signer.toLowerCase() !== knownSigner.toLowerCase()) {
83
+ console.warn(`[sync] signer mismatch on ${record.inputHash}: ` +
84
+ `expected ${knownSigner.slice(0, 10)}… got ${signer.slice(0, 10)}… — rejected`);
85
+ return { inserted: false, signer: null };
86
+ }
87
+ await db.insertRecord(record);
88
+ return { inserted: true, signer };
89
+ }
90
+ function buildRecordsUrl(baseUrl, namespace, since, cursor) {
91
+ const url = new URL('/records', baseUrl);
92
+ url.searchParams.set('namespace', namespace);
93
+ url.searchParams.set('since', String(since));
94
+ url.searchParams.set('limit', '500');
95
+ if (cursor)
96
+ url.searchParams.set('cursor', cursor);
97
+ return url.toString();
98
+ }
99
+ async function fetchRecords(url) {
100
+ const res = await fetch(url, { signal: AbortSignal.timeout(10_000) });
101
+ if (!res.ok)
102
+ throw new Error(`HTTP ${res.status}`);
103
+ return res.json();
104
+ }
105
+ async function fetchPeerHealth(baseUrl) {
106
+ try {
107
+ const res = await fetch(new URL('/health', baseUrl).toString(), {
108
+ signal: AbortSignal.timeout(5_000),
109
+ });
110
+ if (!res.ok)
111
+ return null;
112
+ return res.json();
113
+ }
114
+ catch {
115
+ return null;
116
+ }
117
+ }
118
+ // Fetch the peer's /peers list and add any newly discovered nodes to our DB.
119
+ // Bounded to 10 new peers per sync cycle — prevents runaway growth.
120
+ async function discoverPeers(peer, db) {
121
+ try {
122
+ const res = await fetch(new URL('/peers', peer.url).toString(), {
123
+ signal: AbortSignal.timeout(5_000),
124
+ });
125
+ if (!res.ok)
126
+ return;
127
+ const data = await res.json();
128
+ if (!data.peers?.length)
129
+ return;
130
+ const existing = new Set((await db.getPeers()).map((p) => p.url));
131
+ let added = 0;
132
+ for (const discovered of data.peers) {
133
+ if (added >= 10)
134
+ break;
135
+ if (!discovered.url || existing.has(discovered.url))
136
+ continue;
137
+ try {
138
+ new URL(discovered.url);
139
+ }
140
+ catch {
141
+ continue;
142
+ }
143
+ const url = discovered.url.replace(/\/$/, '');
144
+ await db.upsertPeer({ url, lastSyncAt: 0, healthy: true, nodeVersion: null, signerAddress: discovered.signerAddress });
145
+ added++;
146
+ }
147
+ if (added > 0)
148
+ console.log(`[sync] discovered ${added} new peer(s) from ${peer.url}`);
149
+ }
150
+ catch {
151
+ // non-fatal — gossip is best-effort
152
+ }
153
+ }
154
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/mesh/sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export type VniDocument = {
2
+ nodeId: `0x${string}`;
3
+ signerAddress: `0x${string}`;
4
+ url: string;
5
+ version: string;
6
+ timestamp: number;
7
+ };
8
+ export type SignedVni = VniDocument & {
9
+ signature: `0x${string}`;
10
+ };
11
+ export declare function makeVni(gatewayKey: `0x${string}`, url: string, version?: string): Promise<SignedVni>;
12
+ export declare function verifyVni(vni: SignedVni): Promise<`0x${string}` | null>;
13
+ export declare function fetchPeerVni(baseUrl: string): Promise<SignedVni | null>;
14
+ //# sourceMappingURL=vni.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vni.d.ts","sourceRoot":"","sources":["../../src/mesh/vni.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAS,KAAK,MAAM,EAAE,CAAA;IAC5B,aAAa,EAAE,KAAK,MAAM,EAAE,CAAA;IAC5B,GAAG,EAAY,MAAM,CAAA;IACrB,OAAO,EAAQ,MAAM,CAAA;IACrB,SAAS,EAAM,MAAM,CAAA;CACtB,CAAA;AAED,MAAM,MAAM,SAAS,GAAG,WAAW,GAAG;IAAE,SAAS,EAAE,KAAK,MAAM,EAAE,CAAA;CAAE,CAAA;AAQlE,wBAAsB,OAAO,CAC3B,UAAU,EAAE,KAAK,MAAM,EAAE,EACzB,GAAG,EAAE,MAAM,EACX,OAAO,SAAU,GAChB,OAAO,CAAC,SAAS,CAAC,CAepB;AAGD,wBAAsB,SAAS,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,KAAK,MAAM,EAAE,GAAG,IAAI,CAAC,CAY7E;AAGD,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAU7E"}
@@ -0,0 +1,52 @@
1
+ import { keccak256, toBytes, recoverMessageAddress } from 'viem';
2
+ import { privateKeyToAccount } from 'viem/accounts';
3
+ // Serialise the document body for signing — must be deterministic
4
+ function vniMessage(doc) {
5
+ return 'ccip-router:vni:' + JSON.stringify(doc);
6
+ }
7
+ // Produce a fresh signed VNI for this node.
8
+ export async function makeVni(gatewayKey, url, version = '0.1.0') {
9
+ const account = privateKeyToAccount(gatewayKey);
10
+ const timestamp = Math.floor(Date.now() / 1000);
11
+ const nodeId = keccak256(toBytes(account.address));
12
+ const doc = {
13
+ nodeId,
14
+ signerAddress: account.address,
15
+ url,
16
+ version,
17
+ timestamp,
18
+ };
19
+ const signature = await account.signMessage({ message: vniMessage(doc) });
20
+ return { ...doc, signature };
21
+ }
22
+ // Verify a VNI's signature — returns the recovered signer or null.
23
+ export async function verifyVni(vni) {
24
+ try {
25
+ const { signature, ...doc } = vni;
26
+ const recovered = await recoverMessageAddress({
27
+ message: vniMessage(doc),
28
+ signature,
29
+ });
30
+ if (recovered.toLowerCase() !== vni.signerAddress.toLowerCase())
31
+ return null;
32
+ return recovered;
33
+ }
34
+ catch {
35
+ return null;
36
+ }
37
+ }
38
+ // Fetch and optionally verify a peer's VNI.
39
+ export async function fetchPeerVni(baseUrl) {
40
+ try {
41
+ const res = await fetch(new URL('/vni', baseUrl).toString(), {
42
+ signal: AbortSignal.timeout(5_000),
43
+ });
44
+ if (!res.ok)
45
+ return null;
46
+ return res.json();
47
+ }
48
+ catch {
49
+ return null;
50
+ }
51
+ }
52
+ //# sourceMappingURL=vni.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vni.js","sourceRoot":"","sources":["../../src/mesh/vni.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,qBAAqB,EAAE,MAAM,MAAM,CAAA;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AAYnD,kEAAkE;AAClE,SAAS,UAAU,CAAC,GAAgB;IAClC,OAAO,kBAAkB,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;AACjD,CAAC;AAED,4CAA4C;AAC5C,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,UAAyB,EACzB,GAAW,EACX,OAAO,GAAG,OAAO;IAEjB,MAAM,OAAO,GAAK,mBAAmB,CAAC,UAAU,CAAC,CAAA;IACjD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAA;IAC/C,MAAM,MAAM,GAAM,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAkB,CAAA;IAEtE,MAAM,GAAG,GAAgB;QACvB,MAAM;QACN,aAAa,EAAE,OAAO,CAAC,OAAO;QAC9B,GAAG;QACH,OAAO;QACP,SAAS;KACV,CAAA;IAED,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACzE,OAAO,EAAE,GAAG,GAAG,EAAE,SAAS,EAAE,CAAA;AAC9B,CAAC;AAED,mEAAmE;AACnE,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,GAAc;IAC5C,IAAI,CAAC;QACH,MAAM,EAAE,SAAS,EAAE,GAAG,GAAG,EAAE,GAAG,GAAG,CAAA;QACjC,MAAM,SAAS,GAAG,MAAM,qBAAqB,CAAC;YAC5C,OAAO,EAAI,UAAU,CAAC,GAAkB,CAAC;YACzC,SAAS;SACV,CAAC,CAAA;QACF,IAAI,SAAS,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,aAAa,CAAC,WAAW,EAAE;YAAE,OAAO,IAAI,CAAA;QAC5E,OAAO,SAAS,CAAA;IAClB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED,4CAA4C;AAC5C,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAe;IAChD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,IAAI,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;YAC3D,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC;SACnC,CAAC,CAAA;QACF,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,IAAI,CAAA;QACxB,OAAO,GAAG,CAAC,IAAI,EAAwB,CAAA;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { Hono } from 'hono';
2
+ import type { DB } from '../db/types.js';
3
+ export type ResolverFn = (sender: `0x${string}`, calldata: `0x${string}`, namespace: string) => Promise<`0x${string}`>;
4
+ export type IdentityOpts = {
5
+ agentId: `0x${string}`;
6
+ registryAddress: `0x${string}`;
7
+ chainId: number;
8
+ };
9
+ export type CcipRouterOptions = {
10
+ resolver: ResolverFn;
11
+ namespace?: string;
12
+ db?: DB;
13
+ gatewayKey?: `0x${string}` | null;
14
+ identity?: IdentityOpts;
15
+ };
16
+ export declare class CcipRouter {
17
+ private resolver;
18
+ private namespace;
19
+ private db;
20
+ private gatewayKey;
21
+ private identity;
22
+ constructor(opts: CcipRouterOptions);
23
+ hono(): Hono;
24
+ private writeRecord;
25
+ }
26
+ //# sourceMappingURL=CcipRouter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CcipRouter.d.ts","sourceRoot":"","sources":["../../src/router/CcipRouter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAG3B,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAA;AAOxC,MAAM,MAAM,UAAU,GAAG,CACvB,MAAM,EAAE,KAAK,MAAM,EAAE,EACrB,QAAQ,EAAE,KAAK,MAAM,EAAE,EACvB,SAAS,EAAE,MAAM,KACd,OAAO,CAAC,KAAK,MAAM,EAAE,CAAC,CAAA;AAK3B,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAU,KAAK,MAAM,EAAE,CAAA;IAC9B,eAAe,EAAE,KAAK,MAAM,EAAE,CAAA;IAC9B,OAAO,EAAU,MAAM,CAAA;CACxB,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAK,UAAU,CAAA;IACvB,SAAS,CAAC,EAAG,MAAM,CAAA;IACnB,EAAE,CAAC,EAAU,EAAE,CAAA;IACf,UAAU,CAAC,EAAE,KAAK,MAAM,EAAE,GAAG,IAAI,CAAA;IACjC,QAAQ,CAAC,EAAI,YAAY,CAAA;CAC1B,CAAA;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,EAAE,CAAmB;IAC7B,OAAO,CAAC,UAAU,CAAsB;IACxC,OAAO,CAAC,QAAQ,CAAuB;gBAE3B,IAAI,EAAE,iBAAiB;IASnC,IAAI,IAAI,IAAI;YAsDE,WAAW;CAoB1B"}
@@ -0,0 +1,85 @@
1
+ import { Hono } from 'hono';
2
+ import { cors } from 'hono/cors';
3
+ import { privateKeyToAccount } from 'viem/accounts';
4
+ import { hashCalldata, signRecord } from '../crypto/index.js';
5
+ import { decodeRequest, encodeResponse, CcipRequestError } from '../gateway/eip3668.js';
6
+ export class CcipRouter {
7
+ resolver;
8
+ namespace;
9
+ db;
10
+ gatewayKey;
11
+ identity;
12
+ constructor(opts) {
13
+ this.resolver = opts.resolver;
14
+ this.namespace = opts.namespace ?? 'agent-attestations';
15
+ this.db = opts.db ?? null;
16
+ this.gatewayKey = opts.gatewayKey ?? null;
17
+ this.identity = opts.identity ?? null;
18
+ }
19
+ // Returns a Hono app — mount at '/' via app.route('/', router.hono())
20
+ hono() {
21
+ const app = new Hono();
22
+ // EIP-3668 gateways are called directly from browser clients
23
+ app.use('*', cors({ origin: '*', allowMethods: ['GET'] }));
24
+ // GET /identity — ERC-8004 declared identity, machine-readable for peer discovery.
25
+ // 404 if not configured — callers should treat absence as "identity unknown".
26
+ app.get('/identity', (c) => {
27
+ if (!this.identity) {
28
+ return c.json({ declared: false }, 404);
29
+ }
30
+ const signerAddress = this.gatewayKey
31
+ ? privateKeyToAccount(this.gatewayKey).address
32
+ : null;
33
+ return c.json({
34
+ declared: true,
35
+ agentId: this.identity.agentId,
36
+ registryAddress: this.identity.registryAddress,
37
+ chainId: this.identity.chainId,
38
+ namespace: this.namespace,
39
+ signerAddress,
40
+ });
41
+ });
42
+ app.get('/:sender/:data', async (c) => {
43
+ let req;
44
+ try {
45
+ req = decodeRequest(c.req.param('sender'), c.req.param('data'));
46
+ }
47
+ catch (err) {
48
+ if (err instanceof CcipRequestError) {
49
+ return c.json({ error: err.message }, err.status);
50
+ }
51
+ return c.json({ error: 'bad request' }, 400);
52
+ }
53
+ let result;
54
+ try {
55
+ result = await this.resolver(req.sender, req.calldata, this.namespace);
56
+ }
57
+ catch (err) {
58
+ return c.json({ error: 'resolver error', detail: String(err) }, 500);
59
+ }
60
+ // fire-and-forget — never block the CCIP response on DB write
61
+ this.writeRecord(req.calldata, result).catch((err) => console.error('[ccip-router] writeRecord failed:', err));
62
+ return c.json(encodeResponse(result));
63
+ });
64
+ return app;
65
+ }
66
+ async writeRecord(calldata, response) {
67
+ if (!this.db)
68
+ return;
69
+ const inputHash = hashCalldata(calldata);
70
+ const timestamp = Math.floor(Date.now() / 1000);
71
+ const signature = this.gatewayKey
72
+ ? await signRecord(inputHash, this.namespace, response, timestamp, this.gatewayKey)
73
+ : '0x'; // dry-run — unsigned, peers will accept with warning
74
+ await this.db.insertRecord({
75
+ inputHash,
76
+ namespace: this.namespace,
77
+ key: inputHash,
78
+ value: response,
79
+ timestamp,
80
+ signature,
81
+ sourcePeer: null,
82
+ });
83
+ }
84
+ }
85
+ //# sourceMappingURL=CcipRouter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CcipRouter.js","sourceRoot":"","sources":["../../src/router/CcipRouter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { CcipRouter } from './CcipRouter.js';
2
+ export type { ResolverFn, CcipRouterOptions } from './CcipRouter.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/router/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA"}
@@ -0,0 +1,2 @@
1
+ export { CcipRouter } from './CcipRouter.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/router/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA"}
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "ccip-router",
3
+ "version": "0.1.0",
4
+ "description": "The coordination layer CCIP-Read was missing. Peer sync, deduplication, and cryptographic attestation for any CCIP-Read gateway.",
5
+ "type": "module",
6
+ "main": "./dist/lib.js",
7
+ "types": "./dist/lib.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/lib.js",
11
+ "types": "./dist/lib.d.ts"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist/attestation",
16
+ "dist/chain",
17
+ "dist/crypto",
18
+ "dist/db",
19
+ "dist/gateway",
20
+ "dist/lib.js",
21
+ "dist/lib.js.map",
22
+ "dist/lib.d.ts",
23
+ "dist/lib.d.ts.map",
24
+ "dist/mesh",
25
+ "dist/router",
26
+ "contracts/AttestationIndex.sol",
27
+ "contracts/NodeRegistry.sol"
28
+ ],
29
+ "keywords": [
30
+ "ccip-read", "eip-3668", "ens", "ethereum", "gateway",
31
+ "attestation", "wyriwe", "erc-8004", "ocp"
32
+ ],
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "https://github.com/Echo-Merlini/ccip-router.git"
36
+ },
37
+ "homepage": "https://github.com/Echo-Merlini/ccip-router#readme",
38
+ "scripts": {
39
+ "dev": "tsx watch src/index.ts",
40
+ "build": "tsc",
41
+ "start": "node dist/index.js",
42
+ "lint": "tsc --noEmit",
43
+ "test": "node --import tsx/esm --test src/**/__tests__/**/*.test.ts"
44
+ },
45
+ "dependencies": {
46
+ "@hono/node-server": "^2.0.4",
47
+ "better-sqlite3": "^12.10.0",
48
+ "hono": "^4.4.0",
49
+ "node-cron": "^4.2.1",
50
+ "viem": "^2.0.0"
51
+ },
52
+ "devDependencies": {
53
+ "@types/better-sqlite3": "^7.6.13",
54
+ "@types/node": "^20.0.0",
55
+ "@types/node-cron": "^3.0.11",
56
+ "tsx": "^4.0.0",
57
+ "typescript": "^5.4.0"
58
+ },
59
+ "engines": {
60
+ "node": ">=20"
61
+ },
62
+ "license": "MIT"
63
+ }