x402trace 0.1.0 → 0.2.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 +25 -2
- package/README.md +22 -10
- package/dist/chain/abi.d.ts +35 -0
- package/dist/chain/abi.js +29 -0
- package/dist/chain/client.js +34 -1
- package/dist/chain/types.d.ts +24 -0
- package/dist/cli/explain-command.d.ts +36 -0
- package/dist/cli/explain-command.js +162 -0
- package/dist/cli/index.d.ts +6 -4
- package/dist/cli/index.js +39 -5
- package/dist/cli/validate-command.d.ts +56 -0
- package/dist/cli/validate-command.js +141 -0
- package/dist/diagnose/format.d.ts +23 -0
- package/dist/diagnose/format.js +68 -0
- package/dist/diagnose/index.d.ts +12 -0
- package/dist/diagnose/index.js +11 -0
- package/dist/diagnose/rules.d.ts +93 -0
- package/dist/diagnose/rules.js +276 -0
- package/dist/diagnose/types.d.ts +100 -0
- package/dist/diagnose/types.js +25 -0
- package/package.json +1 -1
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* X402-21 v0.2 diagnose engine — shared types.
|
|
3
|
+
*
|
|
4
|
+
* The diagnose engine is the substrate behind two subcommands per
|
|
5
|
+
* [ADR-002](../../DECISIONS.md#adr-002-v02-feature-pick--validate-primary--explain-paired):
|
|
6
|
+
*
|
|
7
|
+
* - `x402trace validate <wallet> <service>` — pre-flight check. The
|
|
8
|
+
* wallet hasn't signed anything yet; live chain state is queried
|
|
9
|
+
* and a *simulated* authorization is checked against the live 402
|
|
10
|
+
* challenge.
|
|
11
|
+
* - `x402trace explain <jsonl-log>` — offline diagnosis. The
|
|
12
|
+
* authorization is captured (the user already signed); we explain
|
|
13
|
+
* why it failed by running the same rules against the captured
|
|
14
|
+
* state.
|
|
15
|
+
*
|
|
16
|
+
* Same engine, different input populations — `validate` runs with full
|
|
17
|
+
* `walletState` and a synthetic `payment`; `explain` runs with a real
|
|
18
|
+
* `payment` and potentially no `walletState` (the log doesn't capture
|
|
19
|
+
* balance/allowance at the time the request was made).
|
|
20
|
+
*
|
|
21
|
+
* Rules MUST be pure functions of the context — no I/O, no Date.now().
|
|
22
|
+
* The current time enters via `ctx.now`. This lets `explain` reproduce
|
|
23
|
+
* a diagnosis deterministically from a JSONL log.
|
|
24
|
+
*/
|
|
25
|
+
import type { PaymentPayload, PaymentRequirements } from "../decoder/types.js";
|
|
26
|
+
/**
|
|
27
|
+
* Snapshot of the on-chain state needed to diagnose a payment. All
|
|
28
|
+
* fields are optional: `validate` populates them from live RPC,
|
|
29
|
+
* `explain` runs without them (since v0.1 logs don't capture chain
|
|
30
|
+
* state at the moment of failure).
|
|
31
|
+
*/
|
|
32
|
+
export interface WalletState {
|
|
33
|
+
/** Wallet's current USDC balance, in raw token units (no decimals applied). */
|
|
34
|
+
readonly usdcBalance?: bigint;
|
|
35
|
+
/**
|
|
36
|
+
* Whether the authorization's nonce has already been consumed. EIP-3009
|
|
37
|
+
* nonces are unique per `(authorizer, contract)`; a "true" here means
|
|
38
|
+
* the wallet has already used this nonce on the USDC contract.
|
|
39
|
+
*/
|
|
40
|
+
readonly nonceConsumed?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Loose classification of the wallet behind the address. v0.2 supports
|
|
43
|
+
* `eoa` and `smart-wallet`; `unknown` means we couldn't decide (treat
|
|
44
|
+
* as a warning rather than a failure).
|
|
45
|
+
*/
|
|
46
|
+
readonly walletKind?: "eoa" | "smart-wallet" | "unknown";
|
|
47
|
+
}
|
|
48
|
+
export interface DiagnosticContext {
|
|
49
|
+
readonly requirements: PaymentRequirements;
|
|
50
|
+
/**
|
|
51
|
+
* Either a captured `PaymentPayload` (from `explain`) or a simulated
|
|
52
|
+
* one (from `validate`, constructed from the wallet address +
|
|
53
|
+
* requirements). When undefined, payment-side rules skip.
|
|
54
|
+
*/
|
|
55
|
+
readonly payment?: PaymentPayload;
|
|
56
|
+
readonly walletState?: WalletState;
|
|
57
|
+
/**
|
|
58
|
+
* The instant the diagnosis runs. Used for `validBefore` window
|
|
59
|
+
* checks. Injected explicitly so the rule engine stays pure.
|
|
60
|
+
*/
|
|
61
|
+
readonly now: Date;
|
|
62
|
+
}
|
|
63
|
+
export type DiagnosticStatus = "pass" | "fail" | "skip";
|
|
64
|
+
export interface DiagnosticResult {
|
|
65
|
+
/** Stable identifier; downstream tools can grep / filter on this. */
|
|
66
|
+
readonly rule: string;
|
|
67
|
+
readonly status: DiagnosticStatus;
|
|
68
|
+
/**
|
|
69
|
+
* One-line human-readable description. On `pass` it states what was
|
|
70
|
+
* verified; on `fail` it states what was wrong; on `skip` it says
|
|
71
|
+
* what's missing from the context to run this check.
|
|
72
|
+
*/
|
|
73
|
+
readonly message: string;
|
|
74
|
+
/** Plain-English actionable fix. Only present when `status === "fail"`. */
|
|
75
|
+
readonly fix?: string;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Top-level conclusion. Distinct from the per-rule statuses because a
|
|
79
|
+
* diagnosis with only `skip`s is meaningfully different from one with
|
|
80
|
+
* all `pass`es.
|
|
81
|
+
*/
|
|
82
|
+
export type OverallStatus =
|
|
83
|
+
/** Every applicable rule passed — the payment would (or did) succeed. */
|
|
84
|
+
"would-succeed"
|
|
85
|
+
/** At least one rule failed. */
|
|
86
|
+
| "would-fail"
|
|
87
|
+
/** Some rules ran (no fails) but key checks were skipped — we can't be sure. */
|
|
88
|
+
| "uncertain";
|
|
89
|
+
export interface DiagnosticReport {
|
|
90
|
+
readonly results: readonly DiagnosticResult[];
|
|
91
|
+
readonly overallStatus: OverallStatus;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* A rule is a pure function from context to result. The `name` is the
|
|
95
|
+
* stable identifier surfaced in `DiagnosticResult.rule`.
|
|
96
|
+
*/
|
|
97
|
+
export interface DiagnosticRule {
|
|
98
|
+
readonly name: string;
|
|
99
|
+
readonly run: (ctx: DiagnosticContext) => DiagnosticResult;
|
|
100
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* X402-21 v0.2 diagnose engine — shared types.
|
|
3
|
+
*
|
|
4
|
+
* The diagnose engine is the substrate behind two subcommands per
|
|
5
|
+
* [ADR-002](../../DECISIONS.md#adr-002-v02-feature-pick--validate-primary--explain-paired):
|
|
6
|
+
*
|
|
7
|
+
* - `x402trace validate <wallet> <service>` — pre-flight check. The
|
|
8
|
+
* wallet hasn't signed anything yet; live chain state is queried
|
|
9
|
+
* and a *simulated* authorization is checked against the live 402
|
|
10
|
+
* challenge.
|
|
11
|
+
* - `x402trace explain <jsonl-log>` — offline diagnosis. The
|
|
12
|
+
* authorization is captured (the user already signed); we explain
|
|
13
|
+
* why it failed by running the same rules against the captured
|
|
14
|
+
* state.
|
|
15
|
+
*
|
|
16
|
+
* Same engine, different input populations — `validate` runs with full
|
|
17
|
+
* `walletState` and a synthetic `payment`; `explain` runs with a real
|
|
18
|
+
* `payment` and potentially no `walletState` (the log doesn't capture
|
|
19
|
+
* balance/allowance at the time the request was made).
|
|
20
|
+
*
|
|
21
|
+
* Rules MUST be pure functions of the context — no I/O, no Date.now().
|
|
22
|
+
* The current time enters via `ctx.now`. This lets `explain` reproduce
|
|
23
|
+
* a diagnosis deterministically from a JSONL log.
|
|
24
|
+
*/
|
|
25
|
+
export {};
|