@ashlar-blue/x402-trust 0.3.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/LICENSE +21 -0
- package/README.md +198 -0
- package/dist/attested-directory.d.ts +78 -0
- package/dist/attested-directory.d.ts.map +1 -0
- package/dist/attested-directory.js +163 -0
- package/dist/attested-directory.js.map +1 -0
- package/dist/badges.d.ts +131 -0
- package/dist/badges.d.ts.map +1 -0
- package/dist/badges.js +213 -0
- package/dist/badges.js.map +1 -0
- package/dist/catalog-mcp.d.ts +145 -0
- package/dist/catalog-mcp.d.ts.map +1 -0
- package/dist/catalog-mcp.js +409 -0
- package/dist/catalog-mcp.js.map +1 -0
- package/dist/census-reconcile.d.ts +69 -0
- package/dist/census-reconcile.d.ts.map +1 -0
- package/dist/census-reconcile.js +162 -0
- package/dist/census-reconcile.js.map +1 -0
- package/dist/directory-classify.d.ts +47 -0
- package/dist/directory-classify.d.ts.map +1 -0
- package/dist/directory-classify.js +54 -0
- package/dist/directory-classify.js.map +1 -0
- package/dist/discovery.d.ts +304 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +926 -0
- package/dist/discovery.js.map +1 -0
- package/dist/evidence-ref.d.ts +96 -0
- package/dist/evidence-ref.d.ts.map +1 -0
- package/dist/evidence-ref.js +179 -0
- package/dist/evidence-ref.js.map +1 -0
- package/dist/facilitator-config.d.ts +83 -0
- package/dist/facilitator-config.d.ts.map +1 -0
- package/dist/facilitator-config.js +94 -0
- package/dist/facilitator-config.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest-sig.d.ts +131 -0
- package/dist/manifest-sig.d.ts.map +1 -0
- package/dist/manifest-sig.js +262 -0
- package/dist/manifest-sig.js.map +1 -0
- package/dist/merkle-transcript.d.ts +34 -0
- package/dist/merkle-transcript.d.ts.map +1 -0
- package/dist/merkle-transcript.js +162 -0
- package/dist/merkle-transcript.js.map +1 -0
- package/dist/open-catalog.d.ts +111 -0
- package/dist/open-catalog.d.ts.map +1 -0
- package/dist/open-catalog.js +307 -0
- package/dist/open-catalog.js.map +1 -0
- package/dist/reconcile.d.ts +150 -0
- package/dist/reconcile.d.ts.map +1 -0
- package/dist/reconcile.js +136 -0
- package/dist/reconcile.js.map +1 -0
- package/dist/trust-sdk.d.ts +127 -0
- package/dist/trust-sdk.d.ts.map +1 -0
- package/dist/trust-sdk.js +147 -0
- package/dist/trust-sdk.js.map +1 -0
- package/dist/types.d.ts +213 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +68 -0
- package/dist/types.js.map +1 -0
- package/package.json +52 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
// GENERATED from src/x402/reconcile.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
|
+
const ADDR_RE = /^0x[0-9a-fA-F]{40}$/;
|
|
5
|
+
const NONCE_RE = /^0x[0-9a-fA-F]{64}$/;
|
|
6
|
+
export async function reconcileAuthorization(q, reader, scope, now) {
|
|
7
|
+
// `now` is defined by this port to return UNIX SECONDS, matching
|
|
8
|
+
// validBefore's units — the facilitator passes Math.floor(Date.now()/1000)
|
|
9
|
+
// and the tests pass a seconds constant. Do not re-scale it here.
|
|
10
|
+
const clockUnixSeconds = now();
|
|
11
|
+
// Read the height FIRST, so even a verdict that fails early carries the
|
|
12
|
+
// state it failed at. A height fetched after the decision would describe a
|
|
13
|
+
// different chain than the one the decision was made against.
|
|
14
|
+
let blockHeight = null;
|
|
15
|
+
if (reader.blockHeight) {
|
|
16
|
+
try {
|
|
17
|
+
blockHeight = await reader.blockHeight();
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
blockHeight = null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/** Build the observation, marking whether the clock decided this verdict. */
|
|
24
|
+
const obs = (clockWasLoadBearing) => ({
|
|
25
|
+
blockHeight,
|
|
26
|
+
clockUnixSeconds,
|
|
27
|
+
clockWasLoadBearing,
|
|
28
|
+
replayable: blockHeight !== null,
|
|
29
|
+
});
|
|
30
|
+
const at = blockHeight === null
|
|
31
|
+
? 'at an unknown height (this reader does not report one, so the verdict is not replayable)'
|
|
32
|
+
: `at block ${blockHeight}`;
|
|
33
|
+
const rederive = `Read authorizationState(payer, nonce) on the asset contract via any ${scope.network} RPC (${scope.rpc}) ${at}; `
|
|
34
|
+
+ 'if consumed, filter AuthorizationUsed(payer, nonce) logs for the settlement tx and decode its Transfer events.';
|
|
35
|
+
if (!ADDR_RE.test(q.asset ?? '') || !ADDR_RE.test(q.payer ?? '') || !NONCE_RE.test(q.nonce ?? '')) {
|
|
36
|
+
return {
|
|
37
|
+
outcome: 'indeterminate', cause: 'invalid-query',
|
|
38
|
+
reason: 'asset and payer must be 0x addresses and nonce a 32-byte 0x-hex value',
|
|
39
|
+
observation: obs(false), rederive,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
const symbol = scope.assets[q.asset.toLowerCase()];
|
|
43
|
+
if (!symbol) {
|
|
44
|
+
return {
|
|
45
|
+
outcome: 'indeterminate', cause: 'out-of-scope-asset',
|
|
46
|
+
reason: `asset ${q.asset} is not an EIP-3009 asset this rail settles — no verdict, not a refusal`,
|
|
47
|
+
observation: obs(false), rederive,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
let consumed;
|
|
51
|
+
try {
|
|
52
|
+
consumed = await reader.authorizationConsumed(q.asset, q.payer, q.nonce);
|
|
53
|
+
}
|
|
54
|
+
catch (e) {
|
|
55
|
+
return {
|
|
56
|
+
outcome: 'indeterminate', cause: 'rail-unreachable',
|
|
57
|
+
reason: `rail unreachable (${e.message}) — unknown is not a verdict; retry`,
|
|
58
|
+
observation: obs(false), rederive,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
if (consumed) {
|
|
62
|
+
// CONSUMED IS NOT SETTLED. It is used-or-cancelled, and a cancelled
|
|
63
|
+
// authorization moved no tokens. Resolve which by event before
|
|
64
|
+
// returning any verdict — the previous version returned `settled`
|
|
65
|
+
// here and told the reader to widen their log range, which is the
|
|
66
|
+
// one case where widening never helps and the advice is reassuring
|
|
67
|
+
// about a payment that never happened.
|
|
68
|
+
let record = null;
|
|
69
|
+
try {
|
|
70
|
+
record = await reader.findConsumption(q.asset, q.payer, q.nonce);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
// Enumeration failed. We know the nonce is spent but not how,
|
|
74
|
+
// and the two possibilities are OPPOSITE verdicts — so this is
|
|
75
|
+
// indeterminate, never a coin-flip toward settled.
|
|
76
|
+
return {
|
|
77
|
+
outcome: 'indeterminate', cause: 'consumption-kind-unknown',
|
|
78
|
+
reason: 'nonce is consumed but the event read failed — consumed means used OR cancelled, and those are opposite verdicts; retry',
|
|
79
|
+
observation: obs(false), rederive,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
if (record === null) {
|
|
83
|
+
return {
|
|
84
|
+
outcome: 'indeterminate', cause: 'consumption-kind-unknown',
|
|
85
|
+
reason: 'nonce is consumed but neither AuthorizationUsed nor AuthorizationCanceled was locatable in this reader\'s log range — re-derive with a wider range',
|
|
86
|
+
observation: obs(false), rederive,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
if (record.kind === 'cancelled') {
|
|
90
|
+
return {
|
|
91
|
+
outcome: 'refused-not-charged', cause: 'authorization-cancelled',
|
|
92
|
+
reason: `authorization was CANCELLED (tx ${record.tx}, block ${record.blockNumber}) — the nonce is consumed but no tokens moved; the payer was not charged`,
|
|
93
|
+
consumption: record,
|
|
94
|
+
observation: obs(false), rederive,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
outcome: 'settled', cause: 'nonce-used',
|
|
99
|
+
reason: `authorization used on-chain; settlement tx ${record.tx} (block ${record.blockNumber}) carried ${record.transfers.length} ${symbol} transfer(s)`,
|
|
100
|
+
consumption: record,
|
|
101
|
+
observation: obs(false), rederive,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
if (typeof q.validBefore === 'number') {
|
|
105
|
+
// THE CLOCK IS LOAD-BEARING HERE AND NOWHERE ELSE. Everything above is
|
|
106
|
+
// decided by chain state; this one comparison is decided by what time
|
|
107
|
+
// we think it is. The observation publishes the reading so a party who
|
|
108
|
+
// disagrees can recompute the comparison instead of disputing a verdict.
|
|
109
|
+
if (clockUnixSeconds > q.validBefore) {
|
|
110
|
+
return {
|
|
111
|
+
outcome: 'refused-not-charged', cause: 'window-closed-unconsumed',
|
|
112
|
+
// HONEST ABOUT WHAT THIS DOES NOT SAY (Circadian-agent, #3226):
|
|
113
|
+
// the rail cannot distinguish "a settle was attempted and
|
|
114
|
+
// failed" from "nobody ever tried". x402#3231 is a live
|
|
115
|
+
// instance of the first — a valid authorization the reference
|
|
116
|
+
// facilitator could not settle because of a stale nonce on its
|
|
117
|
+
// OWN relayer wallet. The OUTCOME is right either way (no
|
|
118
|
+
// tokens moved, the payer was not charged); the reason must not
|
|
119
|
+
// imply the payer withdrew.
|
|
120
|
+
reason: `authorization unconsumed and its window closed at ${q.validBefore} (clock ${clockUnixSeconds}) — it can never settle, so the payer was not charged. This does NOT say whether a settle was attempted and failed or never attempted; the rail cannot distinguish those.`,
|
|
121
|
+
observation: obs(true), rederive,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
outcome: 'indeterminate', cause: 'window-open-unconsumed',
|
|
126
|
+
reason: `authorization unconsumed but valid until ${q.validBefore} (clock ${clockUnixSeconds}) — it could still settle; re-query after expiry for a determinate verdict`,
|
|
127
|
+
observation: obs(true), rederive,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
outcome: 'indeterminate', cause: 'window-unknown-unconsumed',
|
|
132
|
+
reason: 'authorization unconsumed and no validBefore supplied — cannot rule out a future settle; supply validBefore for a determinate refused-not-charged',
|
|
133
|
+
observation: obs(false), rederive,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=reconcile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reconcile.js","sourceRoot":"","sources":["../src/reconcile.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @flareclaw/x402-trust — the trust layer for agents that spend money.
|
|
3
|
+
*
|
|
4
|
+
* An agent about to pay another agent has two questions, and an agent that just
|
|
5
|
+
* did work has one obligation. This module answers all three in a handful of
|
|
6
|
+
* lines, with zero dependencies and — for the verification half — zero network
|
|
7
|
+
* and zero trust in us:
|
|
8
|
+
*
|
|
9
|
+
* BEFORE YOU PAY checkService(domain) — discover a service, verify what can
|
|
10
|
+
* be verified, and get a plain safeToPay decision with the
|
|
11
|
+
* reasons behind it. Composes the hardened resolver
|
|
12
|
+
* (same-origin enforcement, SSRF/DoS guards, HTTPS-only,
|
|
13
|
+
* live cross-check) so a caller need not re-implement the
|
|
14
|
+
* adversarial edge cases.
|
|
15
|
+
*
|
|
16
|
+
* WHAT YOU'RE HANDED verifyReceipt / verifyDirectoryEntry / verifyReconcileRow
|
|
17
|
+
* — check ONE row of a Merkle-committed receipt, census, or
|
|
18
|
+
* reconciliation against its signed root, holding nothing
|
|
19
|
+
* else. Pure math (RFC 6962). It does not call us, and it
|
|
20
|
+
* does not trust us: if the proof verifies, the claim is
|
|
21
|
+
* true whoever produced it.
|
|
22
|
+
*
|
|
23
|
+
* WHAT YOU PRODUCE new Transcript() — accumulate {id, input, output} entries
|
|
24
|
+
* and emit a root plus per-entry inclusion proofs, so the
|
|
25
|
+
* work YOUR agent did is provable to a third party without
|
|
26
|
+
* disclosing the rest of the session.
|
|
27
|
+
*
|
|
28
|
+
* The verification functions are the point of the whole library: an enterprise
|
|
29
|
+
* does not have to trust FlareClaw to use FlareClaw's proofs. That is the only
|
|
30
|
+
* kind of trust layer worth adopting.
|
|
31
|
+
*/
|
|
32
|
+
import { resolveX402, type ResolveResult } from './discovery.js';
|
|
33
|
+
import { type TranscriptEntry } from './merkle-transcript.js';
|
|
34
|
+
import { type DirectoryEntry } from './attested-directory.js';
|
|
35
|
+
import { type ReconcileRow } from './census-reconcile.js';
|
|
36
|
+
export interface ServiceTrust {
|
|
37
|
+
domain: string;
|
|
38
|
+
/** A discovery record or manifest resolved at all. */
|
|
39
|
+
reachable: boolean;
|
|
40
|
+
/** It resolved to a valid x402 discovery manifest. */
|
|
41
|
+
discoverable: boolean;
|
|
42
|
+
/** How the manifest was found. */
|
|
43
|
+
via?: 'dns-txt' | 'well-known';
|
|
44
|
+
/** The manifest carries a TEE/attestation claim. */
|
|
45
|
+
attested: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* The attestation claim is INDEPENDENTLY CHECKABLE — a same-origin HTTPS
|
|
48
|
+
* verifier the caller could dereference. False for an absent, `none`, or
|
|
49
|
+
* off-origin verifier: a claim, not a verified claim.
|
|
50
|
+
*/
|
|
51
|
+
attestationCheckable: boolean;
|
|
52
|
+
/** Live /supported cross-check outcome (ok/skipped/unreachable/malformed/refused). */
|
|
53
|
+
liveCheck?: ResolveResult['liveCheck'];
|
|
54
|
+
/** True when the facilitator's live kinds match its manifest kinds. */
|
|
55
|
+
liveConsistent: boolean | null;
|
|
56
|
+
/** Manifest entries the resolver DROPPED as off-domain — a spoofing signal, surfaced not hidden. */
|
|
57
|
+
warnings: string[];
|
|
58
|
+
/** The composed decision under the chosen policy. */
|
|
59
|
+
safeToPay: boolean;
|
|
60
|
+
/** Why, in plain words — safe to log, safe to show a human. */
|
|
61
|
+
reasons: string[];
|
|
62
|
+
/** The raw resolver result, for callers that want the detail. */
|
|
63
|
+
resolution?: ResolveResult;
|
|
64
|
+
}
|
|
65
|
+
export interface CheckServiceOptions {
|
|
66
|
+
/** Require an independently-checkable attestation for safeToPay (default false). */
|
|
67
|
+
requireAttestation?: boolean;
|
|
68
|
+
/** Require the live /supported cross-check to have PASSED (default false — 'skipped' is allowed). */
|
|
69
|
+
requireLiveConsistent?: boolean;
|
|
70
|
+
/** Pass-throughs for tests / custom transports. */
|
|
71
|
+
resolveTxt?: Parameters<typeof resolveX402>[1] extends infer O ? O extends {
|
|
72
|
+
resolveTxt?: infer T;
|
|
73
|
+
} ? T : never : never;
|
|
74
|
+
fetchImpl?: typeof fetch;
|
|
75
|
+
lookupImpl?: Parameters<typeof resolveX402>[1] extends infer O ? O extends {
|
|
76
|
+
lookupImpl?: infer L;
|
|
77
|
+
} ? L : never : never;
|
|
78
|
+
noCache?: boolean;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Resolve a domain and decide whether an agent should pay it. The default
|
|
82
|
+
* policy is deliberately conservative but not paranoid: a service is safe to
|
|
83
|
+
* pay when it is genuinely discoverable, nothing was dropped as a spoofing
|
|
84
|
+
* attempt, and the live cross-check did not REFUSE (a dead live signal is a
|
|
85
|
+
* warning, not a veto, unless you ask for one). Tighten with requireAttestation
|
|
86
|
+
* / requireLiveConsistent.
|
|
87
|
+
*/
|
|
88
|
+
export declare function checkService(domain: string, opts?: CheckServiceOptions): Promise<ServiceTrust>;
|
|
89
|
+
/** One retail receipt proof: an entry, its position, the tree size, the path, the signed root. */
|
|
90
|
+
export interface ReceiptProof {
|
|
91
|
+
entry: TranscriptEntry;
|
|
92
|
+
index: number;
|
|
93
|
+
size: number;
|
|
94
|
+
proof: string[];
|
|
95
|
+
root: string;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Verify ONE draw/work receipt against its signed root, holding nothing else.
|
|
99
|
+
* Pure RFC 6962. Returns true iff the entry was genuinely in the committed
|
|
100
|
+
* transcript at that position — no network, no trust in the producer.
|
|
101
|
+
*/
|
|
102
|
+
export declare function verifyReceipt(p: ReceiptProof): boolean;
|
|
103
|
+
/** Verify one directory-census entry against a census outputRoot. */
|
|
104
|
+
export declare function verifyDirectoryEntry(entry: DirectoryEntry, index: number, size: number, proof: string[], outputRoot: string): boolean;
|
|
105
|
+
/** Verify one reconciliation row against a reconciliation rowsRoot. */
|
|
106
|
+
export declare function verifyReconcileRow(row: ReconcileRow, index: number, size: number, proof: string[], rowsRoot: string): boolean;
|
|
107
|
+
/**
|
|
108
|
+
* Build a verifiable transcript of the work your agent did. Add {id, input,
|
|
109
|
+
* output} entries; emit a root you sign/anchor and per-entry inclusion proofs a
|
|
110
|
+
* counterparty can check with verifyReceipt — WITHOUT seeing the rest.
|
|
111
|
+
*
|
|
112
|
+
* `id` is committed (it distinguishes two otherwise-identical entries — the
|
|
113
|
+
* payment-intent identity), so the transcript cannot be made to undercount two
|
|
114
|
+
* distinct pieces of work.
|
|
115
|
+
*/
|
|
116
|
+
export declare class Transcript {
|
|
117
|
+
private entries;
|
|
118
|
+
/** Append one unit of work: an identifier, its input, and its output. */
|
|
119
|
+
add(id: string, input: string, output: string): this;
|
|
120
|
+
/** Number of entries so far. */
|
|
121
|
+
get size(): number;
|
|
122
|
+
/** The Merkle root to sign or anchor — the single value that commits to all entries. */
|
|
123
|
+
root(): string;
|
|
124
|
+
/** A retail inclusion proof for entry `index`, ready to hand to a verifier. */
|
|
125
|
+
prove(index: number): ReceiptProof;
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=trust-sdk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trust-sdk.d.ts","sourceRoot":"","sources":["../src/trust-sdk.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
// GENERATED from src/x402/trust-sdk.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
|
+
* @flareclaw/x402-trust — the trust layer for agents that spend money.
|
|
6
|
+
*
|
|
7
|
+
* An agent about to pay another agent has two questions, and an agent that just
|
|
8
|
+
* did work has one obligation. This module answers all three in a handful of
|
|
9
|
+
* lines, with zero dependencies and — for the verification half — zero network
|
|
10
|
+
* and zero trust in us:
|
|
11
|
+
*
|
|
12
|
+
* BEFORE YOU PAY checkService(domain) — discover a service, verify what can
|
|
13
|
+
* be verified, and get a plain safeToPay decision with the
|
|
14
|
+
* reasons behind it. Composes the hardened resolver
|
|
15
|
+
* (same-origin enforcement, SSRF/DoS guards, HTTPS-only,
|
|
16
|
+
* live cross-check) so a caller need not re-implement the
|
|
17
|
+
* adversarial edge cases.
|
|
18
|
+
*
|
|
19
|
+
* WHAT YOU'RE HANDED verifyReceipt / verifyDirectoryEntry / verifyReconcileRow
|
|
20
|
+
* — check ONE row of a Merkle-committed receipt, census, or
|
|
21
|
+
* reconciliation against its signed root, holding nothing
|
|
22
|
+
* else. Pure math (RFC 6962). It does not call us, and it
|
|
23
|
+
* does not trust us: if the proof verifies, the claim is
|
|
24
|
+
* true whoever produced it.
|
|
25
|
+
*
|
|
26
|
+
* WHAT YOU PRODUCE new Transcript() — accumulate {id, input, output} entries
|
|
27
|
+
* and emit a root plus per-entry inclusion proofs, so the
|
|
28
|
+
* work YOUR agent did is provable to a third party without
|
|
29
|
+
* disclosing the rest of the session.
|
|
30
|
+
*
|
|
31
|
+
* The verification functions are the point of the whole library: an enterprise
|
|
32
|
+
* does not have to trust FlareClaw to use FlareClaw's proofs. That is the only
|
|
33
|
+
* kind of trust layer worth adopting.
|
|
34
|
+
*/
|
|
35
|
+
import { resolveX402, X402NegativeCacheError, } from './discovery.js';
|
|
36
|
+
import { transcriptRoot, inclusionProof, verifyInclusion, } from './merkle-transcript.js';
|
|
37
|
+
import { verifyEntry } from './attested-directory.js';
|
|
38
|
+
import { verifyRow } from './census-reconcile.js';
|
|
39
|
+
/**
|
|
40
|
+
* Resolve a domain and decide whether an agent should pay it. The default
|
|
41
|
+
* policy is deliberately conservative but not paranoid: a service is safe to
|
|
42
|
+
* pay when it is genuinely discoverable, nothing was dropped as a spoofing
|
|
43
|
+
* attempt, and the live cross-check did not REFUSE (a dead live signal is a
|
|
44
|
+
* warning, not a veto, unless you ask for one). Tighten with requireAttestation
|
|
45
|
+
* / requireLiveConsistent.
|
|
46
|
+
*/
|
|
47
|
+
export async function checkService(domain, opts = {}) {
|
|
48
|
+
const reasons = [];
|
|
49
|
+
let resolution;
|
|
50
|
+
try {
|
|
51
|
+
resolution = await resolveX402(domain, {
|
|
52
|
+
...(opts.resolveTxt ? { resolveTxt: opts.resolveTxt } : {}),
|
|
53
|
+
...(opts.fetchImpl ? { fetchImpl: opts.fetchImpl } : {}),
|
|
54
|
+
...(opts.lookupImpl ? { lookupImpl: opts.lookupImpl } : {}),
|
|
55
|
+
...(opts.noCache ? { noCache: true } : {}),
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
catch (e) {
|
|
59
|
+
// A resolver refusal (spoofing/malformed/SSRF/DoS) is a firm NO, and its
|
|
60
|
+
// reason is worth surfacing rather than collapsing to "unreachable".
|
|
61
|
+
const cached = e instanceof X402NegativeCacheError;
|
|
62
|
+
return {
|
|
63
|
+
domain, reachable: false, discoverable: false, attested: false,
|
|
64
|
+
attestationCheckable: false, liveConsistent: null, warnings: [],
|
|
65
|
+
safeToPay: false,
|
|
66
|
+
reasons: [`resolution ${cached ? 'refused (cached)' : 'failed'}: ${e.message}`],
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
const attested = !!resolution.manifest.attestation
|
|
70
|
+
&& resolution.manifest.attestation.type !== 'none';
|
|
71
|
+
const attestationCheckable = resolution.attestationUsable === true;
|
|
72
|
+
const liveConsistent = resolution.kindsMatchLive ?? null;
|
|
73
|
+
const warnings = [
|
|
74
|
+
...(resolution.droppedResources ?? []).map((r) => `dropped off-domain resource: ${r}`),
|
|
75
|
+
...(resolution.droppedPeers ?? []).map((p) => `dropped peer hint: ${p}`),
|
|
76
|
+
];
|
|
77
|
+
reasons.push(`discoverable via ${resolution.via}`);
|
|
78
|
+
if (attested)
|
|
79
|
+
reasons.push(attestationCheckable ? 'attestation claim is same-origin checkable' : 'attestation claim present but NOT independently checkable');
|
|
80
|
+
if (resolution.liveCheck)
|
|
81
|
+
reasons.push(`live cross-check: ${resolution.liveCheck}`);
|
|
82
|
+
if (liveConsistent === false)
|
|
83
|
+
reasons.push('WARNING: live /supported disagrees with the manifest');
|
|
84
|
+
for (const w of warnings)
|
|
85
|
+
reasons.push(`WARNING: ${w}`);
|
|
86
|
+
let safeToPay = resolution.liveCheck !== 'refused' && warnings.length === 0;
|
|
87
|
+
if (opts.requireAttestation && !attestationCheckable) {
|
|
88
|
+
safeToPay = false;
|
|
89
|
+
reasons.push('policy: attestation required, none checkable');
|
|
90
|
+
}
|
|
91
|
+
if (opts.requireLiveConsistent && liveConsistent !== true) {
|
|
92
|
+
safeToPay = false;
|
|
93
|
+
reasons.push('policy: live consistency required, not confirmed');
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
domain, reachable: true, discoverable: true, via: resolution.via,
|
|
97
|
+
attested, attestationCheckable,
|
|
98
|
+
...(resolution.liveCheck ? { liveCheck: resolution.liveCheck } : {}),
|
|
99
|
+
liveConsistent, warnings, safeToPay, reasons, resolution,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Verify ONE draw/work receipt against its signed root, holding nothing else.
|
|
104
|
+
* Pure RFC 6962. Returns true iff the entry was genuinely in the committed
|
|
105
|
+
* transcript at that position — no network, no trust in the producer.
|
|
106
|
+
*/
|
|
107
|
+
export function verifyReceipt(p) {
|
|
108
|
+
return verifyInclusion(p.entry, p.index, p.size, p.proof, p.root);
|
|
109
|
+
}
|
|
110
|
+
/** Verify one directory-census entry against a census outputRoot. */
|
|
111
|
+
export function verifyDirectoryEntry(entry, index, size, proof, outputRoot) {
|
|
112
|
+
return verifyEntry(entry, index, size, proof, outputRoot);
|
|
113
|
+
}
|
|
114
|
+
/** Verify one reconciliation row against a reconciliation rowsRoot. */
|
|
115
|
+
export function verifyReconcileRow(row, index, size, proof, rowsRoot) {
|
|
116
|
+
return verifyRow(row, index, size, proof, rowsRoot);
|
|
117
|
+
}
|
|
118
|
+
// ──────────────────── WHAT YOU PRODUCE ────────────────────
|
|
119
|
+
/**
|
|
120
|
+
* Build a verifiable transcript of the work your agent did. Add {id, input,
|
|
121
|
+
* output} entries; emit a root you sign/anchor and per-entry inclusion proofs a
|
|
122
|
+
* counterparty can check with verifyReceipt — WITHOUT seeing the rest.
|
|
123
|
+
*
|
|
124
|
+
* `id` is committed (it distinguishes two otherwise-identical entries — the
|
|
125
|
+
* payment-intent identity), so the transcript cannot be made to undercount two
|
|
126
|
+
* distinct pieces of work.
|
|
127
|
+
*/
|
|
128
|
+
export class Transcript {
|
|
129
|
+
entries = [];
|
|
130
|
+
/** Append one unit of work: an identifier, its input, and its output. */
|
|
131
|
+
add(id, input, output) {
|
|
132
|
+
this.entries.push({ drawId: id, nonce: input, seed: output });
|
|
133
|
+
return this;
|
|
134
|
+
}
|
|
135
|
+
/** Number of entries so far. */
|
|
136
|
+
get size() { return this.entries.length; }
|
|
137
|
+
/** The Merkle root to sign or anchor — the single value that commits to all entries. */
|
|
138
|
+
root() { return transcriptRoot(this.entries); }
|
|
139
|
+
/** A retail inclusion proof for entry `index`, ready to hand to a verifier. */
|
|
140
|
+
prove(index) {
|
|
141
|
+
const entry = this.entries[index];
|
|
142
|
+
if (!entry)
|
|
143
|
+
throw new Error(`index ${index} outside transcript of ${this.entries.length}`);
|
|
144
|
+
return { entry, index, size: this.entries.length, proof: inclusionProof(this.entries, index), root: this.root() };
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=trust-sdk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trust-sdk.js","sourceRoot":"","sources":["../src/trust-sdk.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* x402 protocol wire types — EMITS v1, PARSES v1 and v2.
|
|
3
|
+
*
|
|
4
|
+
* Shapes follow the x402 spec (Coinbase/x402 Foundation): a resource
|
|
5
|
+
* server answers 402 with `PaymentRequiredResponse`; the client retries
|
|
6
|
+
* with an `X-PAYMENT` header carrying base64(JSON(PaymentPayload)); the
|
|
7
|
+
* facilitator verifies and settles; the server attaches
|
|
8
|
+
* `X-PAYMENT-RESPONSE` = base64(JSON(SettleResponse)).
|
|
9
|
+
*
|
|
10
|
+
* FlareClaw is the first x402 facilitator on Flare (Coston2 first —
|
|
11
|
+
* network id "coston2", eip155:114).
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* The version we EMIT in our own 402 challenges.
|
|
15
|
+
*
|
|
16
|
+
* We accept v2 payloads too (see `normalizeRequirements` /
|
|
17
|
+
* `decodePaymentHeader`) — being a co-author of x402 extensions while
|
|
18
|
+
* silently refusing the ecosystem's current wire format would be an
|
|
19
|
+
* embarrassing kind of wrong. Emission stays on v1 until every one of
|
|
20
|
+
* our own clients is v2-ready; acceptance is widened first, because
|
|
21
|
+
* accepting more than you emit is the only safe direction to move a
|
|
22
|
+
* protocol version.
|
|
23
|
+
*/
|
|
24
|
+
export declare const X402_VERSION = 1;
|
|
25
|
+
/** Versions this implementation can PARSE. */
|
|
26
|
+
export declare const SUPPORTED_X402_VERSIONS: readonly [1, 2];
|
|
27
|
+
export type X402Version = (typeof SUPPORTED_X402_VERSIONS)[number];
|
|
28
|
+
/**
|
|
29
|
+
* How the payer authorizes the transfer (x402 v2 `extra.assetTransferMethod`).
|
|
30
|
+
*
|
|
31
|
+
* `eip3009` is the default and the only one we can SETTLE today — it is
|
|
32
|
+
* the reason a third-party ERC-20 cannot currently pay us, since the
|
|
33
|
+
* token itself must implement `transferWithAuthorization`. `permit2`
|
|
34
|
+
* is x402's universal fallback for arbitrary ERC-20s; we parse it so a
|
|
35
|
+
* v2 client's intent is never silently misread as EIP-3009, and refuse
|
|
36
|
+
* it explicitly rather than mis-settling.
|
|
37
|
+
*/
|
|
38
|
+
export type AssetTransferMethod = 'eip3009' | 'permit2' | 'erc7710';
|
|
39
|
+
export declare const PAYMENT_HEADER = "X-PAYMENT";
|
|
40
|
+
/**
|
|
41
|
+
* v2 servers may deliver the challenge in a RESPONSE HEADER with a null body
|
|
42
|
+
* instead of in the body. Measured on a live commercial deployment
|
|
43
|
+
* (x402.glassnode.com, 2026-08-06): `payment-required:` base64, body `null`.
|
|
44
|
+
* A client that only reads the body sees nothing and cannot pay them.
|
|
45
|
+
*/
|
|
46
|
+
export declare const PAYMENT_REQUIRED_HEADER = "payment-required";
|
|
47
|
+
export declare const PAYMENT_RESPONSE_HEADER = "X-PAYMENT-RESPONSE";
|
|
48
|
+
/** One acceptable way to pay for a resource. */
|
|
49
|
+
export interface PaymentRequirements {
|
|
50
|
+
scheme: 'exact';
|
|
51
|
+
/** Network id, e.g. "coston2" (chainId 114). */
|
|
52
|
+
network: string;
|
|
53
|
+
/**
|
|
54
|
+
* Price in the asset's atomic units, decimal string.
|
|
55
|
+
*
|
|
56
|
+
* v1 spells this `maxAmountRequired`; **v2 renamed it `amount`**.
|
|
57
|
+
* Both are optional at the type level so either wire shape parses;
|
|
58
|
+
* `requirementAmount()` is the single reader that resolves them, so
|
|
59
|
+
* no call site has to know which version it is holding.
|
|
60
|
+
*/
|
|
61
|
+
maxAmountRequired?: string;
|
|
62
|
+
/** x402 v2 name for `maxAmountRequired`. */
|
|
63
|
+
amount?: string;
|
|
64
|
+
/** URL/path of the paid resource. */
|
|
65
|
+
resource: string;
|
|
66
|
+
description: string;
|
|
67
|
+
mimeType: string;
|
|
68
|
+
/** Receiving address (the platform treasury). */
|
|
69
|
+
payTo: string;
|
|
70
|
+
/** Seconds the client has to produce a settleable payment. */
|
|
71
|
+
maxTimeoutSeconds: number;
|
|
72
|
+
/** ERC-20 (EIP-3009) token contract address. */
|
|
73
|
+
asset: string;
|
|
74
|
+
/** EIP-712 domain of the asset — payers need name+version to sign.
|
|
75
|
+
* v2 additionally carries `assetTransferMethod` here. */
|
|
76
|
+
extra: {
|
|
77
|
+
name: string;
|
|
78
|
+
version: string;
|
|
79
|
+
assetTransferMethod?: AssetTransferMethod;
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/** Body of every 402 response. */
|
|
83
|
+
export interface PaymentRequiredResponse {
|
|
84
|
+
x402Version: X402Version;
|
|
85
|
+
error: string;
|
|
86
|
+
/** The offered options. v1 AND v2 both spell this `accepts` (array). */
|
|
87
|
+
accepts?: PaymentRequirements[];
|
|
88
|
+
/**
|
|
89
|
+
* NOT a v2 rename of `accepts` — we had that wrong. In v2, `accepted` is a
|
|
90
|
+
* DIFFERENT field carrying the SINGLE requirement a payer chose, and it
|
|
91
|
+
* lives in the payment payload and settlement response, not in the 402.
|
|
92
|
+
* (v2 spec §5.1.2: `PaymentRequired.accepts` is a required array; §5.2
|
|
93
|
+
* `accepted` is "PaymentRequirements object indicating the payment method
|
|
94
|
+
* chosen".) Kept here only so a server that misuses it in a 402 still
|
|
95
|
+
* parses — being liberal in what we accept, not endorsing the shape.
|
|
96
|
+
*/
|
|
97
|
+
accepted?: PaymentRequirements[] | PaymentRequirements;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* The amount a requirement asks for, whichever version wrote it.
|
|
101
|
+
* Throws rather than defaulting: a missing price must never quietly
|
|
102
|
+
* become zero on a payment path.
|
|
103
|
+
*/
|
|
104
|
+
export declare function requirementAmount(r: PaymentRequirements): string;
|
|
105
|
+
/**
|
|
106
|
+
* The offered requirements of a 402 body.
|
|
107
|
+
*
|
|
108
|
+
* `accepts` is the spec field in BOTH versions. The `accepted` fallback exists
|
|
109
|
+
* only to tolerate servers that put the chosen-requirement field in a 402 by
|
|
110
|
+
* mistake; it is normalised to an array so no caller has to care.
|
|
111
|
+
*/
|
|
112
|
+
export declare function offeredRequirements(body: PaymentRequiredResponse): PaymentRequirements[];
|
|
113
|
+
/** Declared transfer method, defaulting per spec to `eip3009`. */
|
|
114
|
+
export declare function transferMethod(r: PaymentRequirements): AssetTransferMethod;
|
|
115
|
+
/** EIP-3009 TransferWithAuthorization message (all uints as decimal strings). */
|
|
116
|
+
export interface Eip3009Authorization {
|
|
117
|
+
from: string;
|
|
118
|
+
to: string;
|
|
119
|
+
value: string;
|
|
120
|
+
validAfter: string;
|
|
121
|
+
validBefore: string;
|
|
122
|
+
/** 32-byte hex nonce, unique per (from, nonce) — on-chain replay guard. */
|
|
123
|
+
nonce: string;
|
|
124
|
+
}
|
|
125
|
+
/** Scheme-specific payload for "exact" on EVM. */
|
|
126
|
+
export interface ExactEvmPayload {
|
|
127
|
+
/** 65-byte EIP-712 signature over the authorization, hex. */
|
|
128
|
+
signature: string;
|
|
129
|
+
authorization: Eip3009Authorization;
|
|
130
|
+
}
|
|
131
|
+
/** Decoded content of the X-PAYMENT header. */
|
|
132
|
+
export interface PaymentPayload {
|
|
133
|
+
x402Version: typeof X402_VERSION;
|
|
134
|
+
scheme: 'exact';
|
|
135
|
+
network: string;
|
|
136
|
+
payload: ExactEvmPayload;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Machine-readable failure classes for `verify`.
|
|
140
|
+
*
|
|
141
|
+
* ── WHY A CODE AND NOT JUST PROSE ──
|
|
142
|
+
* `invalidReason` is a human string, so a payer can only pattern-match
|
|
143
|
+
* it — and every implementer words it differently. The distinction that
|
|
144
|
+
* actually matters to a client is REMEDY: is this rejection permanent
|
|
145
|
+
* (do not retry — you would be signing a second payment for a claim
|
|
146
|
+
* that will never succeed), or is it a repairable local condition?
|
|
147
|
+
*
|
|
148
|
+
* Clock skew is the case that forced this. A payer whose clock is fast
|
|
149
|
+
* builds `validAfter` in the future, or one whose clock is slow builds
|
|
150
|
+
* `validBefore` too close to now; the facilitator rejects, and the
|
|
151
|
+
* payer reads a generic failure as "this venue refuses me" when the
|
|
152
|
+
* correct action is *resync your clock and re-sign*. That is a
|
|
153
|
+
* repairable condition being reported as a rejection — the payer gives
|
|
154
|
+
* up on a service that would have served them.
|
|
155
|
+
*/
|
|
156
|
+
export type InvalidCode =
|
|
157
|
+
/** Payer's clock disagrees with the facilitator's. RESYNC AND RETRY. */
|
|
158
|
+
'clock-skew'
|
|
159
|
+
/** Payment terms don't match the requirements (payTo, asset, amount, scheme). */
|
|
160
|
+
| 'terms-mismatch'
|
|
161
|
+
/** Signature invalid or recovers to the wrong address. */
|
|
162
|
+
| 'signature'
|
|
163
|
+
/** Nonce already used or canceled — this authorization is spent. */
|
|
164
|
+
| 'nonce-used'
|
|
165
|
+
/**
|
|
166
|
+
* A settlement for THIS (payer, nonce) is already broadcasting.
|
|
167
|
+
* Distinct from `nonce-used`: that one is spent, this one is
|
|
168
|
+
* in-flight and its outcome is not yet knowable. Retry after the
|
|
169
|
+
* first attempt resolves — do NOT sign a fresh nonce (the original
|
|
170
|
+
* may well succeed). Costs the payer nothing and the facilitator
|
|
171
|
+
* no gas.
|
|
172
|
+
*/
|
|
173
|
+
| 'nonce-in-flight'
|
|
174
|
+
/** Payer lacks the funds. */
|
|
175
|
+
| 'insufficient-funds'
|
|
176
|
+
/** Authorization expired; a fresh one is required. */
|
|
177
|
+
| 'expired'
|
|
178
|
+
/** Malformed request the facilitator could not interpret. */
|
|
179
|
+
| 'malformed';
|
|
180
|
+
export interface VerifyResponse {
|
|
181
|
+
isValid: boolean;
|
|
182
|
+
invalidReason?: string;
|
|
183
|
+
/**
|
|
184
|
+
* Machine-readable class of `invalidReason`. Optional for backward
|
|
185
|
+
* compatibility — a client that ignores it behaves exactly as
|
|
186
|
+
* before; one that reads it can tell "fix your clock" from "this
|
|
187
|
+
* will never work".
|
|
188
|
+
*/
|
|
189
|
+
invalidCode?: InvalidCode;
|
|
190
|
+
/**
|
|
191
|
+
* Present when the failure is clock-related: the facilitator's own
|
|
192
|
+
* unix seconds at verification, so the payer can measure its skew
|
|
193
|
+
* directly instead of guessing. This is the same courtesy HTTP
|
|
194
|
+
* `Date` provides — the server already knows the answer, and
|
|
195
|
+
* withholding it makes the payer's problem unsolvable.
|
|
196
|
+
*/
|
|
197
|
+
serverTime?: number;
|
|
198
|
+
/** Recovered payer address (when the signature is valid). */
|
|
199
|
+
payer?: string;
|
|
200
|
+
}
|
|
201
|
+
export interface SettleResponse {
|
|
202
|
+
success: boolean;
|
|
203
|
+
errorReason?: string;
|
|
204
|
+
/** Same classification as VerifyResponse — settle verifies first. */
|
|
205
|
+
invalidCode?: InvalidCode;
|
|
206
|
+
/** Facilitator's unix seconds, present on clock-related failures. */
|
|
207
|
+
serverTime?: number;
|
|
208
|
+
/** Settlement transaction hash. */
|
|
209
|
+
transaction: string;
|
|
210
|
+
network: string;
|
|
211
|
+
payer: string;
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|