@ashlar-blue/x402-trust 0.3.0 → 0.5.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.
package/README.md CHANGED
@@ -49,22 +49,38 @@ grammar below.
49
49
  The rest of this document is the building blocks `checkService` sits on, for
50
50
  callers who want the lower-level surface.
51
51
 
52
- ## The Open Catalog, self-hostable (staged for 0.2.0)
53
-
54
- Two further modules ship the catalog itself as a reference implementation —
55
- the "anyone can rebuild this from public data" claim, made executable:
56
-
57
- - **`open-catalog`** — the catalog engine: mirror the CDP Bazaar via its own
58
- public API (with attribution), crawl `discovery` records breadth-first with
59
- per-operator frontier-diversity bounds, and serve a provenance-tagged,
60
- sha256-digested snapshot. Run it yourself and you are an independent
61
- observer, not a mirror of ours.
62
- - **`catalog-mcp`** — a transport-free MCP server core for that catalog:
63
- stateless protocol revision 2026-07-28 primary, sessionless legacy
64
- `initialize` shim, four read tools, a signable Server Card, and evidence
65
- (snapshot digest + on-chain anchor) carried in BOTH `_meta` and readable
66
- content. Wire it to any HTTP framework in ~20 lines; every dependency is
67
- injected.
52
+ ## Model Context Protocol (MCP) Server
53
+
54
+ Connect any autonomous AI coding agent (Claude Desktop, Cursor, Antigravity, VS Code, or custom AI agents) directly to the x402 trust and discovery mesh via standard MCP over `stdio`:
55
+
56
+ ```bash
57
+ # Run standalone MCP server
58
+ npx @ashlar-blue/x402-trust mcp
59
+ ```
60
+
61
+ ### Claude Desktop / Cursor MCP Configuration:
62
+ ```json
63
+ {
64
+ "mcpServers": {
65
+ "x402-trust": {
66
+ "command": "npx",
67
+ "args": ["-y", "@ashlar-blue/x402-trust", "mcp"],
68
+ "env": {
69
+ "X402_NETWORK": "coston2"
70
+ }
71
+ }
72
+ }
73
+ }
74
+ ```
75
+
76
+ ### Supported MCP Tools:
77
+ - `x402_check_service`: Resolves DNS TXT (`_x402`) and `/.well-known/x402` to return a hardened `safeToPay` decision with full reasons.
78
+ - `x402_verify_attestation_entry`: Offline RFC 6962 Merkle verification of Intel TDX / AMD SEV TEE hardware quote measurements against a signed directory root.
79
+ - `x402_verify_transcript_inclusion`: Offline RFC 6962 Merkle verification of agent-to-agent session audit entries against a signed transcript root.
80
+ - `x402_verify_reconcile_row`: Offline verification of EIP-3009 / XRPL settlement reconciliation rows against a signed census root.
81
+ - `x402_catalog_search`: Filter and search the decentralized catalog of active x402 endpoints across discovery and bazaar-mirror lanes.
82
+ - `x402_catalog_get`: Retrieve complete provenance records and re-derivation recipes for any resource URL or hostname.
83
+ - `x402_catalog_stats`: Inspect network-wide node counts, active chains, and on-chain Coston2/Flare Merkle anchor hashes.
68
84
 
69
85
  ## Zero dependencies
70
86
 
@@ -83,9 +99,9 @@ npm install @ashlar-blue/x402-trust
83
99
  ```ts
84
100
  import { resolveX402 } from '@ashlar-blue/x402-trust';
85
101
 
86
- const r = await resolveX402('flareclaw.app');
102
+ const r = await resolveX402('ashlar.blue');
87
103
 
88
- r.via; // 'dns-txt' — found via _x402.flareclaw.app
104
+ r.via; // 'dns-txt' — found via _x402.ashlar.blue
89
105
  r.manifest.facilitator.baseUrl;
90
106
  r.liveKinds; // fetched from /supported — authoritative over the manifest
91
107
  r.kindsMatchLive; // false = the operator's manifest is stale
@@ -95,7 +111,7 @@ r.attestationUsable // false = treat any TEE claim as absent
95
111
  Runs in Node out of the box. In a browser or a worker, inject a DNS resolver (DoH) and it works unchanged:
96
112
 
97
113
  ```ts
98
- await resolveX402('flareclaw.app', { resolveTxt: myDohResolver, fetchImpl: fetch });
114
+ await resolveX402('ashlar.blue', { resolveTxt: myDohResolver, fetchImpl: fetch });
99
115
  ```
100
116
 
101
117
  ### What it refuses to do
@@ -184,15 +200,46 @@ import { encodeEvidenceRef, parseEvidenceRef, sameEvidence, canonicalJson } from
184
200
  const ref = encodeEvidenceRef({
185
201
  alg: 'sha256',
186
202
  hex: '...',
187
- ref: 'https://api.flareclaw.app/evidence/<digest>.json',
203
+ ref: 'https://api.ashlar.blue/evidence/<digest>.json',
188
204
  });
189
205
  // "x402ev/1; digest=sha256:...; ref=https://..."
190
206
  ```
191
207
 
192
208
  Verify one by fetching the artifact, canonicalizing it ([RFC 8785 JCS](https://www.rfc-editor.org/rfc/rfc8785)), hashing, and comparing to the digest. A fetched artifact that **mismatches** its digest is evidence-invalid and must be a hard negative; an artifact that is merely **unreachable** should down-weight the record, not revoke it. Link rot and tampering are different failures.
193
209
 
210
+ ## ISDA Common Domain Model (CDM) & Securities Bridge
211
+
212
+ Parse institutional derivatives and securities lifecycle events (Variation Margin, Bond Coupons, Swap Settlements, Equity DvP) directly into conformant x402 HTTP 402 payment challenges and deterministic SCITT accounting statements with SHA-256 pre-image binding:
213
+
214
+ ```ts
215
+ import {
216
+ parseIsdaCdmEvent,
217
+ buildIsdaX402Challenge,
218
+ buildIsdaScittStatement,
219
+ verifyIsdaSettlement
220
+ } from '@ashlar-blue/x402-trust';
221
+
222
+ // 1. Parse and validate an incoming ISDA trade lifecycle event
223
+ const event = parseIsdaCdmEvent(rawPayload);
224
+
225
+ // 2. Generate an x402 HTTP 402 payment challenge for RLUSD / XRPL / Flare
226
+ const challenge = buildIsdaX402Challenge(event, {
227
+ facilityUrl: 'https://api.ashlar.blue/settle/isda',
228
+ payToAddress: '0x2222222222222222222222222222222222222222',
229
+ assetNetwork: 'xrpl:mainnet'
230
+ });
231
+
232
+ // 3. Emit a canonical SCITT accounting statement bound to the event
233
+ const statement = buildIsdaScittStatement(event);
234
+
235
+ // 4. Verify on-chain settlement receipt against the accounting statement
236
+ const verdict = verifyIsdaSettlement(statement, onchainReceipt);
237
+ if (!verdict.valid) throw new Error(verdict.error);
238
+ ```
239
+
194
240
  ## Status
195
241
 
196
- `0.2.0`. Both extensions are open pull requests, not ratified standards — the wire formats may change in response to review, and this package tracks them. It is published because a specification with an installable implementation is a proposal with users attached, and one without is a PDF. Requires Node ≥20 (the manifest signer validates UTF-16 well-formedness via `String.prototype.isWellFormed`).
242
+ `0.5.0`. Zero-dependency institutional trust and discovery layer for autonomous AI agents and institutional clearing. Published on npm as `@ashlar-blue/x402-trust`. Requires Node ≥20.
197
243
 
198
244
  MIT.
245
+
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env node
2
+ // GENERATED from src/x402/cli.ts by scripts/sdk/sync-sdk.ts — do not edit here.
3
+ // The canonical module is the one FlareClaw runs in production; this is a copy so
4
+ // that what we publish and what we run cannot diverge. Edit the canonical file.
5
+ /**
6
+ * @ashlar-blue/x402-trust CLI & MCP Server Runner.
7
+ *
8
+ * Usage:
9
+ * npx @ashlar-blue/x402-trust mcp
10
+ * npx x402-mcp
11
+ */
12
+ import { startStdioMcpServer, MCP_SERVER_INFO } from './mcp-server.js';
13
+ import * as path from 'node:path';
14
+ const args = process.argv.slice(2);
15
+ const command = args[0] || 'mcp';
16
+ if (args.includes('--version') || args.includes('-v')) {
17
+ console.log(`${MCP_SERVER_INFO.name} v${MCP_SERVER_INFO.version}`);
18
+ process.exit(0);
19
+ }
20
+ if (args.includes('--help') || args.includes('-h')) {
21
+ console.log(`
22
+ Ashlar Blue x402 Trust Layer CLI & Model Context Protocol (MCP) Server
23
+
24
+ Commands:
25
+ mcp Start the MCP server over stdio (default)
26
+ --version, -v Show version
27
+ --help, -h Show this help message
28
+
29
+ Environment Variables:
30
+ X402_CATALOG_PATH Path to x402 catalog state JSON (optional)
31
+
32
+ Documentation:
33
+ https://ashlar.blue
34
+ https://github.com/correntelabs/ashlar-blue
35
+ `);
36
+ process.exit(0);
37
+ }
38
+ if (command === 'mcp') {
39
+ const catalogPath = process.env.X402_CATALOG_PATH || path.resolve(process.cwd(), 'data/x402-catalog.json');
40
+ startStdioMcpServer(catalogPath);
41
+ }
42
+ else {
43
+ console.error(`Unknown command: ${command}. Run with --help for available options.`);
44
+ process.exit(1);
45
+ }
46
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,gFAAgF;AAChF,kFAAkF;AAClF,gFAAgF;AAGhF;;;;;;GAMG;AAEH,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC;AAEjC,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,GAAG,eAAe,CAAC,IAAI,KAAK,eAAe,CAAC,OAAO,EAAE,CAAC,CAAC;IACnE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC;AAED,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;CAcf,CAAC,CAAC;IACC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC;AAED,IAAI,OAAO,KAAK,KAAK,EAAE,CAAC;IACpB,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,wBAAwB,CAAC,CAAC;IAC3G,mBAAmB,CAAC,WAAW,CAAC,CAAC;AACrC,CAAC;KAAM,CAAC;IACJ,OAAO,CAAC,KAAK,CAAC,oBAAoB,OAAO,0CAA0C,CAAC,CAAC;IACrF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC"}
package/dist/index.d.ts CHANGED
@@ -6,10 +6,12 @@ export * from './facilitator-config.js';
6
6
  export * from './open-catalog.js';
7
7
  export * from './catalog-mcp.js';
8
8
  export * from './reconcile.js';
9
+ export * from './isda-cdm.js';
9
10
  export * from './manifest-sig.js';
10
11
  export * from './merkle-transcript.js';
11
12
  export * from './attested-directory.js';
12
13
  export * from './census-reconcile.js';
13
14
  export * from './directory-classify.js';
14
15
  export * from './trust-sdk.js';
16
+ export * from './mcp-server.js';
15
17
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC"}
package/dist/index.js CHANGED
@@ -9,10 +9,12 @@ export * from './facilitator-config.js';
9
9
  export * from './open-catalog.js';
10
10
  export * from './catalog-mcp.js';
11
11
  export * from './reconcile.js';
12
+ export * from './isda-cdm.js';
12
13
  export * from './manifest-sig.js';
13
14
  export * from './merkle-transcript.js';
14
15
  export * from './attested-directory.js';
15
16
  export * from './census-reconcile.js';
16
17
  export * from './directory-classify.js';
17
18
  export * from './trust-sdk.js';
19
+ export * from './mcp-server.js';
18
20
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,kFAAkF;AAClF,gFAAgF;AAEhF,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,kFAAkF;AAClF,gFAAgF;AAEhF,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC"}
@@ -0,0 +1,83 @@
1
+ import type { X402Challenge } from './types.js';
2
+ export interface IsdaCdmTradeEvent {
3
+ tradeId: string;
4
+ eventType: 'VARIATION_MARGIN' | 'INITIAL_MARGIN' | 'SWAP_SETTLEMENT' | 'BOND_COUPON' | 'EQUITY_DVP';
5
+ payer: string;
6
+ receiver: string;
7
+ notionalAmount: string;
8
+ settlementCurrency: string;
9
+ isinOrCusip?: string;
10
+ effectiveDate: string;
11
+ enclaveMeasurement?: string;
12
+ }
13
+ export interface IsdaX402ChallengeOptions {
14
+ facilityUrl: string;
15
+ assetNetwork: string;
16
+ payToAddress: string;
17
+ expirationSeconds?: number;
18
+ }
19
+ export interface IsdaScittStatement {
20
+ statementType: string;
21
+ tradeId: string;
22
+ eventType: string;
23
+ grossAmount: string;
24
+ currency: string;
25
+ payer: string;
26
+ receiver: string;
27
+ isinOrCusip: string;
28
+ timestamp: number;
29
+ enclaveMeasurement: string;
30
+ statementDigest: string;
31
+ }
32
+ export interface IsdaSettlementReceipt {
33
+ transactionHash: string;
34
+ payer: string;
35
+ receiver: string;
36
+ settledAmount: string;
37
+ currency: string;
38
+ status: 'CONFIRMED' | 'FAILED';
39
+ }
40
+ /**
41
+ * Parses a raw ISDA CDM JSON string or object payload into a validated IsdaCdmTradeEvent.
42
+ */
43
+ export declare function parseIsdaCdmEvent(rawPayload: unknown): IsdaCdmTradeEvent;
44
+ /**
45
+ * Constructs a standard x402 Challenge from an ISDA CDM Trade Event.
46
+ */
47
+ export declare function buildIsdaX402Challenge(event: IsdaCdmTradeEvent, opts: IsdaX402ChallengeOptions): X402Challenge;
48
+ /**
49
+ * Builds a deterministic SCITT Signed Accounting Statement payload for an ISDA trade settlement.
50
+ */
51
+ export declare function buildIsdaScittStatement(event: IsdaCdmTradeEvent, settlementTimestamp?: number): IsdaScittStatement;
52
+ /**
53
+ * Verifies an on-chain settlement receipt against a canonical ISDA SCITT statement.
54
+ */
55
+ export declare function verifyIsdaSettlement(statement: IsdaScittStatement, receipt: IsdaSettlementReceipt): {
56
+ valid: boolean;
57
+ error?: string;
58
+ };
59
+ export interface DvpSettlementResult {
60
+ tradeId: string;
61
+ status: 'SETTLED' | 'REFUSED_FAILED_LEG' | 'REFUSED_EXPIRED';
62
+ assetLeg: {
63
+ assetIdentifier: string;
64
+ from: string;
65
+ to: string;
66
+ quantity: string;
67
+ status: 'TRANSFERRED' | 'PENDING';
68
+ };
69
+ cashLeg: {
70
+ currency: string;
71
+ from: string;
72
+ to: string;
73
+ amount: string;
74
+ status: 'SETTLED' | 'PENDING';
75
+ };
76
+ enclaveProofDigest: string;
77
+ settlementTimestamp: number;
78
+ }
79
+ /**
80
+ * Simulates atomic Delivery-vs-Payment (DvP) trade execution inside a secure TEE enclave.
81
+ */
82
+ export declare function executeDvpSettlement(event: IsdaCdmTradeEvent, assetQuantity: string, assetConfirmed: boolean, cashConfirmed: boolean, enclaveMeasurement?: string): DvpSettlementResult;
83
+ //# sourceMappingURL=isda-cdm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isda-cdm.d.ts","sourceRoot":"","sources":["../src/isda-cdm.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,182 @@
1
+ // GENERATED from src/x402/isda-cdm.ts by scripts/sdk/sync-sdk.ts — do not edit here.
2
+ // The canonical module is the one FlareClaw runs in production; this is a copy so
3
+ // that what we publish and what we run cannot diverge. Edit the canonical file.
4
+ /**
5
+ * ISDA Common Domain Model (CDM) & Securities x402 Bridge
6
+ *
7
+ * Provides zero-dependency mapping between ISDA CDM trade lifecycle events
8
+ * (Variation Margin calls, Interest Rate Swap payoffs, Bond Coupon distributions)
9
+ * and x402 payment challenges + SCITT audit statements.
10
+ */
11
+ import { createHash } from 'node:crypto';
12
+ /**
13
+ * Parses a raw ISDA CDM JSON string or object payload into a validated IsdaCdmTradeEvent.
14
+ */
15
+ export function parseIsdaCdmEvent(rawPayload) {
16
+ let obj;
17
+ if (typeof rawPayload === 'string') {
18
+ try {
19
+ obj = JSON.parse(rawPayload);
20
+ }
21
+ catch {
22
+ throw new TypeError('Invalid JSON string for ISDA CDM payload');
23
+ }
24
+ }
25
+ else if (typeof rawPayload === 'object' && rawPayload !== null) {
26
+ obj = rawPayload;
27
+ }
28
+ else {
29
+ throw new TypeError('Invalid ISDA CDM payload: expected an object or JSON string');
30
+ }
31
+ if (typeof obj.tradeId !== 'string' || !obj.tradeId) {
32
+ throw new TypeError('Missing required ISDA fields: invalid tradeId');
33
+ }
34
+ const validTypes = ['VARIATION_MARGIN', 'INITIAL_MARGIN', 'SWAP_SETTLEMENT', 'BOND_COUPON', 'EQUITY_DVP'];
35
+ if (typeof obj.eventType !== 'string' || !validTypes.includes(obj.eventType)) {
36
+ throw new TypeError(`Invalid ISDA CDM payload: eventType must be one of ${validTypes.join(', ')}`);
37
+ }
38
+ if (typeof obj.payer !== 'string' || typeof obj.receiver !== 'string') {
39
+ throw new TypeError('Invalid ISDA CDM payload: payer and receiver must be valid string identifiers');
40
+ }
41
+ if (typeof obj.notionalAmount !== 'string' || typeof obj.settlementCurrency !== 'string') {
42
+ throw new TypeError('Invalid ISDA CDM payload: notionalAmount and settlementCurrency must be strings');
43
+ }
44
+ const num = parseFloat(obj.notionalAmount);
45
+ if (isNaN(num) || num <= 0) {
46
+ throw new TypeError('Invalid notional amount: must be positive numeric string');
47
+ }
48
+ return {
49
+ tradeId: obj.tradeId,
50
+ eventType: obj.eventType,
51
+ payer: obj.payer,
52
+ receiver: obj.receiver,
53
+ notionalAmount: obj.notionalAmount,
54
+ settlementCurrency: obj.settlementCurrency,
55
+ isinOrCusip: typeof obj.isinOrCusip === 'string' ? obj.isinOrCusip : 'N/A',
56
+ effectiveDate: typeof obj.effectiveDate === 'string' ? obj.effectiveDate : new Date().toISOString(),
57
+ enclaveMeasurement: typeof obj.enclaveMeasurement === 'string' ? obj.enclaveMeasurement : '',
58
+ };
59
+ }
60
+ /**
61
+ * Constructs a standard x402 Challenge from an ISDA CDM Trade Event.
62
+ */
63
+ export function buildIsdaX402Challenge(event, opts) {
64
+ return {
65
+ x402Version: 1,
66
+ error: `Payment required for ISDA CDM event ${event.eventType} (${event.tradeId})`,
67
+ accepts: [
68
+ {
69
+ scheme: 'exact',
70
+ network: opts.assetNetwork,
71
+ amount: event.notionalAmount,
72
+ maxAmountRequired: event.notionalAmount,
73
+ resource: opts.facilityUrl,
74
+ description: `ISDA Settlement: ${event.eventType} for ${event.isinOrCusip || event.tradeId}`,
75
+ mimeType: 'application/json',
76
+ payTo: opts.payToAddress,
77
+ maxTimeoutSeconds: 300,
78
+ asset: opts.payToAddress,
79
+ extra: {
80
+ name: event.settlementCurrency,
81
+ version: '1',
82
+ assetTransferMethod: 'eip3009'
83
+ }
84
+ }
85
+ ]
86
+ };
87
+ }
88
+ /**
89
+ * Builds a deterministic SCITT Signed Accounting Statement payload for an ISDA trade settlement.
90
+ */
91
+ export function buildIsdaScittStatement(event, settlementTimestamp = Math.floor(Date.now() / 1000)) {
92
+ const base = {
93
+ statementType: 'https://x402.org/schemas/v1/isda-settlement',
94
+ tradeId: event.tradeId,
95
+ eventType: event.eventType,
96
+ grossAmount: event.notionalAmount,
97
+ currency: event.settlementCurrency,
98
+ payer: event.payer,
99
+ receiver: event.receiver,
100
+ isinOrCusip: event.isinOrCusip || 'N/A',
101
+ timestamp: settlementTimestamp,
102
+ enclaveMeasurement: event.enclaveMeasurement || '',
103
+ };
104
+ const rawBytes = JSON.stringify(base);
105
+ const digest = `sha256:${createHash('sha256').update(rawBytes, 'utf8').digest('hex')}`;
106
+ return {
107
+ ...base,
108
+ statementDigest: digest,
109
+ };
110
+ }
111
+ /**
112
+ * Verifies an on-chain settlement receipt against a canonical ISDA SCITT statement.
113
+ */
114
+ export function verifyIsdaSettlement(statement, receipt) {
115
+ if (receipt.status !== 'CONFIRMED') {
116
+ return { valid: false, error: 'Settlement receipt status is not CONFIRMED' };
117
+ }
118
+ if (receipt.payer.toLowerCase() !== statement.payer.toLowerCase()) {
119
+ return { valid: false, error: `Payer mismatch: expected ${statement.payer}, got ${receipt.payer}` };
120
+ }
121
+ if (receipt.receiver.toLowerCase() !== statement.receiver.toLowerCase()) {
122
+ return { valid: false, error: `Receiver mismatch: expected ${statement.receiver}, got ${receipt.receiver}` };
123
+ }
124
+ if (receipt.currency !== statement.currency) {
125
+ return { valid: false, error: `Currency mismatch: expected ${statement.currency}, got ${receipt.currency}` };
126
+ }
127
+ if (receipt.settledAmount !== statement.grossAmount) {
128
+ return { valid: false, error: `Settled amount mismatch: expected ${statement.grossAmount}, got ${receipt.settledAmount}` };
129
+ }
130
+ return { valid: true };
131
+ }
132
+ /**
133
+ * Simulates atomic Delivery-vs-Payment (DvP) trade execution inside a secure TEE enclave.
134
+ */
135
+ export function executeDvpSettlement(event, assetQuantity, assetConfirmed, cashConfirmed, enclaveMeasurement = 'sha256:d0e0af6c00aede25451ce3a67df4a45d0d964c7b9196dc725dd310723eb8a49f') {
136
+ const timestamp = Math.floor(Date.now() / 1000);
137
+ if (!assetConfirmed || !cashConfirmed) {
138
+ return {
139
+ tradeId: event.tradeId,
140
+ status: 'REFUSED_FAILED_LEG',
141
+ assetLeg: {
142
+ assetIdentifier: event.isinOrCusip || 'N/A',
143
+ from: event.receiver, // Asset seller
144
+ to: event.payer, // Asset buyer
145
+ quantity: assetQuantity,
146
+ status: assetConfirmed ? 'TRANSFERRED' : 'PENDING',
147
+ },
148
+ cashLeg: {
149
+ currency: event.settlementCurrency,
150
+ from: event.payer,
151
+ to: event.receiver,
152
+ amount: event.notionalAmount,
153
+ status: cashConfirmed ? 'SETTLED' : 'PENDING',
154
+ },
155
+ enclaveProofDigest: 'sha256:0000000000000000000000000000000000000000000000000000000000000000',
156
+ settlementTimestamp: timestamp,
157
+ };
158
+ }
159
+ const rawProof = `${event.tradeId}:${event.isinOrCusip}:${event.notionalAmount}:${enclaveMeasurement}:${timestamp}`;
160
+ const proofDigest = `sha256:${createHash('sha256').update(rawProof, 'utf8').digest('hex')}`;
161
+ return {
162
+ tradeId: event.tradeId,
163
+ status: 'SETTLED',
164
+ assetLeg: {
165
+ assetIdentifier: event.isinOrCusip || 'N/A',
166
+ from: event.receiver,
167
+ to: event.payer,
168
+ quantity: assetQuantity,
169
+ status: 'TRANSFERRED',
170
+ },
171
+ cashLeg: {
172
+ currency: event.settlementCurrency,
173
+ from: event.payer,
174
+ to: event.receiver,
175
+ amount: event.notionalAmount,
176
+ status: 'SETTLED',
177
+ },
178
+ enclaveProofDigest: proofDigest,
179
+ settlementTimestamp: timestamp,
180
+ };
181
+ }
182
+ //# sourceMappingURL=isda-cdm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isda-cdm.js","sourceRoot":"","sources":["../src/isda-cdm.ts"],"names":[],"mappings":"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"}