@xfuel/verify 0.1.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/dist/cli.js ADDED
@@ -0,0 +1,236 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /**
4
+ * xfuel-verify CLI — Offline receipt verification.
5
+ *
6
+ * Usage:
7
+ * xfuel-verify receipt.json
8
+ * xfuel-verify receipt.json --check-nullifier
9
+ * xfuel-verify receipt.json --rpc https://mainnet.base.org
10
+ * cat receipt.json | xfuel-verify -
11
+ *
12
+ * Exit codes:
13
+ * 0 = verified
14
+ * 1 = verification failed
15
+ * 2 = partial (binding ok, nullifier not checked or pending)
16
+ * 3 = input error
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ const node_fs_1 = require("node:fs");
20
+ const index_js_1 = require("./index.js");
21
+ const HELP = `
22
+ xfuel-verify — Offline verification for Chit402 receipts
23
+
24
+ Usage:
25
+ xfuel-verify <receipt.json> Verify binding locally
26
+ xfuel-verify <receipt.json> --jwks-file <jwks.json>
27
+ Verify issuer signature with JWKS
28
+ xfuel-verify <receipt.json> --check-nullifier
29
+ Also verify nullifier on-chain
30
+ xfuel-verify - < receipt.json Read from stdin
31
+ xfuel-verify --help Show this help
32
+
33
+ Options:
34
+ --jwks-file <path> JWKS file for issuer signature verification (no network)
35
+ --check-nullifier Query Base RPC for nullifier anchor (requires network)
36
+ --rpc <url> Custom RPC URL (default: https://mainnet.base.org)
37
+ --json Output JSON instead of human-readable
38
+ --quiet Only output errors
39
+
40
+ Exit codes:
41
+ 0 = verified
42
+ 1 = verification failed
43
+ 2 = partial verification (binding ok, nullifier not checked)
44
+ 3 = input error
45
+
46
+ Network behavior:
47
+ By default, no network requests are made. Network is only used when:
48
+ - --check-nullifier is passed (queries Base RPC for on-chain anchor)
49
+
50
+ JWKS must be provided as a local file (--jwks-file). The CLI does not
51
+ automatically fetch JWKS from a URL to ensure offline verification.
52
+
53
+ Examples:
54
+ # Local binding verification (no network)
55
+ xfuel-verify my-receipt.json
56
+
57
+ # Verify issuer signature with JWKS file
58
+ xfuel-verify my-receipt.json --jwks-file issuer-jwks.json
59
+
60
+ # Full verification including on-chain nullifier
61
+ xfuel-verify my-receipt.json --jwks-file issuer-jwks.json --check-nullifier
62
+
63
+ # Pipe from curl
64
+ curl -s https://api.chit402.com/receipt/task-123?format=json | xfuel-verify -
65
+ `;
66
+ function parseArgs(args) {
67
+ const result = {
68
+ file: null,
69
+ jwksFile: null,
70
+ checkNullifier: false,
71
+ rpcUrl: null,
72
+ json: false,
73
+ quiet: false,
74
+ help: false,
75
+ };
76
+ for (let i = 0; i < args.length; i++) {
77
+ const arg = args[i];
78
+ if (arg === '--help' || arg === '-h') {
79
+ result.help = true;
80
+ }
81
+ else if (arg === '--check-nullifier') {
82
+ result.checkNullifier = true;
83
+ }
84
+ else if (arg === '--jwks-file' && args[i + 1]) {
85
+ result.jwksFile = args[++i];
86
+ }
87
+ else if (arg === '--rpc' && args[i + 1]) {
88
+ result.rpcUrl = args[++i];
89
+ }
90
+ else if (arg === '--json') {
91
+ result.json = true;
92
+ }
93
+ else if (arg === '--quiet' || arg === '-q') {
94
+ result.quiet = true;
95
+ }
96
+ else if (!arg.startsWith('-')) {
97
+ result.file = arg;
98
+ }
99
+ }
100
+ return result;
101
+ }
102
+ function readReceipt(file) {
103
+ let content;
104
+ if (file === '-') {
105
+ content = (0, node_fs_1.readFileSync)(0, 'utf8');
106
+ }
107
+ else {
108
+ content = (0, node_fs_1.readFileSync)(file, 'utf8');
109
+ }
110
+ return JSON.parse(content);
111
+ }
112
+ function formatAmount(units) {
113
+ if (!units)
114
+ return '—';
115
+ const n = Number(units);
116
+ if (!Number.isFinite(n))
117
+ return units;
118
+ const usd = n / 1e6;
119
+ return `$${usd.toFixed(usd >= 0.01 ? 2 : 6)} (${units} units)`;
120
+ }
121
+ async function main() {
122
+ const args = parseArgs(process.argv.slice(2));
123
+ if (args.help || !args.file) {
124
+ console.log(HELP);
125
+ return args.help ? 0 : 3;
126
+ }
127
+ let receipt;
128
+ try {
129
+ receipt = readReceipt(args.file);
130
+ }
131
+ catch (err) {
132
+ console.error(`Error reading receipt: ${err instanceof Error ? err.message : String(err)}`);
133
+ return 3;
134
+ }
135
+ if (!receipt.task_id) {
136
+ console.error('Invalid receipt: missing task_id');
137
+ return 3;
138
+ }
139
+ // Load JWKS if provided
140
+ let jwks;
141
+ if (args.jwksFile) {
142
+ try {
143
+ const jwksContent = (0, node_fs_1.readFileSync)(args.jwksFile, 'utf8');
144
+ jwks = JSON.parse(jwksContent);
145
+ }
146
+ catch (err) {
147
+ console.error(`Error reading JWKS file: ${err instanceof Error ? err.message : String(err)}`);
148
+ return 3;
149
+ }
150
+ }
151
+ const result = await (0, index_js_1.verifyReceipt)(receipt, {
152
+ jwks,
153
+ checkNullifier: args.checkNullifier,
154
+ rpcUrl: args.rpcUrl || undefined,
155
+ });
156
+ if (args.json) {
157
+ console.log(JSON.stringify(result, null, 2));
158
+ }
159
+ else if (!args.quiet || result.overall === 'failed') {
160
+ console.log('');
161
+ console.log(` Chit402 Receipt Verification`);
162
+ console.log(` ─────────────────────────────────────────────────`);
163
+ console.log(` Receipt ID: ${result.receipt_id}`);
164
+ console.log(` Hub: ${result.hub || '—'}`);
165
+ console.log(` Model: ${result.model || '—'}`);
166
+ console.log(` Amount: ${formatAmount(result.amount_usdc)}`);
167
+ console.log(` TX: ${result.tx || '—'}`);
168
+ console.log(` Output Hash: ${result.output_hash ? result.output_hash.slice(0, 18) + '…' : '—'}`);
169
+ console.log('');
170
+ console.log(` Binding`);
171
+ console.log(` ─────────────────────────────────────────────────`);
172
+ if (result.binding.expected) {
173
+ console.log(` Expected: ${result.binding.expected.slice(0, 18)}…`);
174
+ console.log(` Recomputed: ${result.binding.recomputed?.slice(0, 18)}…`);
175
+ console.log(` Match: ${result.binding.matches ? '✓ YES' : '✗ NO'}`);
176
+ console.log(` Covers: ${result.binding.covers.join(', ')}`);
177
+ }
178
+ else {
179
+ console.log(` Status: No binding (${result.binding.reason})`);
180
+ }
181
+ console.log('');
182
+ console.log(` Issuer Signature`);
183
+ console.log(` ─────────────────────────────────────────────────`);
184
+ if (result.issuer_signature.checked) {
185
+ console.log(` Kid: ${result.issuer_signature.kid || '—'}`);
186
+ console.log(` Valid: ${result.issuer_signature.valid ? '✓ YES' : '✗ NO'}`);
187
+ if (!result.issuer_signature.valid && result.issuer_signature.reason) {
188
+ console.log(` Reason: ${result.issuer_signature.reason}`);
189
+ }
190
+ }
191
+ else {
192
+ console.log(` Status: ${result.issuer_signature.reason || 'Not checked'}`);
193
+ if (receipt.issuer_signature && !args.jwksFile) {
194
+ console.log(` (receipt has signature — pass --jwks-file to verify)`);
195
+ }
196
+ }
197
+ console.log('');
198
+ console.log(` Nullifier`);
199
+ console.log(` ─────────────────────────────────────────────────`);
200
+ if (result.nullifier.nullifier) {
201
+ console.log(` Value: ${result.nullifier.nullifier.slice(0, 18)}…`);
202
+ if (args.checkNullifier) {
203
+ console.log(` On-chain: ${result.nullifier.anchored ? '✓ ANCHORED' : '✗ NOT FOUND'}`);
204
+ }
205
+ else {
206
+ console.log(` On-chain: (not checked — use --check-nullifier)`);
207
+ }
208
+ }
209
+ else {
210
+ console.log(` Status: No nullifier (Tier-1 receipt)`);
211
+ }
212
+ console.log('');
213
+ console.log(` Overall: ${result.overall.toUpperCase()}`);
214
+ if (result.errors.length > 0) {
215
+ console.log(` Errors: ${result.errors.join(', ')}`);
216
+ }
217
+ console.log('');
218
+ }
219
+ switch (result.overall) {
220
+ case 'verified':
221
+ return 0;
222
+ case 'failed':
223
+ return 1;
224
+ case 'partial':
225
+ return 2;
226
+ default:
227
+ return 1;
228
+ }
229
+ }
230
+ main()
231
+ .then((code) => process.exit(code))
232
+ .catch((err) => {
233
+ console.error('Unexpected error:', err);
234
+ process.exit(3);
235
+ });
236
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,228 @@
1
+ /**
2
+ * @xfuel/verify — Offline verification for Chit402 receipts.
3
+ *
4
+ * Verify payment binding and output commitment WITHOUT calling the Chit402 API.
5
+ * Third parties use this to confirm:
6
+ * 1. The receipt's payment binding matches on-chain settlement
7
+ * 2. The output hash commitment is correct
8
+ * 3. The issuer signature is valid (ES256/JWKS)
9
+ * 4. (Optional) The SP1 nullifier is anchored on-chain
10
+ *
11
+ * See docs/specs/RECEIPT_V2_SEMANTICS.md for the verification algorithm.
12
+ */
13
+ import { computePaymentCommitment, computeInferenceBinding, type PaymentCommitmentInput, type InferenceBindingInput } from './binding.js';
14
+ export { computePaymentCommitment, computeInferenceBinding, type PaymentCommitmentInput, type InferenceBindingInput, };
15
+ /** ZKVerifierSP1 contract on Base mainnet. */
16
+ export declare const ZK_VERIFIER_ADDRESS = "0x9373499645292715a2275A78eD65B14215C41c06";
17
+ /** Default Base mainnet RPC. */
18
+ export declare const BASE_RPC_URL = "https://mainnet.base.org";
19
+ /** Base Sepolia testnet RPC. */
20
+ export declare const BASE_SEPOLIA_RPC_URL = "https://sepolia.base.org";
21
+ /** Chit402 receipt (v2/v3 compatible). */
22
+ export interface XFuelReceipt {
23
+ schema?: string;
24
+ task_id: string;
25
+ status: string;
26
+ proof_outcome?: string;
27
+ verify_url?: string;
28
+ route?: {
29
+ model?: string;
30
+ provider?: string;
31
+ model_commitment?: {
32
+ commitment?: string;
33
+ } | null;
34
+ };
35
+ payment?: {
36
+ rail?: string;
37
+ ref?: string | null;
38
+ gross_amount?: string;
39
+ net_amount?: string;
40
+ fee_amount?: string;
41
+ fee_bps?: number;
42
+ protocol_fee_bps?: number;
43
+ platform_fee?: string;
44
+ platform_fee_bps?: number;
45
+ };
46
+ provider_cogs?: {
47
+ actual?: string;
48
+ };
49
+ output?: {
50
+ hash?: string;
51
+ kind?: string;
52
+ } | null;
53
+ proof?: {
54
+ tier?: string;
55
+ has_proof?: boolean;
56
+ nullifier?: string | null;
57
+ };
58
+ binding?: {
59
+ expected_commitment?: string;
60
+ recomputed_commitment?: string;
61
+ matches?: boolean;
62
+ covers?: string[];
63
+ model_commitment?: string | null;
64
+ output_hash?: string | null;
65
+ amount?: string;
66
+ rail?: string;
67
+ } | null;
68
+ signature?: {
69
+ alg?: string;
70
+ value?: string;
71
+ };
72
+ issuer_signature?: {
73
+ alg?: string;
74
+ value?: string;
75
+ kid?: string;
76
+ };
77
+ }
78
+ /** JWK public key for ES256 verification. */
79
+ export interface Es256Jwk {
80
+ kty: 'EC';
81
+ crv: 'P-256';
82
+ x: string;
83
+ y: string;
84
+ kid?: string;
85
+ alg?: string;
86
+ use?: string;
87
+ }
88
+ /** JWKS (JSON Web Key Set) structure. */
89
+ export interface Jwks {
90
+ keys: Es256Jwk[];
91
+ }
92
+ /** Result of ECDSA signature verification. */
93
+ export interface IssuerSignatureVerification {
94
+ /** Whether an issuer signature was present to check. */
95
+ checked: boolean;
96
+ /** True if the ECDSA signature is valid. */
97
+ valid: boolean;
98
+ /** Key ID from the signature. */
99
+ kid?: string;
100
+ /** Reason for failure when valid=false. */
101
+ reason?: string;
102
+ }
103
+ export interface BindingVerification {
104
+ verified: boolean;
105
+ expected: string | null;
106
+ recomputed: string | null;
107
+ matches: boolean;
108
+ covers: string[];
109
+ reason?: string;
110
+ }
111
+ export interface NullifierVerification {
112
+ verified: boolean;
113
+ nullifier: string | null;
114
+ anchored: boolean | null;
115
+ reason?: string;
116
+ }
117
+ export interface ReceiptVerification {
118
+ receipt_id: string;
119
+ binding: BindingVerification;
120
+ issuer_signature: IssuerSignatureVerification;
121
+ nullifier: NullifierVerification;
122
+ output_hash: string | null;
123
+ hub: string | null;
124
+ model: string | null;
125
+ amount_usdc: string | null;
126
+ tx: string | null;
127
+ overall: 'verified' | 'partial' | 'failed';
128
+ errors: string[];
129
+ }
130
+ /**
131
+ * Canonical, order-stable payload an issuer signature covers.
132
+ * MUST match `canonicalSignedPayload` in services/gateway/src/receipt.js exactly.
133
+ *
134
+ * Signed fields (15 total):
135
+ * 1. task_id
136
+ * 2. payment.rail
137
+ * 3. payment.ref
138
+ * 4. payment.gross_amount
139
+ * 5. payment.net_amount
140
+ * 6. payment.fee_amount
141
+ * 7. payment.protocol_fee_bps ?? payment.fee_bps
142
+ * 8. payment.platform_fee
143
+ * 9. payment.platform_fee_bps
144
+ * 10. provider_cogs.actual
145
+ * 11. route.model
146
+ * 12. route.model_commitment.commitment
147
+ * 13. route.provider
148
+ * 14. output.hash
149
+ * 15. binding.expected_commitment
150
+ */
151
+ export declare function canonicalIssuerPayload(receipt: XFuelReceipt): string;
152
+ /**
153
+ * Verify a receipt's ES256 issuer signature against a JWK (public key).
154
+ * This is the public-key verification path — no shared secret required.
155
+ *
156
+ * Verification steps:
157
+ * 1. GET /receipt/:taskId?format=json → receipt.issuer_signature
158
+ * 2. GET /.well-known/jwks.json → find key matching issuer_signature.kid
159
+ * 3. ES256 verify canonicalIssuerPayload(receipt) against the signature
160
+ *
161
+ * @param receipt - Receipt JSON with issuer_signature
162
+ * @param jwk - JWK public key { kty: 'EC', crv: 'P-256', x, y }
163
+ */
164
+ export declare function verifyIssuerSignature(receipt: XFuelReceipt, jwk: Es256Jwk): IssuerSignatureVerification;
165
+ /**
166
+ * Verify a receipt's ES256 issuer signature against a JWKS (key set).
167
+ * Finds the matching key by kid and verifies.
168
+ *
169
+ * @param receipt - Receipt JSON with issuer_signature
170
+ * @param jwks - JWKS with keys array
171
+ */
172
+ export declare function verifyIssuerSignatureWithJwks(receipt: XFuelReceipt, jwks: Jwks): IssuerSignatureVerification;
173
+ /**
174
+ * Verify a receipt's payment binding locally (no network required).
175
+ *
176
+ * This recomputes the commitment from the receipt's fields and compares
177
+ * it to the stored `binding.expected_commitment`.
178
+ */
179
+ export declare function verifyBinding(receipt: XFuelReceipt): BindingVerification;
180
+ /**
181
+ * Verify a receipt's nullifier is anchored on-chain.
182
+ *
183
+ * Requires network access to the Base RPC.
184
+ */
185
+ export declare function verifyNullifier(receipt: XFuelReceipt, options?: {
186
+ rpcUrl?: string;
187
+ verifierAddress?: string;
188
+ }): Promise<NullifierVerification>;
189
+ /**
190
+ * Canonical signed payload for HMAC verification.
191
+ * Alias of canonicalIssuerPayload — both must produce identical bytes.
192
+ */
193
+ export declare const canonicalSignedPayload: typeof canonicalIssuerPayload;
194
+ /**
195
+ * Hash the canonical payload (for ERC-8004 response_hash).
196
+ */
197
+ export declare function hashCanonicalPayload(receipt: XFuelReceipt): string;
198
+ /**
199
+ * Full receipt verification — binding + issuer signature + optional nullifier check.
200
+ *
201
+ * @param receipt The Chit402 receipt JSON
202
+ * @param options.jwks JWKS for issuer signature verification (no network fetch)
203
+ * @param options.checkNullifier Whether to verify nullifier on-chain (requires network)
204
+ * @param options.rpcUrl RPC URL for on-chain checks
205
+ */
206
+ export declare function verifyReceipt(receipt: XFuelReceipt, options?: {
207
+ jwks?: Jwks;
208
+ checkNullifier?: boolean;
209
+ rpcUrl?: string;
210
+ verifierAddress?: string;
211
+ }): Promise<ReceiptVerification>;
212
+ declare const _default: {
213
+ verifyBinding: typeof verifyBinding;
214
+ verifyIssuerSignature: typeof verifyIssuerSignature;
215
+ verifyIssuerSignatureWithJwks: typeof verifyIssuerSignatureWithJwks;
216
+ verifyNullifier: typeof verifyNullifier;
217
+ verifyReceipt: typeof verifyReceipt;
218
+ computePaymentCommitment: typeof computePaymentCommitment;
219
+ computeInferenceBinding: typeof computeInferenceBinding;
220
+ canonicalIssuerPayload: typeof canonicalIssuerPayload;
221
+ canonicalSignedPayload: typeof canonicalIssuerPayload;
222
+ hashCanonicalPayload: typeof hashCanonicalPayload;
223
+ ZK_VERIFIER_ADDRESS: string;
224
+ BASE_RPC_URL: string;
225
+ BASE_SEPOLIA_RPC_URL: string;
226
+ };
227
+ export default _default;
228
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}