twzrd-x402-gate 0.10.0 → 0.11.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 (186) hide show
  1. package/CHANGELOG.md +146 -0
  2. package/QUICKSTART.md +76 -14
  3. package/README.md +284 -50
  4. package/bin/twzrd-bounty-preflight.js +63 -0
  5. package/bin/twzrd-cold-start.js +69 -0
  6. package/bin/twzrd-evidence-bundle.js +10 -3
  7. package/bin/twzrd-payment-decision.js +25 -0
  8. package/dist/adoption-proof.d.ts +8 -0
  9. package/dist/adoption-proof.d.ts.map +1 -1
  10. package/dist/adoption-proof.js +13 -2
  11. package/dist/adoption-proof.js.map +1 -1
  12. package/dist/attempt-echo.d.ts +42 -0
  13. package/dist/attempt-echo.d.ts.map +1 -0
  14. package/dist/attempt-echo.js +170 -0
  15. package/dist/attempt-echo.js.map +1 -0
  16. package/dist/auto-gate.d.ts +43 -4
  17. package/dist/auto-gate.d.ts.map +1 -1
  18. package/dist/auto-gate.js +112 -22
  19. package/dist/auto-gate.js.map +1 -1
  20. package/dist/bounty-preflight-cli.d.ts +25 -0
  21. package/dist/bounty-preflight-cli.d.ts.map +1 -0
  22. package/dist/bounty-preflight-cli.js +157 -0
  23. package/dist/bounty-preflight-cli.js.map +1 -0
  24. package/dist/bounty-preflight.d.ts +140 -0
  25. package/dist/bounty-preflight.d.ts.map +1 -0
  26. package/dist/bounty-preflight.js +208 -0
  27. package/dist/bounty-preflight.js.map +1 -0
  28. package/dist/buyer-defaults.d.ts +4 -3
  29. package/dist/buyer-defaults.d.ts.map +1 -1
  30. package/dist/buyer-defaults.js +5 -4
  31. package/dist/buyer-defaults.js.map +1 -1
  32. package/dist/cloudflare-base.d.ts +49 -0
  33. package/dist/cloudflare-base.d.ts.map +1 -0
  34. package/dist/cloudflare-base.js +113 -0
  35. package/dist/cloudflare-base.js.map +1 -0
  36. package/dist/cloudflare-x402.d.ts +29 -0
  37. package/dist/cloudflare-x402.d.ts.map +1 -0
  38. package/dist/cloudflare-x402.js +31 -0
  39. package/dist/cloudflare-x402.js.map +1 -0
  40. package/dist/cold-start.d.ts +124 -0
  41. package/dist/cold-start.d.ts.map +1 -0
  42. package/dist/cold-start.js +515 -0
  43. package/dist/cold-start.js.map +1 -0
  44. package/dist/config.d.ts +4 -1
  45. package/dist/config.d.ts.map +1 -1
  46. package/dist/config.js +18 -9
  47. package/dist/config.js.map +1 -1
  48. package/dist/consumer-adjacency.d.ts +79 -0
  49. package/dist/consumer-adjacency.d.ts.map +1 -0
  50. package/dist/consumer-adjacency.js +236 -0
  51. package/dist/consumer-adjacency.js.map +1 -0
  52. package/dist/decision-token.d.ts +1 -1
  53. package/dist/delivery-capture.d.ts +4 -3
  54. package/dist/delivery-capture.d.ts.map +1 -1
  55. package/dist/delivery-capture.js +4 -3
  56. package/dist/delivery-capture.js.map +1 -1
  57. package/dist/doctor.d.ts.map +1 -1
  58. package/dist/doctor.js +29 -7
  59. package/dist/doctor.js.map +1 -1
  60. package/dist/evaluate.d.ts +46 -15
  61. package/dist/evaluate.d.ts.map +1 -1
  62. package/dist/evaluate.js +140 -48
  63. package/dist/evaluate.js.map +1 -1
  64. package/dist/evidence-bundle.d.ts +50 -0
  65. package/dist/evidence-bundle.d.ts.map +1 -1
  66. package/dist/evidence-bundle.js +95 -14
  67. package/dist/evidence-bundle.js.map +1 -1
  68. package/dist/evidence-verify.d.ts +145 -0
  69. package/dist/evidence-verify.d.ts.map +1 -0
  70. package/dist/evidence-verify.js +784 -0
  71. package/dist/evidence-verify.js.map +1 -0
  72. package/dist/foreign-key.d.ts +23 -0
  73. package/dist/foreign-key.d.ts.map +1 -0
  74. package/dist/foreign-key.js +66 -0
  75. package/dist/foreign-key.js.map +1 -0
  76. package/dist/guarded-x402-fetch.d.ts +33 -0
  77. package/dist/guarded-x402-fetch.d.ts.map +1 -0
  78. package/dist/guarded-x402-fetch.js +201 -0
  79. package/dist/guarded-x402-fetch.js.map +1 -0
  80. package/dist/index.d.ts +19 -5
  81. package/dist/index.d.ts.map +1 -1
  82. package/dist/index.js +23 -6
  83. package/dist/index.js.map +1 -1
  84. package/dist/intelligence.js +2 -2
  85. package/dist/intelligence.js.map +1 -1
  86. package/dist/intent-adapters.d.ts.map +1 -1
  87. package/dist/intent-adapters.js +6 -2
  88. package/dist/intent-adapters.js.map +1 -1
  89. package/dist/log-inclusion.d.ts +135 -0
  90. package/dist/log-inclusion.d.ts.map +1 -0
  91. package/dist/log-inclusion.js +127 -0
  92. package/dist/log-inclusion.js.map +1 -0
  93. package/dist/mcp-hook.d.ts.map +1 -1
  94. package/dist/mcp-hook.js +5 -1
  95. package/dist/mcp-hook.js.map +1 -1
  96. package/dist/merchant-card.d.ts +51 -2
  97. package/dist/merchant-card.d.ts.map +1 -1
  98. package/dist/merchant-card.js +70 -13
  99. package/dist/merchant-card.js.map +1 -1
  100. package/dist/mpp-hook.d.ts.map +1 -1
  101. package/dist/mpp-hook.js +3 -1
  102. package/dist/mpp-hook.js.map +1 -1
  103. package/dist/network.d.ts +28 -7
  104. package/dist/network.d.ts.map +1 -1
  105. package/dist/network.js +45 -7
  106. package/dist/network.js.map +1 -1
  107. package/dist/paying-fetch.d.ts +17 -0
  108. package/dist/paying-fetch.d.ts.map +1 -0
  109. package/dist/paying-fetch.js +116 -0
  110. package/dist/paying-fetch.js.map +1 -0
  111. package/dist/payment-decision.d.ts +257 -0
  112. package/dist/payment-decision.d.ts.map +1 -0
  113. package/dist/payment-decision.js +690 -0
  114. package/dist/payment-decision.js.map +1 -0
  115. package/dist/payto.d.ts +38 -1
  116. package/dist/payto.d.ts.map +1 -1
  117. package/dist/payto.js +81 -3
  118. package/dist/payto.js.map +1 -1
  119. package/dist/policy-fetch.d.ts +18 -0
  120. package/dist/policy-fetch.d.ts.map +1 -0
  121. package/dist/policy-fetch.js +81 -0
  122. package/dist/policy-fetch.js.map +1 -0
  123. package/dist/policy-runtime.d.ts +3 -1
  124. package/dist/policy-runtime.d.ts.map +1 -1
  125. package/dist/policy-runtime.js +53 -21
  126. package/dist/policy-runtime.js.map +1 -1
  127. package/dist/policy.d.ts +20 -0
  128. package/dist/policy.d.ts.map +1 -1
  129. package/dist/policy.js +286 -57
  130. package/dist/policy.js.map +1 -1
  131. package/dist/quick.d.ts +5 -3
  132. package/dist/quick.d.ts.map +1 -1
  133. package/dist/quick.js.map +1 -1
  134. package/dist/record-leash-settle.d.ts +20 -0
  135. package/dist/record-leash-settle.d.ts.map +1 -0
  136. package/dist/record-leash-settle.js +25 -0
  137. package/dist/record-leash-settle.js.map +1 -0
  138. package/dist/resource-bind-tx.d.ts +4 -0
  139. package/dist/resource-bind-tx.d.ts.map +1 -1
  140. package/dist/resource-bind-tx.js +32 -10
  141. package/dist/resource-bind-tx.js.map +1 -1
  142. package/dist/resource-bind.d.ts +17 -3
  143. package/dist/resource-bind.d.ts.map +1 -1
  144. package/dist/resource-bind.js +93 -22
  145. package/dist/resource-bind.js.map +1 -1
  146. package/dist/safe-fetch.d.ts +2 -0
  147. package/dist/safe-fetch.d.ts.map +1 -1
  148. package/dist/safe-fetch.js +19 -1
  149. package/dist/safe-fetch.js.map +1 -1
  150. package/dist/seller-hook.d.ts +6 -2
  151. package/dist/seller-hook.d.ts.map +1 -1
  152. package/dist/seller-hook.js +44 -8
  153. package/dist/seller-hook.js.map +1 -1
  154. package/dist/spend-control.d.ts +12 -0
  155. package/dist/spend-control.d.ts.map +1 -1
  156. package/dist/spend-control.js +169 -64
  157. package/dist/spend-control.js.map +1 -1
  158. package/dist/spend-ledger-file.d.ts +3 -0
  159. package/dist/spend-ledger-file.d.ts.map +1 -1
  160. package/dist/spend-ledger-file.js +33 -1
  161. package/dist/spend-ledger-file.js.map +1 -1
  162. package/dist/ssrf.d.ts +15 -0
  163. package/dist/ssrf.d.ts.map +1 -0
  164. package/dist/ssrf.js +72 -0
  165. package/dist/ssrf.js.map +1 -0
  166. package/dist/trust-gate-reason.d.ts.map +1 -1
  167. package/dist/trust-gate-reason.js +1 -0
  168. package/dist/trust-gate-reason.js.map +1 -1
  169. package/dist/types.d.ts +74 -12
  170. package/dist/types.d.ts.map +1 -1
  171. package/dist/wash-default.d.ts +131 -0
  172. package/dist/wash-default.d.ts.map +1 -0
  173. package/dist/wash-default.js +329 -0
  174. package/dist/wash-default.js.map +1 -0
  175. package/dist/with-guard.d.ts +3 -3
  176. package/dist/with-guard.d.ts.map +1 -1
  177. package/dist/with-guard.js +13 -11
  178. package/dist/with-guard.js.map +1 -1
  179. package/dist/wrap-fetch.d.ts.map +1 -1
  180. package/dist/wrap-fetch.js +12 -9
  181. package/dist/wrap-fetch.js.map +1 -1
  182. package/dist/x402-client-hook.d.ts +54 -4
  183. package/dist/x402-client-hook.d.ts.map +1 -1
  184. package/dist/x402-client-hook.js +182 -49
  185. package/dist/x402-client-hook.js.map +1 -1
  186. package/package.json +39 -17
package/CHANGELOG.md ADDED
@@ -0,0 +1,146 @@
1
+ # Changelog
2
+
3
+ All notable changes to `twzrd-x402-gate`. Dates are npm publish dates (UTC).
4
+
5
+ ## Versioning policy (from 0.11.0)
6
+
7
+ - **A change to what the gate allows or refuses ships in a minor release** (0.x.0 while
8
+ the package is below 1.0), with an entry here. Below 1.0, npm's caret range stays
9
+ within one minor (`^0.11.0` never resolves to 0.12.0), so nobody gets a new refusal
10
+ policy without choosing it.
11
+ - **Patch releases** (0.x.y) carry fixes that do not change any allow/refuse outcome
12
+ for a well-formed card, plus docs, types and tests.
13
+ - The package is published from this repository only, by the `publish` workflow with an
14
+ `expected_version` input, with npm provenance.
15
+
16
+ ## failOpen, stated once
17
+
18
+ - **Buyer side** (`createTwzrdBeforePaymentHook`, `createGuardedX402Fetch`,
19
+ `withTwzrdGuard`, `evaluate_x402_resource`): fail-closed by default. A preflight that
20
+ returns any non-2xx status or a non-JSON body, or throws, refuses with
21
+ `twzrd_fail_closed`.
22
+ A free merchant-card lookup that returns 5xx/429, a non-JSON body, or throws refuses
23
+ with `twzrd_card_unreachable_fail_closed`. With `failOpen: true` (or
24
+ `TWZRD_FAIL_OPEN=1`) both allow instead. A merchant-card 4xx is intel answering,
25
+ not an outage, and never refuses on its own.
26
+ - **Seller side** (`createTwzrdSettleGuard`): fail-open by default. A screen that throws
27
+ returns without aborting settlement unless `failOpen: false`.
28
+
29
+ ## 0.11.0 — unreleased
30
+
31
+ **Behaviour change: unevaluated sellers follow the card's cap.**
32
+
33
+ - A seller intel has never evaluated (`null_reason` set, or `score: null`) is no longer
34
+ refused outright. Live intel answers such a seller with `decision: "warn"` and a
35
+ `recommended_cap_usdc` of min($0.10, requested price) on 2026-09-28; the gate now allows the
36
+ payment at or under that cap (`twzrd_unevaluated_within_cap_<price>_le_<cap>`) and
37
+ refuses it above the cap, when the card has no cap, or when the price is unknown.
38
+ An approval carries `unevaluated: true` and `score: null`. The free wash check still
39
+ runs after it.
40
+ - New option `refuseUnevaluated` (env `TWZRD_REFUSE_UNEVALUATED`), default `false`.
41
+ `true` restores the 0.9.9–0.9.16 behaviour: every unevaluated seller is refused with
42
+ `twzrd_unevaluated_subject_<null_reason>`. The bounty preflight CLI sets it, so bounty
43
+ payees are still refused when unevaluated.
44
+ - Direct callers of the exported `evaluateReadinessCard` must pass `priceUsdc` to get
45
+ an approval for an unevaluated card. Without it the reason is now
46
+ `twzrd_unevaluated_unknown_price_<null_reason>` (was
47
+ `twzrd_unevaluated_subject_<null_reason>`); `approved` is still `false`.
48
+ - The $0.001 `/quick` escalation (`escalateOnWarn`) no longer runs for an unevaluated
49
+ seller: intel has no paid score for it either, so the hop spent money without being
50
+ able to change the decision.
51
+ - Why a minor: 0.9.9 made "never evaluated" a refusal in a patch release, which meant
52
+ every new seller was refused before signing even when intel itself said "warn,
53
+ within cap". This reverses that default, so it ships as a minor.
54
+ - **Why 0.11.0 and not 0.10.0:** see the 0.10.x entry below. Those version numbers are
55
+ taken on npm.
56
+
57
+ Unchanged in 0.11.0: attribution headers. Every preflight still sends
58
+ `X-TWZRD-Client` and `X-Twzrd-Caller` (the gate version); `X-TWZRD-Integration` and
59
+ `X-TWZRD-Run-Id` are sent only when `attribution` is configured.
60
+
61
+ ## 0.9.16 — 2026-09-28
62
+
63
+ - `createGuardedX402Fetch` recognises devnet USDC (Circle and faucet mints) on Solana
64
+ devnet instead of treating it as an unknown asset.
65
+ - An `@x402/core` spend-control refusal is rethrown with a hint explaining that core's
66
+ default controls ran before the TWZRD hook.
67
+ - A missing optional `@x402/fetch` peer throws an install hint instead of a bare import
68
+ error.
69
+
70
+ ## 0.9.15 — 2026-09-27
71
+
72
+ - Docs: the package README explains `@x402/core` ≥2.23 default spend controls
73
+ (recognised assets, $1 per payment), which run before any `beforePaymentCreation` hook.
74
+
75
+ ## 0.9.14 — 2026-09-27
76
+
77
+ - Tests run against `@x402/core` ^2.26 with its default spend controls on. No `src`
78
+ change.
79
+
80
+ ## 0.9.13 — 2026-09-26
81
+
82
+ - `safeFetch` counts a `pay()` that throws after the signer ran against the budget,
83
+ instead of releasing it.
84
+
85
+ Entries below were reconstructed on 2026-09-28 by diffing the published tarballs, so
86
+ each change is listed under the first version that actually contains it. Several of
87
+ them changed allow/refuse or paid behaviour in a patch release; 0.11.0's policy exists
88
+ because of that.
89
+
90
+ ## 0.9.12 — 2026-09-26 (paid behaviour change in a patch release)
91
+
92
+ - Buyer Path A defaults changed. With `x402Fetch` wired and the flags unset, a `warn`
93
+ now takes the $0.001 `/quick` hop at any price; before, a `warn` at $2.50 or more
94
+ bought the $0.05 receipt. `requireReceipt` default `onWarn` went from `true` to
95
+ `false`.
96
+
97
+ ## 0.9.11 — 2026-09-26 (behaviour change in a patch release)
98
+
99
+ - An `accepts[]` entry whose v1 and v2 price fields (`maxAmountRequired` / `amount`)
100
+ or recipient fields (`payTo` / `pay_to`) disagree is refused on every path
101
+ (`amount_field_conflict` / `payto_field_conflict`). New export
102
+ `resolveRequirementFields`.
103
+
104
+ ## 0.9.10 — 2026-09-20 (behaviour change in a patch release)
105
+
106
+ - The wash engine no longer hardcodes allow on an intel outage (timeout, 5xx, 429,
107
+ throw, bad JSON). New modules: `attempt-echo`, `cloudflare-x402`, `foreign-key`,
108
+ `paying-fetch`, `policy-fetch`, `wash-default`. See `COMPATIBILITY.md`.
109
+
110
+ ## 0.9.9 — 2026-09-15 (behaviour change in a patch release)
111
+
112
+ - Base mainnet (`eip155:8453`) is scored instead of abstaining.
113
+ - **A seller intel never evaluated is refused** (`twzrd_unevaluated_subject_*`). Every
114
+ new seller was refused before signing. 0.11.0 reverses the default.
115
+
116
+ ## 0.9.8 — 2026-09-13 (behaviour change in a patch release)
117
+
118
+ - A merchant-card outage obeys `failOpen` instead of silently allowing. Before this, a
119
+ card lookup that failed was treated as "no wash signal" and allowed the payment even
120
+ with `failOpen: false`.
121
+
122
+ ## 0.9.7 — 2026-09-12
123
+
124
+ - `evaluateIntent` re-checks the mandate ceiling and new-counterparty cap in the same
125
+ step that records the spend, so two concurrent intents can no longer both clear one
126
+ ceiling.
127
+ - `safeFetch` hands the payer only the offer the gate approved (`accepts: [selected]`),
128
+ not the whole `accepts[]`.
129
+
130
+ ## 0.9.4 – 0.9.6 — 2026-09-07 to 2026-09-12
131
+
132
+ - 0.9.4: `./unsafe` removed from the exports map and from the release contract. The
133
+ version line was moved from 0.10.1 back to 0.9.4 (see below).
134
+ - 0.9.5: portable payment decisions (`twzrd.payment_decision.v1`) with an offline
135
+ verifier.
136
+ - 0.9.6: reproducible build.
137
+
138
+ ## 0.10.0, 0.10.1 — 2026-09-02, 2026-09-07 (deprecated)
139
+
140
+ - Both exported `./unsafe`, a documented signature-bypass export, because the release
141
+ contract at the time required it for a "complete" release. Both also carried the
142
+ merchant-card fail-open defect fixed in 0.9.8, and neither build is reproducible from
143
+ source in git.
144
+ - Both are deprecated on npm. The line continued at 0.9.4. Semver ranks 0.10.1 above
145
+ every 0.9.x, so an install pinned to `^0.10` stays on the deprecated line: move to
146
+ `^0.11.0`.
package/QUICKSTART.md CHANGED
@@ -2,16 +2,17 @@
2
2
 
3
3
  Refuses payment to a wash-flagged merchant **before your wallet signs**. Free intel, no
4
4
  API key, no signup, no config — every `TWZRD_*` env var is an optional override. If intel
5
- is unreachable the gate never *invents* a wash flag (the wash check fails open); a failed
6
- preflight blocks the payment by default (`TWZRD_FAIL_OPEN=true` to allow).
5
+ is unreachable the gate never *invents* a wash flag. A failed preflight, or a merchant_card
6
+ outage on a scored path, blocks by default (`TWZRD_FAIL_OPEN=true` to allow). A reachable
7
+ card with no wash signal still proceeds.
7
8
 
8
- **Pin:** `twzrd-x402-gate@0.9.3` + stock PayAI client `x402-solana@3.0.0` (official
9
+ **Pin:** `twzrd-x402-gate@0.11.0` + stock PayAI client `x402-solana@3.0.0` (official
9
10
  `beforePayment` seat). `@x402/core` Path E remains supported; refuse script is fallback.
10
11
 
11
12
  ## 1. Stock PayAI client (default seat — copy-paste)
12
13
 
13
14
  ```bash
14
- npm install twzrd-x402-gate@0.9.3 x402-solana@3.0.0
15
+ npm install twzrd-x402-gate@0.11.0 x402-solana@3.0.0
15
16
  ```
16
17
 
17
18
  > **ESM-only.** The package ships `import` conditions only — a CommonJS
@@ -36,7 +37,7 @@ Then: `await client.fetch("https://merchant.example/paid");`
36
37
  ## 1b. Official `@x402/core` client (Path E)
37
38
 
38
39
  ```bash
39
- npm install twzrd-x402-gate@0.9.3 @x402/core @x402/fetch @x402/svm
40
+ npm install twzrd-x402-gate@0.11.0 @x402/core @x402/fetch @x402/svm
40
41
  ```
41
42
 
42
43
  ```typescript
@@ -49,17 +50,75 @@ installTwzrdAutoGate(client, { refuseWashFlagged: true });
49
50
  // then register schemes + wrapFetchWithPayment as usual
50
51
  ```
51
52
 
53
+ ## 1c. PayKit (`createPayKitClient`) — Foundation #303
54
+
55
+ PayKit callers pass TWZRD as `onBeforeX402PaymentCreation`. No TWZRD branding
56
+ inside pay-kit itself. The option is on `solana-foundation/pay-kit#303` (and the
57
+ `twzrd-sol` fork); until Foundation merges, use the fork or wait.
58
+
59
+ ```typescript
60
+ import { createPayKitClient } from "@solana/pay-kit";
61
+ import { createTwzrdPayKitBeforePaymentHook } from "twzrd-x402-gate";
62
+
63
+ const client = await createPayKitClient({
64
+ accept: ["x402"],
65
+ onBeforeX402PaymentCreation: createTwzrdPayKitBeforePaymentHook({
66
+ refuseWashFlagged: true,
67
+ }),
68
+ rpcUrl,
69
+ signer,
70
+ });
71
+ ```
72
+
73
+ Equivalent: `onBeforeX402PaymentCreation: installTwzrdAutoGate("pay-kit", { refuseWashFlagged: true })`.
74
+ The hook is the official `@x402/core` context shape (same evaluator as Path E).
75
+ `@solana/pay-kit` is optional — this package does not hard-depend on it.
76
+ `createTwzrdPayKitBeforePaymentHook` does not read `TWZRD_AUTO_GATE` or
77
+ `TWZRD_GATE_ENABLED`. `installTwzrdAutoGate("pay-kit", opts)` is the seat that
78
+ reads that kill switch per call and then calls the factory. You cannot
79
+ `installTwzrdAutoGate(client)` after `createPayKitClient` — PayKit only accepts
80
+ the hook at construction.
81
+
82
+ ## 1d. Cold-start a foreign diet (0 USDC)
83
+
84
+ ```bash
85
+ npx twzrd-cold-start
86
+ # policy.json: default-deny allowlist of foreign 402 hosts
87
+ # signer_invocation_count: 0, usdc_spent: 0
88
+ ```
89
+
90
+ Probes a pinned foreign GET 402 diet (not `*.twzrd`), scores each `payTo` with
91
+ `evaluate_x402_resource` (wash refuse), writes `policy.json`, hops once from
92
+ the resource join. Does not spend. `--spend` is refused. Seat AutoGate on the
93
+ payer with
94
+ `beforePayment: installTwzrdAutoGate("x402-solana", { refuseWashFlagged: true })`
95
+ using that policy as the host allowlist. Live proof (needs egress):
96
+ `npm run cold-start-live`.
97
+
52
98
  ## 2. Prove it blocked something (spends nothing)
53
99
 
100
+ Hello-world that closes from this package (needs a prior **repo-root** `npm ci`
101
+ and `npm run build`; do not `npm ci` in this directory):
102
+
54
103
  ```bash
55
- # Stock-client seat proof (beforePayment, signer_invocation_count=0)
56
- # needs x402-solana@3.0.0 installed - the harness fallback runs but does not
57
- # clear closure (its negative arm counts a would-be sign)
104
+ npm run gate-eval-refuse
105
+ # signer_invocation_count: 0, usdc_spent: 0
106
+ ```
107
+
108
+ Optional seat proofs (live intel; the clean-fixture leg can exit 2 when
109
+ `CLEAN_PAYTO` is wash-flagged — that is not the first demo):
110
+
111
+ ```bash
112
+ # Stock-client seat proof (beforePayment). Needs x402-solana@3.0.0.
113
+ # Harness fallback runs without it but does not clear closure.
58
114
  npm run x402-solana-before-payment-proof
59
115
  # writes block-proof-<run_id>.json — hook: beforePayment
60
116
 
61
117
  # @x402/core Path E proof (onBeforePaymentCreation)
62
118
  npm run autogate-block-proof
119
+
120
+ # PayKit seat (fake createPayKitClient — no unpublished @solana/pay-kit)
121
+ npm run pay-kit-before-payment
63
122
  ```
64
123
 
65
124
  That JSON is your receipt: a bad merchant intercepted with 0 USDC at risk.
@@ -90,9 +149,10 @@ createTwzrdBeforePaymentHook({
90
149
 
91
150
  ## 3b. Turn on Path A (buyer cash, not the rail)
92
151
 
93
- Refuse stays free until you wire a paying fetch. Then warn + material amount
94
- buys the $0.05 V6 (or $0.001 quick below $2.50). Facilitator settle hooks stay
95
- free.
152
+ Refuse stays free until you wire a paying fetch. Then a proceeding `warn`
153
+ settles the first paid hop: `GET /v1/intel/quick/{payTo}` at $0.001. Optional
154
+ V7 `$0.05` `/trust` stays on material allow or explicit `autoReceipt`.
155
+ Facilitator settle hooks stay free.
96
156
 
97
157
  ```typescript
98
158
  import { wrapFetchWithPayment } from "@x402/svm";
@@ -112,7 +172,7 @@ payWrap as `x402Fetch`.
112
172
 
113
173
  | Knob | Effect |
114
174
  |------|--------|
115
- | `TWZRD_AUTO_GATE=0` | Kill switch — gate fully off, payments proceed unguarded |
175
+ | `TWZRD_AUTO_GATE=0` | Kill switch for `installTwzrdAutoGate` only — that seat proceeds unguarded. `createTwzrdBeforePaymentHook` does not read `TWZRD_AUTO_GATE` or `TWZRD_GATE_ENABLED`, so a direct call still aborts a bad payment. `installTwzrdAutoGate` reads the switch per call on the x402-client / x402-solana / pay-kit / MPP seats before it calls the factory. The fetch (payWrap) seat resolves it once when the fetch is composed — rebuild the fetch to change it. |
116
176
  | `refuseWashFlagged: false` | Stop refusing wash-flagged merchants (default `true`) |
117
177
  | `gateOnCanSpend: true` | Opt-in hard cap: also block when `can_spend=false` (default `false`) |
118
178
 
@@ -120,7 +180,9 @@ Everything else (thresholds, wash caps, fail posture, settle guard): [README](./
120
180
 
121
181
  ## What this will NOT do
122
182
 
123
- - **No Base/EVM reputation.** Non-Solana networks get an explicit `unknown` (payment
124
- allowed, observed) unless you set `TWZRD_UNSUPPORTED_NETWORK_MODE=strict`.
183
+ - **Base mainnet is scored.** Solana mainnet and Base mainnet (`eip155:8453`)
184
+ run the scored preflight. Other EVM networks do not: they get an explicit
185
+ `unknown` unless you set `TWZRD_UNSUPPORTED_NETWORK_MODE=strict`. Observe is
186
+ not a wash bypass — `wash_flagged` still refuses before sign.
125
187
  - **No delivery guarantee.** It screens the merchant before you pay, nothing after.
126
188
  - **Not a wallet.** It never holds keys or signs — it only decides if your signer runs.