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.
- package/CHANGELOG.md +146 -0
- package/QUICKSTART.md +76 -14
- package/README.md +284 -50
- package/bin/twzrd-bounty-preflight.js +63 -0
- package/bin/twzrd-cold-start.js +69 -0
- package/bin/twzrd-evidence-bundle.js +10 -3
- package/bin/twzrd-payment-decision.js +25 -0
- package/dist/adoption-proof.d.ts +8 -0
- package/dist/adoption-proof.d.ts.map +1 -1
- package/dist/adoption-proof.js +13 -2
- package/dist/adoption-proof.js.map +1 -1
- package/dist/attempt-echo.d.ts +42 -0
- package/dist/attempt-echo.d.ts.map +1 -0
- package/dist/attempt-echo.js +170 -0
- package/dist/attempt-echo.js.map +1 -0
- package/dist/auto-gate.d.ts +43 -4
- package/dist/auto-gate.d.ts.map +1 -1
- package/dist/auto-gate.js +112 -22
- package/dist/auto-gate.js.map +1 -1
- package/dist/bounty-preflight-cli.d.ts +25 -0
- package/dist/bounty-preflight-cli.d.ts.map +1 -0
- package/dist/bounty-preflight-cli.js +157 -0
- package/dist/bounty-preflight-cli.js.map +1 -0
- package/dist/bounty-preflight.d.ts +140 -0
- package/dist/bounty-preflight.d.ts.map +1 -0
- package/dist/bounty-preflight.js +208 -0
- package/dist/bounty-preflight.js.map +1 -0
- package/dist/buyer-defaults.d.ts +4 -3
- package/dist/buyer-defaults.d.ts.map +1 -1
- package/dist/buyer-defaults.js +5 -4
- package/dist/buyer-defaults.js.map +1 -1
- package/dist/cloudflare-base.d.ts +49 -0
- package/dist/cloudflare-base.d.ts.map +1 -0
- package/dist/cloudflare-base.js +113 -0
- package/dist/cloudflare-base.js.map +1 -0
- package/dist/cloudflare-x402.d.ts +29 -0
- package/dist/cloudflare-x402.d.ts.map +1 -0
- package/dist/cloudflare-x402.js +31 -0
- package/dist/cloudflare-x402.js.map +1 -0
- package/dist/cold-start.d.ts +124 -0
- package/dist/cold-start.d.ts.map +1 -0
- package/dist/cold-start.js +515 -0
- package/dist/cold-start.js.map +1 -0
- package/dist/config.d.ts +4 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +18 -9
- package/dist/config.js.map +1 -1
- package/dist/consumer-adjacency.d.ts +79 -0
- package/dist/consumer-adjacency.d.ts.map +1 -0
- package/dist/consumer-adjacency.js +236 -0
- package/dist/consumer-adjacency.js.map +1 -0
- package/dist/decision-token.d.ts +1 -1
- package/dist/delivery-capture.d.ts +4 -3
- package/dist/delivery-capture.d.ts.map +1 -1
- package/dist/delivery-capture.js +4 -3
- package/dist/delivery-capture.js.map +1 -1
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +29 -7
- package/dist/doctor.js.map +1 -1
- package/dist/evaluate.d.ts +46 -15
- package/dist/evaluate.d.ts.map +1 -1
- package/dist/evaluate.js +140 -48
- package/dist/evaluate.js.map +1 -1
- package/dist/evidence-bundle.d.ts +50 -0
- package/dist/evidence-bundle.d.ts.map +1 -1
- package/dist/evidence-bundle.js +95 -14
- package/dist/evidence-bundle.js.map +1 -1
- package/dist/evidence-verify.d.ts +145 -0
- package/dist/evidence-verify.d.ts.map +1 -0
- package/dist/evidence-verify.js +784 -0
- package/dist/evidence-verify.js.map +1 -0
- package/dist/foreign-key.d.ts +23 -0
- package/dist/foreign-key.d.ts.map +1 -0
- package/dist/foreign-key.js +66 -0
- package/dist/foreign-key.js.map +1 -0
- package/dist/guarded-x402-fetch.d.ts +33 -0
- package/dist/guarded-x402-fetch.d.ts.map +1 -0
- package/dist/guarded-x402-fetch.js +201 -0
- package/dist/guarded-x402-fetch.js.map +1 -0
- package/dist/index.d.ts +19 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -6
- package/dist/index.js.map +1 -1
- package/dist/intelligence.js +2 -2
- package/dist/intelligence.js.map +1 -1
- package/dist/intent-adapters.d.ts.map +1 -1
- package/dist/intent-adapters.js +6 -2
- package/dist/intent-adapters.js.map +1 -1
- package/dist/log-inclusion.d.ts +135 -0
- package/dist/log-inclusion.d.ts.map +1 -0
- package/dist/log-inclusion.js +127 -0
- package/dist/log-inclusion.js.map +1 -0
- package/dist/mcp-hook.d.ts.map +1 -1
- package/dist/mcp-hook.js +5 -1
- package/dist/mcp-hook.js.map +1 -1
- package/dist/merchant-card.d.ts +51 -2
- package/dist/merchant-card.d.ts.map +1 -1
- package/dist/merchant-card.js +70 -13
- package/dist/merchant-card.js.map +1 -1
- package/dist/mpp-hook.d.ts.map +1 -1
- package/dist/mpp-hook.js +3 -1
- package/dist/mpp-hook.js.map +1 -1
- package/dist/network.d.ts +28 -7
- package/dist/network.d.ts.map +1 -1
- package/dist/network.js +45 -7
- package/dist/network.js.map +1 -1
- package/dist/paying-fetch.d.ts +17 -0
- package/dist/paying-fetch.d.ts.map +1 -0
- package/dist/paying-fetch.js +116 -0
- package/dist/paying-fetch.js.map +1 -0
- package/dist/payment-decision.d.ts +257 -0
- package/dist/payment-decision.d.ts.map +1 -0
- package/dist/payment-decision.js +690 -0
- package/dist/payment-decision.js.map +1 -0
- package/dist/payto.d.ts +38 -1
- package/dist/payto.d.ts.map +1 -1
- package/dist/payto.js +81 -3
- package/dist/payto.js.map +1 -1
- package/dist/policy-fetch.d.ts +18 -0
- package/dist/policy-fetch.d.ts.map +1 -0
- package/dist/policy-fetch.js +81 -0
- package/dist/policy-fetch.js.map +1 -0
- package/dist/policy-runtime.d.ts +3 -1
- package/dist/policy-runtime.d.ts.map +1 -1
- package/dist/policy-runtime.js +53 -21
- package/dist/policy-runtime.js.map +1 -1
- package/dist/policy.d.ts +20 -0
- package/dist/policy.d.ts.map +1 -1
- package/dist/policy.js +286 -57
- package/dist/policy.js.map +1 -1
- package/dist/quick.d.ts +5 -3
- package/dist/quick.d.ts.map +1 -1
- package/dist/quick.js.map +1 -1
- package/dist/record-leash-settle.d.ts +20 -0
- package/dist/record-leash-settle.d.ts.map +1 -0
- package/dist/record-leash-settle.js +25 -0
- package/dist/record-leash-settle.js.map +1 -0
- package/dist/resource-bind-tx.d.ts +4 -0
- package/dist/resource-bind-tx.d.ts.map +1 -1
- package/dist/resource-bind-tx.js +32 -10
- package/dist/resource-bind-tx.js.map +1 -1
- package/dist/resource-bind.d.ts +17 -3
- package/dist/resource-bind.d.ts.map +1 -1
- package/dist/resource-bind.js +93 -22
- package/dist/resource-bind.js.map +1 -1
- package/dist/safe-fetch.d.ts +2 -0
- package/dist/safe-fetch.d.ts.map +1 -1
- package/dist/safe-fetch.js +19 -1
- package/dist/safe-fetch.js.map +1 -1
- package/dist/seller-hook.d.ts +6 -2
- package/dist/seller-hook.d.ts.map +1 -1
- package/dist/seller-hook.js +44 -8
- package/dist/seller-hook.js.map +1 -1
- package/dist/spend-control.d.ts +12 -0
- package/dist/spend-control.d.ts.map +1 -1
- package/dist/spend-control.js +169 -64
- package/dist/spend-control.js.map +1 -1
- package/dist/spend-ledger-file.d.ts +3 -0
- package/dist/spend-ledger-file.d.ts.map +1 -1
- package/dist/spend-ledger-file.js +33 -1
- package/dist/spend-ledger-file.js.map +1 -1
- package/dist/ssrf.d.ts +15 -0
- package/dist/ssrf.d.ts.map +1 -0
- package/dist/ssrf.js +72 -0
- package/dist/ssrf.js.map +1 -0
- package/dist/trust-gate-reason.d.ts.map +1 -1
- package/dist/trust-gate-reason.js +1 -0
- package/dist/trust-gate-reason.js.map +1 -1
- package/dist/types.d.ts +74 -12
- package/dist/types.d.ts.map +1 -1
- package/dist/wash-default.d.ts +131 -0
- package/dist/wash-default.d.ts.map +1 -0
- package/dist/wash-default.js +329 -0
- package/dist/wash-default.js.map +1 -0
- package/dist/with-guard.d.ts +3 -3
- package/dist/with-guard.d.ts.map +1 -1
- package/dist/with-guard.js +13 -11
- package/dist/with-guard.js.map +1 -1
- package/dist/wrap-fetch.d.ts.map +1 -1
- package/dist/wrap-fetch.js +12 -9
- package/dist/wrap-fetch.js.map +1 -1
- package/dist/x402-client-hook.d.ts +54 -4
- package/dist/x402-client-hook.d.ts.map +1 -1
- package/dist/x402-client-hook.js +182 -49
- package/dist/x402-client-hook.js.map +1 -1
- 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
|
|
6
|
-
|
|
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
|
+
**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.
|
|
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.
|
|
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
|
-
|
|
56
|
-
#
|
|
57
|
-
|
|
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
|
|
94
|
-
|
|
95
|
-
|
|
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
|
|
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
|
-
- **
|
|
124
|
-
|
|
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.
|