twzrd-x402-gate 0.8.1 → 0.8.3

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
@@ -2,9 +2,58 @@
2
2
 
3
3
  **TWZRD is the default `onBeforePaymentCreation` policy engine for official x402 clients.**
4
4
 
5
- Agent-side firewall: after the client selects the exact payment requirement and **before**
6
- payment payload creation / wallet signing — free preflight + merchant_card wash refuse.
7
- Chain-neutral envelope; **Solana-deep** reputation only (Base/EVM = explicit `unknown`).
5
+ **Core product (buyer gate):** after the client selects the exact payment requirement and
6
+ **before** payment payload creation / wallet signing — free preflight + merchant_card wash
7
+ refuse. Protects the **payer** from a risky **merchant** (`payTo`). Chain-neutral envelope;
8
+ **Solana-deep** reputation only (Base/EVM = explicit `unknown`).
9
+
10
+ **Optional (0.8.1):** a resource-server settle hook so merchants can apply **customer policy**
11
+ before they settle and serve (abuse, sanctions, bots, “don’t serve this payer”). Not an equal
12
+ mirror of the buyer problem — settled USDC is final; wash resistance is mainly TWZRD scoring.
13
+
14
+ ## Seller settle guard (`onBeforeSettle`) — optional 0.8.1
15
+
16
+ Resource servers can screen the **payer** before *they* settle an inbound payment and serve
17
+ the resource. Use for merchant policy (abuse / sanctions / bots / customer selection). TWZRD is
18
+ not in the settlement path: advisory + fail-open by default. Attaches to official
19
+ `x402ResourceServer.onBeforeSettle` (inherited by `@x402/express|hono|next|fastify` and Python x402).
20
+
21
+ Do **not** treat this as “protect merchant reputation by rejecting USDC” — anyone can still
22
+ transfer on-chain. Wash/sybil edges are primarily discounted in TWZRD scoring, not forced
23
+ revenue refusal.
24
+
25
+ ```bash
26
+ npm install twzrd-x402-gate@0.8.2
27
+ ```
28
+
29
+ ```typescript
30
+ import { x402ResourceServer } from "@x402/core/server";
31
+ import { createTwzrdSettleGuard, twzrdPayerScreen } from "twzrd-x402-gate";
32
+
33
+ const server = new x402ResourceServer(facilitator);
34
+ server.onBeforeSettle(
35
+ createTwzrdSettleGuard({ screen: twzrdPayerScreen() }),
36
+ );
37
+ ```
38
+
39
+ **Defaults (fail-open / advisory):**
40
+
41
+ | Behavior | Default |
42
+ |----------|---------|
43
+ | Abort settlement | `decision=block` **or** `wash_flagged=true` |
44
+ | `warn` | **allowed** (continues) unless you set `abortOn.warn` |
45
+ | Default screen | free `GET /v1/intel/merchant_card/{payer}` via `twzrdPayerScreen()` |
46
+ | Screen/extract timeout | `timeoutMs: 3000` — on timeout, **continue** (fail-open) |
47
+ | Unresolved payer / null screen / screen error | **continue** unless `failOpen: false` |
48
+ | Paid `/v1/intel/trust` | **not** default — inject a custom `screen` if you want it |
49
+
50
+ Payer identity prefers signed/encoded scheme fields (EIP-3009 `authorization.from`, Permit2
51
+ `permit2Authorization.from`, exact-SVM `payload.transaction` via optional peer `@x402/svm`)
52
+ over client-supplied loose aliases — so a spoofed `payload.payer` cannot bypass screening.
53
+
54
+ Offline demo: `npx tsx examples/seller-settle-guard.ts`
55
+ Fixture-backed SVM extract tests live in `test/seller-hook.test.ts` +
56
+ `test/fixtures/exact-svm-transfer-checked.ts`.
8
57
 
9
58
 
10
59
  ## Demonstrable refuse mechanism (free, fail-open, reproducible)
@@ -14,7 +63,7 @@ Chain-neutral envelope; **Solana-deep** reputation only (Base/EVM = explicit `un
14
63
  Install the published gate and run against wash fixtures:
15
64
 
16
65
  ```bash
17
- npm install twzrd-x402-gate@0.7.1
66
+ npm install twzrd-x402-gate@0.8.2
18
67
  # from package root after install, or from a checkout:
19
68
  npm run wash-dogfood
20
69
  ```
@@ -34,7 +83,7 @@ Gate dogfood: `approved=false` `reason=twzrd_decision_block`, **USDC spent = 0**
34
83
 
35
84
  **Accurate paste line:**
36
85
 
37
- > Preflight returned decision=block on wash seller 7G73PL… / HuSiSpc… (preflight_id 378468 / 378469, wash_flagged=true). Gate approved=false reason=twzrd_decision_block. No USDC spent. No tx broadcast. Repro: `npm i twzrd-x402-gate@0.7.1 && npm run wash-dogfood` or gist above.
86
+ > Preflight returned decision=block on wash seller 7G73PL… / HuSiSpc… (preflight_id 378468 / 378469, wash_flagged=true). Gate approved=false reason=twzrd_decision_block. No USDC spent. No tx broadcast. Repro: `npm i twzrd-x402-gate@0.8.1 && npm run wash-dogfood` or gist above.
38
87
 
39
88
  This is a **reproducible demonstration** that the free gate blocks known wash sellers with stamped `preflight_id`s and zero spend. It is **not** proof that external agents already default to this path at scale.
40
89
 
@@ -116,17 +165,27 @@ Canonical path for every agent that spends USDC on Solana x402:
116
165
 
117
166
  **Order note:** `onWarnUpsell` (points at paid `/trust`) fires on preflight `warn` **before** the merchant_card wash check. A wash-flagged seller that preflighted as `warn` may still get the upsell hook, then be refused on step 2.
118
167
 
119
- Dogfood:
168
+ Dogfood (one public live proof path):
120
169
  - Free only (wash refuse): `npm run wash-dogfood` → [`examples/wash-refuse-dogfood.ts`](./examples/wash-refuse-dogfood.ts)
121
170
  - Official client + Path E hook (live Solana ≤$0.001): `npm run official-dogfood` → [`examples/official-x402-dogfood.ts`](./examples/official-x402-dogfood.ts). Needs `@x402/fetch` `@x402/svm` `@x402/core` `@solana/kit` `@scure/base` and a funded Solana key (`SVM_KEYPAIR_PATH` or `~/.agentcash/solana-wallet.json`). `--block` exercises hard `gateOnCanSpend` abort with $0 spend.
171
+ - Multi-hook composition (amount cap then TWZRD, abort short-circuit) is proven offline against the real `x402Client` in `test/x402-official-compat.test.ts`.
172
+ - Release identity: `CLIENT_VERSION` is read from `package.json` (single source of truth); `npm test` includes `version-identity`; `npm run pack-smoke` packs the tarball and checks the installed header.
122
173
 
123
174
  ## Install
124
175
 
125
176
  ```bash
126
- npm install twzrd-x402-gate@0.7.1
177
+ npm install twzrd-x402-gate@0.8.2
127
178
  ```
128
179
 
129
- Current npm truth: check `npm view twzrd-x402-gate version` (do not pin stale **0.5.4**).
180
+ Current npm truth: `0.8.2` (buyer gate + optional seller settle guard + payer-extract hardening).
181
+ Check `npm view twzrd-x402-gate version` if in doubt (do not pin stale **0.5.4** / **0.7.1**).
182
+
183
+ Optional settle guard (resource-server **payer** policy): see **Seller settle guard
184
+ (`onBeforeSettle`) — optional 0.8.1** above. Do not confuse with facilitator
185
+ `createOnBeforeSettleHook` in `@wzrd_sol/plugin-trustgate/facilitator` — that screens
186
+ the **merchant/payTo** on a brokered settle (buyer-side counterparty check at the rail).
187
+
188
+ Live card screen: `npx tsx examples/seller-settle-guard.ts --live <payerWallet>`
130
189
 
131
190
  ## TWZRD Payment Control (protocol-neutral authorization core)
132
191
 
@@ -299,6 +358,18 @@ Library: `import { safeFetch } from "twzrd-x402-gate/safe-fetch"`.
299
358
 
300
359
  ## Quickstart: `installTwzrdAutoGate` (default-on)
301
360
 
361
+ Canonical entry point (design: `docs/strategy/install-autogate-design.md`). One name, three adapters:
362
+
363
+ | Call | Adapter |
364
+ |------|---------|
365
+ | `installTwzrdAutoGate(payWrap, opts?)` | Fetch: guard raw fetch → pay client |
366
+ | `installTwzrdAutoGate(x402Client, opts?)` | Official x402 `onBeforePaymentCreation` |
367
+ | `installTwzrdAutoGate("mpp", opts)` | MPP `onChallenge` (returns handler) |
368
+
369
+ Aliases: `installTwzrdX402ClientHook`, `createTwzrdMppOnChallenge` remain; docs prefer AutoGate.
370
+ Kill switch: `TWZRD_GATE_ENABLED=false` or `TWZRD_AUTO_GATE=0`. Uninstall x402 installs with `uninstallTwzrdAutoGate(client)`.
371
+
372
+
302
373
  `installTwzrdAutoGate` is the one-liner form of "guard the raw fetch, then hand it to your
303
374
  x402 client." It takes a `payWrap` function — whatever composes your paying client on top of
304
375
  a fetch — and returns a fetch that's already gated: a blocked seller throws before your client
@@ -592,6 +663,16 @@ A 402 whose payment requirements yield **no identifiable seller wallet** (missin
592
663
  | `disabled` (`installTwzrdAutoGate` only) | `TWZRD_AUTO_GATE=0`/`false` | `false` | Bypass the guard entirely — `payWrap` gets the raw, unguarded fetch |
593
664
  | `attribution` | `TWZRD_ATTRIBUTION_INTEGRATION` + `TWZRD_ATTRIBUTION_RUN_ID` | — | Opt-in run attribution (see below) |
594
665
 
666
+ ## Gate adoption proof (no-spend harness)
667
+
668
+ Deterministic install→transcript path for operators (no wallet, no USDC):
669
+
670
+ ```bash
671
+ npm run adoption-proof -- --integration <YOUR_ID> --run-id <UUID>
672
+ ```
673
+
674
+ Emits `twzrd.gate_adoption_transcript.v1` JSON: block path aborts with `signerInvocations: 0`, allow path emits decision, attribution headers stamped on mocked preflight. Full acceptance criteria (what counts as `EXTERNAL_RUN` vs dogfood): monorepo `docs/strategy/gate-adoption-operator-proof.md`.
675
+
595
676
  ## Run attribution (optional, for integration correlation)
596
677
 
597
678
  When you set `attribution`, the gate stamps **only the TWZRD preflight request** (never the
@@ -632,8 +713,10 @@ If you're composing `withTwzrdGuard` manually instead, pass the raw (non-paying)
632
713
 
633
714
  `GET /v1/intel/trust/{wallet}` is the **paid** ($0.05 USDC) deep-intel surface — not a gate.
634
715
  `POST /v1/intel/preflight` is the **free** `ReadinessCard` for the pre-spend decision.
635
- This package only ever calls the free preflight; you decide whether to proceed before any
636
- USDC leaves your wallet.
716
+ The gate path only ever calls free endpoints — the preflight plus, by default
717
+ (`refuseWashFlagged: true`), the free merchant_card wash check. Paid intel
718
+ (`quickCheck`, `autoReceipt`) is opt-in and never runs implicitly; you decide
719
+ whether to proceed before any USDC leaves your wallet.
637
720
 
638
721
  ## License
639
722
 
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Gate Adoption Proof Harness — deterministic, no-spend, package-local.
3
+ *
4
+ * Closes the install→transcript gap for operators who already installed
5
+ * installTwzrdX402ClientHook / installTwzrdAutoGate:
6
+ * 1) exact selectedRequirements reach the pre-sign hook
7
+ * 2) onDecision emits a verdict
8
+ * 3) block path aborts and never invokes a wallet/signer stub
9
+ * 4) attribution (integration + runId + client) is stamped on preflight only
10
+ *
11
+ * This harness is correlation / integration evidence. It is NOT EXTERNAL_RUN
12
+ * by itself (see docs/strategy/gate-adoption-operator-proof.md).
13
+ */
14
+ import { type X402SelectedRequirements } from "./x402-client-hook.js";
15
+ export declare const ADOPTION_TRANSCRIPT_SCHEMA: "twzrd.gate_adoption_transcript.v1";
16
+ /** Fixture merchant pubkey (base58-shaped); not a live spend target. */
17
+ export declare const ADOPTION_PROOF_SELLER = "sLJ4uneGcD1mg6hKtkLYsY5HCw1nJ8GpNAmbzBWPBgk";
18
+ export declare const ADOPTION_PROOF_NETWORK = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
19
+ export declare const ADOPTION_PROOF_RESOURCE = "https://merchant.example/twzrd-adoption-proof";
20
+ export type GateAdoptionStepName = "block_path" | "allow_path";
21
+ export type GateAdoptionStep = {
22
+ name: GateAdoptionStepName;
23
+ selectedRequirements: X402SelectedRequirements;
24
+ abort: boolean;
25
+ reason?: string;
26
+ decisionEmitted: boolean;
27
+ verdict: string;
28
+ approved: boolean;
29
+ /**
30
+ * payTo as reported by the hook's onDecision callback (hook-derived).
31
+ * Used to prove selectedRequirements reached the real hook path — not
32
+ * merely echoed from harness-local selectedRequirements.
33
+ */
34
+ hookPayTo?: string;
35
+ /**
36
+ * seller_wallet from the preflight JSON body the hook actually POSTed
37
+ * (hook-derived via mocked fetch recorder).
38
+ */
39
+ preflightSellerWallet?: string | null;
40
+ /** Count of wallet/signer stub invocations during this step (must be 0). */
41
+ signerInvocations: number;
42
+ /** Headers observed on the mocked preflight fetch for this step. */
43
+ preflightAttribution: {
44
+ integration: string | null;
45
+ runId: string | null;
46
+ client: string | null;
47
+ };
48
+ };
49
+ export type GateAdoptionAssertions = {
50
+ selectedRequirementReachedHook: boolean;
51
+ decisionEmitted: boolean;
52
+ blockedPathNeverInvokesSigner: boolean;
53
+ allowPathNeverInvokesSigner: boolean;
54
+ attributionSurfaced: boolean;
55
+ };
56
+ /**
57
+ * Lineage of this transcript.
58
+ * - dogfood: package harness, CI, or TWZRD-authored run
59
+ * - external_candidate: operator-supplied integration id (still needs server-side join for EXTERNAL_RUN)
60
+ */
61
+ export type GateAdoptionLineage = "dogfood" | "external_candidate";
62
+ export type GateAdoptionTranscript = {
63
+ schema: typeof ADOPTION_TRANSCRIPT_SCHEMA;
64
+ package: "twzrd-x402-gate";
65
+ packageVersion: string;
66
+ proofKind: "local_deterministic_harness";
67
+ mode: "no_spend";
68
+ integration: string;
69
+ runId: string;
70
+ lineage: GateAdoptionLineage;
71
+ clientHeader: string;
72
+ steps: GateAdoptionStep[];
73
+ assertions: GateAdoptionAssertions;
74
+ ok: boolean;
75
+ /**
76
+ * What this transcript is NOT. Operators must not treat package downloads,
77
+ * free preflight hits alone, or self-authored runIds as EXTERNAL_RUN.
78
+ */
79
+ notExternalRunProof: string[];
80
+ /** Human pointer to the acceptance contract. */
81
+ acceptanceDoc: "docs/strategy/gate-adoption-operator-proof.md";
82
+ };
83
+ export type RunGateAdoptionProofOptions = {
84
+ /** Stable integration label (e.g. "acme-agent-v1"). Default dogfood label. */
85
+ integration?: string;
86
+ /** Per-run id. Default random UUID. Echo in your issue / transcript. */
87
+ runId?: string;
88
+ /**
89
+ * Mark lineage external_candidate when the operator sets a non-internal integration id.
90
+ * Still not EXTERNAL_RUN without server-side observation (see acceptance doc).
91
+ */
92
+ lineage?: GateAdoptionLineage;
93
+ };
94
+ /**
95
+ * Run the deterministic no-spend adoption proof.
96
+ * Never contacts a wallet; never spends USDC. Preflight is mocked.
97
+ */
98
+ export declare function runGateAdoptionProof(opts?: RunGateAdoptionProofOptions): Promise<GateAdoptionTranscript>;
99
+ /** CLI entry: print one JSON transcript to stdout; exit 0 if ok else 1. */
100
+ export declare function main(argv?: string[]): Promise<number>;
101
+ //# sourceMappingURL=adoption-proof.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adoption-proof.d.ts","sourceRoot":"","sources":["../src/adoption-proof.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAKL,KAAK,wBAAwB,EAC9B,MAAM,uBAAuB,CAAC;AAE/B,eAAO,MAAM,0BAA0B,EAAG,mCAA4C,CAAC;AAEvF,wEAAwE;AACxE,eAAO,MAAM,qBAAqB,gDAAgD,CAAC;AACnF,eAAO,MAAM,sBAAsB,4CAA4C,CAAC;AAChF,eAAO,MAAM,uBAAuB,kDAAkD,CAAC;AAEvF,MAAM,MAAM,oBAAoB,GAAG,YAAY,GAAG,YAAY,CAAC;AAE/D,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,oBAAoB,CAAC;IAC3B,oBAAoB,EAAE,wBAAwB,CAAC;IAC/C,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,OAAO,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,4EAA4E;IAC5E,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oEAAoE;IACpE,oBAAoB,EAAE;QACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;KACvB,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,8BAA8B,EAAE,OAAO,CAAC;IACxC,eAAe,EAAE,OAAO,CAAC;IACzB,6BAA6B,EAAE,OAAO,CAAC;IACvC,2BAA2B,EAAE,OAAO,CAAC;IACrC,mBAAmB,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG,oBAAoB,CAAC;AAEnE,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,EAAE,OAAO,0BAA0B,CAAC;IAC1C,OAAO,EAAE,iBAAiB,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,6BAA6B,CAAC;IACzC,IAAI,EAAE,UAAU,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,mBAAmB,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,UAAU,EAAE,sBAAsB,CAAC;IACnC,EAAE,EAAE,OAAO,CAAC;IACZ;;;OAGG;IACH,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,gDAAgD;IAChD,aAAa,EAAE,+CAA+C,CAAC;CAChE,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,OAAO,CAAC,EAAE,mBAAmB,CAAC;CAC/B,CAAC;AA8FF;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,GAAE,2BAAgC,GACrC,OAAO,CAAC,sBAAsB,CAAC,CAsLjC;AAED,2EAA2E;AAC3E,wBAAsB,IAAI,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,OAAO,CAAC,MAAM,CAAC,CAmBlF"}
@@ -0,0 +1,290 @@
1
+ /**
2
+ * Gate Adoption Proof Harness — deterministic, no-spend, package-local.
3
+ *
4
+ * Closes the install→transcript gap for operators who already installed
5
+ * installTwzrdX402ClientHook / installTwzrdAutoGate:
6
+ * 1) exact selectedRequirements reach the pre-sign hook
7
+ * 2) onDecision emits a verdict
8
+ * 3) block path aborts and never invokes a wallet/signer stub
9
+ * 4) attribution (integration + runId + client) is stamped on preflight only
10
+ *
11
+ * This harness is correlation / integration evidence. It is NOT EXTERNAL_RUN
12
+ * by itself (see docs/strategy/gate-adoption-operator-proof.md).
13
+ */
14
+ import { CLIENT_VERSION } from "./version.js";
15
+ import { installTwzrdX402ClientHook, } from "./x402-client-hook.js";
16
+ export const ADOPTION_TRANSCRIPT_SCHEMA = "twzrd.gate_adoption_transcript.v1";
17
+ /** Fixture merchant pubkey (base58-shaped); not a live spend target. */
18
+ export const ADOPTION_PROOF_SELLER = "sLJ4uneGcD1mg6hKtkLYsY5HCw1nJ8GpNAmbzBWPBgk";
19
+ export const ADOPTION_PROOF_NETWORK = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
20
+ export const ADOPTION_PROOF_RESOURCE = "https://merchant.example/twzrd-adoption-proof";
21
+ function mockClient() {
22
+ let hook;
23
+ const client = {
24
+ onBeforePaymentCreation(h) {
25
+ hook = h;
26
+ return client;
27
+ },
28
+ };
29
+ return {
30
+ client,
31
+ async fire(ctx) {
32
+ if (!hook)
33
+ throw new Error("adoption-proof: hook not installed");
34
+ return hook(ctx);
35
+ },
36
+ };
37
+ }
38
+ function preflightCard(decision, canSpend) {
39
+ return {
40
+ readiness_card: {
41
+ decision,
42
+ can_spend: canSpend,
43
+ trust_score: decision === "block" || !canSpend ? 10 : 90,
44
+ seller_wallet: ADOPTION_PROOF_SELLER,
45
+ },
46
+ preflight_id: decision === "block" || !canSpend ? 1 : 2,
47
+ };
48
+ }
49
+ function recordingPreflightFetch(body) {
50
+ let last = null;
51
+ let lastSeller = null;
52
+ const fetchImpl = (async (_url, init) => {
53
+ last = new Headers(init?.headers);
54
+ lastSeller = null;
55
+ if (typeof init?.body === "string") {
56
+ try {
57
+ const parsed = JSON.parse(init.body);
58
+ if (typeof parsed.seller_wallet === "string")
59
+ lastSeller = parsed.seller_wallet;
60
+ }
61
+ catch {
62
+ // ignore non-JSON bodies
63
+ }
64
+ }
65
+ return new Response(JSON.stringify(body), {
66
+ status: 200,
67
+ headers: { "content-type": "application/json" },
68
+ });
69
+ });
70
+ return {
71
+ fetch: fetchImpl,
72
+ lastHeaders: () => last,
73
+ lastSellerWallet: () => lastSeller,
74
+ };
75
+ }
76
+ function baseRequirements(amount) {
77
+ return {
78
+ payTo: ADOPTION_PROOF_SELLER,
79
+ network: ADOPTION_PROOF_NETWORK,
80
+ amount,
81
+ asset: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
82
+ resource: ADOPTION_PROOF_RESOURCE,
83
+ scheme: "exact",
84
+ };
85
+ }
86
+ function isInternalIntegration(integration) {
87
+ const i = integration.toLowerCase();
88
+ return (i.startsWith("twzrd-") ||
89
+ i.startsWith("twzrd/") ||
90
+ i.startsWith("ops-") ||
91
+ i.startsWith("test-") ||
92
+ i === "dogfood" ||
93
+ i.includes("dogfood") ||
94
+ i.includes("internal") ||
95
+ i.includes("ci-") ||
96
+ i === "gate-adoption-proof");
97
+ }
98
+ /**
99
+ * Run the deterministic no-spend adoption proof.
100
+ * Never contacts a wallet; never spends USDC. Preflight is mocked.
101
+ */
102
+ export async function runGateAdoptionProof(opts = {}) {
103
+ const integration = opts.integration?.trim() || "gate-adoption-proof";
104
+ const runId = opts.runId?.trim() ||
105
+ (typeof crypto !== "undefined" && "randomUUID" in crypto
106
+ ? crypto.randomUUID()
107
+ : `run-${Date.now()}`);
108
+ const lineage = opts.lineage ??
109
+ (isInternalIntegration(integration) ? "dogfood" : "external_candidate");
110
+ const clientHeader = `twzrd-x402-gate/${CLIENT_VERSION}`;
111
+ const steps = [];
112
+ // ── block path: can_spend false → abort, signer must stay 0 ─────────────
113
+ {
114
+ const signerInvocations = { n: 0 };
115
+ const signer = {
116
+ async sign() {
117
+ signerInvocations.n += 1;
118
+ throw new Error("adoption-proof: signer must not be called");
119
+ },
120
+ };
121
+ const { fetch, lastHeaders, lastSellerWallet } = recordingPreflightFetch(preflightCard("warn", false));
122
+ const { client, fire } = mockClient();
123
+ let decisionDetail;
124
+ installTwzrdX402ClientHook(client, {
125
+ gateOnCanSpend: true,
126
+ refuseWashFlagged: false,
127
+ fetch,
128
+ attribution: { integration, runId },
129
+ onDecision: (d) => {
130
+ decisionDetail = {
131
+ approved: d.approved,
132
+ verdict: d.verdict,
133
+ reason: d.reason,
134
+ payTo: d.payTo,
135
+ };
136
+ },
137
+ });
138
+ // Operator would call wallet.signMessage only after hook returns non-abort.
139
+ // We only invoke signer if the hook allows — proving block never reaches it.
140
+ const req = baseRequirements("1000");
141
+ const result = await fire({ selectedRequirements: req });
142
+ const abort = Boolean(result && typeof result === "object" && "abort" in result && result.abort);
143
+ if (!abort) {
144
+ await signer.sign();
145
+ }
146
+ const h = lastHeaders();
147
+ const abortReason = abort && result && typeof result === "object" && "reason" in result
148
+ ? String(result.reason)
149
+ : undefined;
150
+ steps.push({
151
+ name: "block_path",
152
+ selectedRequirements: req,
153
+ abort,
154
+ reason: abortReason,
155
+ decisionEmitted: decisionDetail != null,
156
+ verdict: decisionDetail?.verdict ?? "missing",
157
+ approved: decisionDetail?.approved ?? false,
158
+ hookPayTo: decisionDetail?.payTo,
159
+ preflightSellerWallet: lastSellerWallet(),
160
+ signerInvocations: signerInvocations.n,
161
+ preflightAttribution: {
162
+ integration: h?.get("x-twzrd-integration") ?? null,
163
+ runId: h?.get("x-twzrd-run-id") ?? null,
164
+ client: h?.get("x-twzrd-client") ?? null,
165
+ },
166
+ });
167
+ }
168
+ // ── allow path: decision allow, still no real wallet spend ──────────────
169
+ {
170
+ const signerInvocations = { n: 0 };
171
+ const { fetch, lastHeaders, lastSellerWallet } = recordingPreflightFetch(preflightCard("allow", true));
172
+ const { client, fire } = mockClient();
173
+ let decisionDetail;
174
+ installTwzrdX402ClientHook(client, {
175
+ gateOnCanSpend: true,
176
+ refuseWashFlagged: false,
177
+ preflightMinScore: 40,
178
+ fetch,
179
+ attribution: { integration, runId },
180
+ onDecision: (d) => {
181
+ decisionDetail = {
182
+ approved: d.approved,
183
+ verdict: d.verdict,
184
+ reason: d.reason,
185
+ payTo: d.payTo,
186
+ };
187
+ },
188
+ });
189
+ const req = baseRequirements("1000");
190
+ const result = await fire({ selectedRequirements: req });
191
+ const abort = Boolean(result && typeof result === "object" && "abort" in result && result.abort);
192
+ // Allow path: payload construction would run next — we do not call a wallet signer
193
+ // in this no_spend harness (proves allow decision without spend).
194
+ void signerInvocations;
195
+ const h = lastHeaders();
196
+ steps.push({
197
+ name: "allow_path",
198
+ selectedRequirements: req,
199
+ abort,
200
+ reason: abort && result && typeof result === "object" && "reason" in result
201
+ ? String(result.reason)
202
+ : undefined,
203
+ decisionEmitted: decisionDetail != null,
204
+ verdict: decisionDetail?.verdict ?? "missing",
205
+ approved: decisionDetail?.approved ?? false,
206
+ hookPayTo: decisionDetail?.payTo,
207
+ preflightSellerWallet: lastSellerWallet(),
208
+ signerInvocations: signerInvocations.n,
209
+ preflightAttribution: {
210
+ integration: h?.get("x-twzrd-integration") ?? null,
211
+ runId: h?.get("x-twzrd-run-id") ?? null,
212
+ client: h?.get("x-twzrd-client") ?? null,
213
+ },
214
+ });
215
+ }
216
+ const block = steps.find((s) => s.name === "block_path");
217
+ const allow = steps.find((s) => s.name === "allow_path");
218
+ // Hook-derived only: onDecision.payTo, abort reason, and preflight POST body.
219
+ // Do NOT use step.selectedRequirements (harness-echo) for this flag.
220
+ const blockHookSawSeller = block.hookPayTo === ADOPTION_PROOF_SELLER ||
221
+ (typeof block.reason === "string" && block.reason.includes(ADOPTION_PROOF_SELLER)) ||
222
+ block.preflightSellerWallet === ADOPTION_PROOF_SELLER;
223
+ const allowHookSawSeller = allow.hookPayTo === ADOPTION_PROOF_SELLER ||
224
+ allow.preflightSellerWallet === ADOPTION_PROOF_SELLER;
225
+ const assertions = {
226
+ selectedRequirementReachedHook: blockHookSawSeller && allowHookSawSeller,
227
+ decisionEmitted: block.decisionEmitted && allow.decisionEmitted,
228
+ blockedPathNeverInvokesSigner: block.abort === true && block.signerInvocations === 0,
229
+ allowPathNeverInvokesSigner: allow.signerInvocations === 0 && allow.abort === false,
230
+ attributionSurfaced: block.preflightAttribution.integration === integration &&
231
+ block.preflightAttribution.runId === runId &&
232
+ block.preflightAttribution.client === clientHeader &&
233
+ allow.preflightAttribution.integration === integration &&
234
+ allow.preflightAttribution.runId === runId,
235
+ };
236
+ const ok = Object.values(assertions).every(Boolean);
237
+ return {
238
+ schema: ADOPTION_TRANSCRIPT_SCHEMA,
239
+ package: "twzrd-x402-gate",
240
+ packageVersion: CLIENT_VERSION,
241
+ proofKind: "local_deterministic_harness",
242
+ mode: "no_spend",
243
+ integration,
244
+ runId,
245
+ lineage,
246
+ clientHeader,
247
+ steps,
248
+ assertions,
249
+ ok,
250
+ notExternalRunProof: [
251
+ "package_download_counts",
252
+ "preflight_hits_alone",
253
+ "self_authored_run_id_without_operator_transcript",
254
+ "this_harness_alone_without_server_side_join",
255
+ ],
256
+ acceptanceDoc: "docs/strategy/gate-adoption-operator-proof.md",
257
+ };
258
+ }
259
+ /** CLI entry: print one JSON transcript to stdout; exit 0 if ok else 1. */
260
+ export async function main(argv = process.argv.slice(2)) {
261
+ let integration;
262
+ let runId;
263
+ for (let i = 0; i < argv.length; i++) {
264
+ const a = argv[i];
265
+ if (a === "--integration" && argv[i + 1])
266
+ integration = argv[++i];
267
+ else if (a === "--run-id" && argv[i + 1])
268
+ runId = argv[++i];
269
+ else if (a === "--help" || a === "-h") {
270
+ process.stdout.write("Usage: npm run adoption-proof -- [--integration <id>] [--run-id <uuid>]\n" +
271
+ "Deterministic no-spend gate adoption transcript (JSON on stdout).\n" +
272
+ "See docs/strategy/gate-adoption-operator-proof.md\n");
273
+ return 0;
274
+ }
275
+ }
276
+ const transcript = await runGateAdoptionProof({ integration, runId });
277
+ process.stdout.write(`${JSON.stringify(transcript, null, 2)}\n`);
278
+ return transcript.ok ? 0 : 1;
279
+ }
280
+ const isDirect = typeof process !== "undefined" &&
281
+ process.argv[1] &&
282
+ (process.argv[1].endsWith("adoption-proof.ts") ||
283
+ process.argv[1].endsWith("adoption-proof.js"));
284
+ if (isDirect) {
285
+ main().then((code) => process.exit(code), (err) => {
286
+ console.error(err);
287
+ process.exit(1);
288
+ });
289
+ }
290
+ //# sourceMappingURL=adoption-proof.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adoption-proof.js","sourceRoot":"","sources":["../src/adoption-proof.ts"],"names":[],"mappings":"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"}