chit402-verify 0.3.5 → 0.4.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 (108) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +205 -17
  3. package/dist/anchor-trust.d.ts +144 -0
  4. package/dist/anchor-trust.d.ts.map +1 -0
  5. package/dist/anchor-trust.js +441 -0
  6. package/dist/anchor-trust.js.map +1 -0
  7. package/dist/anchor-witness.d.ts +265 -0
  8. package/dist/anchor-witness.d.ts.map +1 -0
  9. package/dist/anchor-witness.js +833 -0
  10. package/dist/anchor-witness.js.map +1 -0
  11. package/dist/base-payer.d.ts +65 -0
  12. package/dist/base-payer.d.ts.map +1 -0
  13. package/dist/base-payer.js +222 -0
  14. package/dist/base-payer.js.map +1 -0
  15. package/dist/binding.d.ts +52 -0
  16. package/dist/binding.d.ts.map +1 -0
  17. package/dist/binding.js +80 -0
  18. package/dist/binding.js.map +1 -0
  19. package/dist/canonical-preimage.d.ts +9 -0
  20. package/dist/canonical-preimage.d.ts.map +1 -0
  21. package/dist/canonical-preimage.js +25 -0
  22. package/dist/canonical-preimage.js.map +1 -0
  23. package/dist/carry-forward.d.ts +79 -0
  24. package/dist/carry-forward.d.ts.map +1 -0
  25. package/dist/carry-forward.js +184 -0
  26. package/dist/carry-forward.js.map +1 -0
  27. package/dist/cli.d.ts +18 -0
  28. package/dist/cli.d.ts.map +1 -0
  29. package/dist/cli.js +2090 -0
  30. package/dist/cli.js.map +1 -0
  31. package/dist/epoch.d.ts +143 -0
  32. package/dist/epoch.d.ts.map +1 -0
  33. package/dist/epoch.js +352 -0
  34. package/dist/epoch.js.map +1 -0
  35. package/dist/head-binding.d.ts +24 -0
  36. package/dist/head-binding.d.ts.map +1 -0
  37. package/dist/head-binding.js +61 -0
  38. package/dist/head-binding.js.map +1 -0
  39. package/dist/index.d.ts +585 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +1648 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/issuer-history.d.ts +151 -0
  44. package/dist/issuer-history.d.ts.map +1 -0
  45. package/dist/issuer-history.js +595 -0
  46. package/dist/issuer-history.js.map +1 -0
  47. package/dist/issuer-pin.d.ts +126 -0
  48. package/dist/issuer-pin.d.ts.map +1 -0
  49. package/dist/issuer-pin.js +567 -0
  50. package/dist/issuer-pin.js.map +1 -0
  51. package/dist/jcs.d.ts +8 -0
  52. package/dist/jcs.d.ts.map +1 -0
  53. package/dist/jcs.js +64 -0
  54. package/dist/jcs.js.map +1 -0
  55. package/dist/jws.d.ts +46 -0
  56. package/dist/jws.d.ts.map +1 -0
  57. package/dist/jws.js +129 -0
  58. package/dist/jws.js.map +1 -0
  59. package/dist/payer.d.ts +65 -0
  60. package/dist/payer.d.ts.map +1 -0
  61. package/dist/payer.js +148 -0
  62. package/dist/payer.js.map +1 -0
  63. package/dist/preimage.d.ts +78 -0
  64. package/dist/preimage.d.ts.map +1 -0
  65. package/dist/preimage.js +363 -0
  66. package/dist/preimage.js.map +1 -0
  67. package/dist/receipt-lane.d.ts +235 -0
  68. package/dist/receipt-lane.d.ts.map +1 -0
  69. package/dist/receipt-lane.js +446 -0
  70. package/dist/receipt-lane.js.map +1 -0
  71. package/dist/receipt-version.d.ts +98 -0
  72. package/dist/receipt-version.d.ts.map +1 -0
  73. package/dist/receipt-version.js +364 -0
  74. package/dist/receipt-version.js.map +1 -0
  75. package/dist/refusal.d.ts +93 -0
  76. package/dist/refusal.d.ts.map +1 -0
  77. package/dist/refusal.js +249 -0
  78. package/dist/refusal.js.map +1 -0
  79. package/dist/request-binding.d.ts +7 -0
  80. package/dist/request-binding.d.ts.map +1 -0
  81. package/dist/request-binding.js +26 -0
  82. package/dist/request-binding.js.map +1 -0
  83. package/dist/row-hash.d.ts +22 -0
  84. package/dist/row-hash.d.ts.map +1 -0
  85. package/dist/row-hash.js +26 -0
  86. package/dist/row-hash.js.map +1 -0
  87. package/dist/shell.d.ts +65 -0
  88. package/dist/shell.d.ts.map +1 -0
  89. package/dist/shell.js +268 -0
  90. package/dist/shell.js.map +1 -0
  91. package/dist/solana-payer.d.ts +99 -0
  92. package/dist/solana-payer.d.ts.map +1 -0
  93. package/dist/solana-payer.js +258 -0
  94. package/dist/solana-payer.js.map +1 -0
  95. package/dist/v11-receipt.d.ts +23 -0
  96. package/dist/v11-receipt.d.ts.map +1 -0
  97. package/dist/v11-receipt.js +368 -0
  98. package/dist/v11-receipt.js.map +1 -0
  99. package/dist/verdict.d.ts +94 -0
  100. package/dist/verdict.d.ts.map +1 -0
  101. package/dist/verdict.js +381 -0
  102. package/dist/verdict.js.map +1 -0
  103. package/issuer-history.snapshot.json +1 -0
  104. package/package.json +32 -22
  105. package/cli.js +0 -42
  106. package/index.cjs +0 -8
  107. package/index.d.ts +0 -5
  108. package/index.js +0 -7
package/LICENSE CHANGED
@@ -186,7 +186,7 @@
186
186
  same "printed page" as the copyright notice for easier
187
187
  identification within third-party archives.
188
188
 
189
- Copyright [yyyy] [name of copyright owner]
189
+ Copyright 2026 XFuel Lab
190
190
 
191
191
  Licensed under the Apache License, Version 2.0 (the "License");
192
192
  you may not use this file except in compliance with the License.
package/README.md CHANGED
@@ -4,6 +4,8 @@ Offline verification for Chit402 receipts — verify payment binding and output
4
4
 
5
5
  npm: `chit402-verify` · License: Apache-2.0 · Docs: https://chit402.com
6
6
 
7
+ `@xfuel/verify` 0.4.0 is an alias pinned to exactly this version. The `xfuel-verify` command stays.
8
+
7
9
  ## Installation
8
10
 
9
11
  ```bash
@@ -15,7 +17,7 @@ npm install chit402-verify
15
17
  ### Library
16
18
 
17
19
  ```typescript
18
- import { verifyReceipt, verifyBinding, verifyNullifier } from 'chit402-verify';
20
+ import { verifyReceipt, verifyBinding, verifyNullifier } from '@xfuel/verify';
19
21
 
20
22
  // Verify a receipt offline (binding only, no network)
21
23
  const receipt = { /* Chit402 receipt JSON */ };
@@ -25,26 +27,39 @@ console.log(result.matches); // true if binding verified
25
27
  // Full verification including on-chain nullifier check
26
28
  const fullResult = await verifyReceipt(receipt, { checkNullifier: true });
27
29
  console.log(fullResult.overall); // 'verified' | 'partial' | 'failed'
30
+ console.log(fullResult.receipt_lane.freeze); // unsigned; does not change overall
28
31
  ```
29
32
 
30
33
  ### CLI
31
34
 
32
35
  ```bash
33
- # Local binding verification (no network required)
34
- npx chit402-verify receipt.json
36
+ # History is always checked. With no file, a live snapshot must prefix-extend
37
+ # the copy shipped in this package, or that copy is used (as of 2026-10-14).
38
+ npx xfuel-verify receipt.json
39
+
40
+ # Offline history. --no-issuer-history, --strict, --accept-no-key-window,
41
+ # and --accept-shell are removed.
42
+ npx xfuel-verify receipt.json --issuer-history issuer-history.json
35
43
 
36
- # Hash the canonical object (must match signed payload_hash) and read not_after
37
- # from a pinned issuer-history snapshot. Both flags are offline.
38
- npx chit402-verify receipt.json --canonical-preimage preimage.json --issuer-history-file issuer-history.json
44
+ # Hash the canonical object (must match signed payload_hash).
45
+ npx xfuel-verify receipt.json --canonical-preimage preimage.json --issuer-history issuer-history.json
46
+
47
+ # A signed refusal (schema chit402.refusal.v1) is not a payment.
48
+ # The check proves the issuer refused, at the signed anchor, for that code.
49
+ # It does not prove a payment or that the block still stands.
50
+ npx xfuel-verify refusal.json
39
51
 
40
52
  # With on-chain nullifier check (requires network)
41
- npx chit402-verify receipt.json --check-nullifier
53
+ npx xfuel-verify receipt.json --check-nullifier
42
54
 
43
55
  # Output as JSON
44
- npx chit402-verify receipt.json --json
56
+ npx xfuel-verify receipt.json --json
45
57
 
46
58
  # From stdin
47
- curl -s https://api.chit402.com/receipt/task-123?format=json | npx chit402-verify -
59
+ curl -s https://api.chit402.com/receipt/task-123?format=json | npx xfuel-verify -
60
+
61
+ # Dual anchor: inclusion, Solana memo, Base calldata
62
+ npx xfuel-verify receipt.json inclusion.json head.json --rpc
48
63
  ```
49
64
 
50
65
  ## What This Verifies
@@ -52,12 +67,124 @@ curl -s https://api.chit402.com/receipt/task-123?format=json | npx chit402-verif
52
67
  | Check | Requires Network? | Description |
53
68
  |-------|-------------------|-------------|
54
69
  | Payment binding | No | Recompute commitment from receipt fields |
55
- | Issuer signature | No, unless `--fetch-jwks` | ES256. Trusted via JWKS (by kid) or the pinned production kid. Embedded `issuer_jwk` alone is not enough. |
70
+ | Issuer signature | No, unless `--fetch-jwks` | ES256. Trusted only via JWKS (by kid) or a pinned RFC 7638 kid |
56
71
  | Output hash | No | Hash is on the receipt |
57
72
  | On-chain settlement | Yes | Query Base RPC for tx |
58
73
  | Nullifier anchor | Yes | Query ZKVerifierSP1 contract |
59
- | Canonical preimage | No | `--canonical-preimage` is SHA-256'd and matched to signed `payload_hash` |
60
- | Issuer history | No, with `--issuer-history-file` | `iat` is inside the kid's `not_before` / `not_after`. A payload v10 pin must match |
74
+ | Tree head and inclusion | No | Head ES256 signature over size and root, then an index-and-size-bound inclusion proof |
75
+ | Anchored receipt root | Yes, with `--rpc` | The offline head and inclusion checks, then Solana memo and fee payer and Base calldata and sender |
76
+ | Canonical preimage | No | SHA-256 of `--canonical-preimage`, or the stored canonical object, matches signed `payload_hash` |
77
+ | Issuer history | Always. File, else a live prefix of the shipped snapshot, else the shipped snapshot | `iat` is inside the latest `not_before` and the earliest `not_after` for that kid. A changed `not_before` is `kid_status_regression` (exit 1). No covering key is exit 2 |
78
+
79
+ ## Issuer Signature Verification (ES256)
80
+
81
+ Receipts include `issuer_signature.jws` (compact ES256 / P-256). The signature
82
+ counts only when the verifying key is trusted:
83
+
84
+ 1. **JWKS by kid** — a key in `--jwks-file`, `--jwks-url`, or `--fetch-jwks`
85
+ (allowlisted host, default `api.chit402.com`) whose `kid` matches the JWS.
86
+ 2. **Pinned thumbprint** — the embedded `issuer_jwk` is used only when its
87
+ RFC 7638 thumbprint equals a trusted kid. The default offline pin is the
88
+ production kid `IvFpmC-vPhkY_v0vidsrWVT9uzlE5XWKZgAEOeJTq1Q`. Override with
89
+ `--trusted-kid`, or disable with `--no-trusted-kid`.
90
+
91
+ The epoch record and the tree head use those same sources, with or without `--rpc`. `xfuel-verify receipt.json inclusion.json head.json` checks the head signature and the inclusion proof offline. `--rpc` adds the chain checks. An embedded key still has to match the trusted-kid pin, or the kid has to be in a verified issuer-history entry. The head's signed `anchors.base.from` and `anchors.solana.fee_payer` must be on the anchor-wallet list (the package pin, or a verified `/.well-known/anchor-wallets.json`). The chain sender and fee payer must be those wallets. `--version` prints the package version.
92
+
93
+ Anchor mode also checks a content-addressed issuer pin when the receipt or the head carries `issuer_key_pin`, or when you pass `--issuer-pin`. The pin is a 40-hex commit plus the SHA-256 of `docs/well-known/issuer-key.json`. A branch name is not fetched. A claimed pin requires `issuer_signature.jws` verified under that key. Unsigned envelope kids do not satisfy the check. The registration self-signature is checked when the file has one. A claimed era with no pin fails `ISSUER_PIN_DOWNGRADE`. Receipts that do not claim the era skip this check. The pin chain is Base Sepolia (`eip155:84532`). See [issuer-key-pin.md](../../docs/product/issuer-key-pin.md).
94
+
95
+ `issuer_jwk` on the receipt is not a trust root. A copy re-signed with an
96
+ arbitrary P-256 key reports `key untrusted` (`issuer_signature.valid === false`),
97
+ including when `--jwks-file` points at the real JWKS.
98
+
99
+ ```bash
100
+ # History is always on. A local snapshot:
101
+ npx xfuel-verify receipt.json --issuer-history issuer-history.json
102
+
103
+ # Recompute a published canonical preimage and check the kid window.
104
+ # curl -f stops on HTTP errors. Most receipts have no /preimage (a 404).
105
+ # A missing preimage is not a verification failure: omit --canonical-preimage.
106
+ curl -fsS "https://api.chit402.com/receipt/RECEIPT_ID?format=json" -o receipt.json
107
+ curl -fsS "https://api.chit402.com/.well-known/issuer-history.json?version=1" -o issuer-history.json
108
+ if curl -fsS "https://api.chit402.com/receipt/RECEIPT_ID/preimage" -o preimage.json; then
109
+ npx xfuel-verify receipt.json --canonical-preimage preimage.json --issuer-history issuer-history.json
110
+ else
111
+ npx xfuel-verify receipt.json --issuer-history issuer-history.json
112
+ fi
113
+
114
+ # Trust the published JWKS instead of (or in addition to) the pin
115
+ curl -o issuer-jwks.json https://api.chit402.com/.well-known/jwks.json
116
+ npx xfuel-verify receipt.json --jwks-file issuer-jwks.json --no-trusted-kid
117
+
118
+ # Fetch the issuer JWKS (https://api.chit402.com/.well-known/jwks.json)
119
+ npx xfuel-verify receipt.json --fetch-jwks
120
+ ```
121
+
122
+ ```typescript
123
+ import { verifyReceipt } from '@xfuel/verify';
124
+
125
+ const result = await verifyReceipt(receipt);
126
+ console.log(result.issuer_signature.valid); // true only for a trusted key
127
+ console.log(result.issuer_signature.key_trusted);
128
+ console.log(result.amount_usdc); // from verified claims, not the outer copy
129
+ console.log(result.claim_mismatches); // any signed path whose outer copy disagrees
130
+ console.log(result.unsigned_fields); // outer paths the signature does not cover
131
+ console.log(result.verified_scope); // 'signed_claims'
132
+ ```
133
+
134
+ Amount, payer, payee, asset, and tx are read from the verified JWS claims.
135
+ Every signed path is compared with the outer receipt. A mismatch fails.
136
+ Paths the signature does not cover are `unsigned_fields` and are printed as
137
+ `UNVERIFIED`. Overall does not verify them. The outer document `schema` is
138
+ not a copy of the JWS `schema`. `--check-payer` on Base confirms payer, payee,
139
+ asset, and amount in the USDC `Transfer` log.
140
+
141
+ `xfuel-verify receipt.json inclusion.json head.json` also runs those receipt
142
+ checks. A matching inclusion proof does not make a tampered receipt VERIFIED.
143
+
144
+ A paid USDC receipt whose signed `binding.expected_commitment` is null is
145
+ reported as “No payment-binding commitment”, not as an unmetered or TFUEL receipt.
146
+
147
+ The CLI does **not** fetch JWKS unless `--fetch-jwks` or `--jwks-url` is set.
148
+ Exit code 1 is returned when the key is untrusted, the signature is invalid, or
149
+ a signed claim disagrees with the outer copy.
150
+
151
+ ## Frozen Fields
152
+
153
+ These fields are immutable once set and verifiable by any third party:
154
+
155
+ - `task_id` — unique task identifier
156
+ - `route.provider` — compute hub (theta-edgecloud, akash-network)
157
+ - `route.model` — model that served the request
158
+ - `payment.gross_amount` — total charged in USDC atomic units
159
+ - `payment.ref` — settlement reference (network:txHash)
160
+ - `output.hash` — commitment to model output
161
+ - `proof.nullifier` — single-use nullifier anchored on-chain
162
+
163
+ ## Verification Algorithm
164
+
165
+ The binding commitment is computed as:
166
+
167
+ ```solidity
168
+ // Payment-only binding
169
+ keccak256(abi.encodePacked(
170
+ keccak256(payment_ref),
171
+ keccak256(task_id),
172
+ rail_discriminant, // 1=usdc, 2=tfuel
173
+ amount
174
+ ))
175
+
176
+ // PBR (Payment-Bound Receipt) — includes model + output
177
+ keccak256(abi.encodePacked(
178
+ keccak256(payment_ref),
179
+ keccak256(task_id),
180
+ rail_discriminant,
181
+ amount,
182
+ model_commitment,
183
+ output_hash
184
+ ))
185
+ ```
186
+
187
+ This matches `SP1ProofHooks.computePaymentCommitment` on-chain.
61
188
 
62
189
  ## Exit Codes (CLI)
63
190
 
@@ -68,14 +195,75 @@ curl -s https://api.chit402.com/receipt/task-123?format=json | npx chit402-verif
68
195
  | 2 | Partial (binding ok, nullifier not checked) |
69
196
  | 3 | Input error |
70
197
 
71
- ## Publish
198
+ `unsupported_version` uses exit 1. No flag (`--check-payer`, `--rpc`, `--fetch-jwks`, `--no-issuer-history`, `--no-preimage`, `--no-trusted-kid`, `--accept-shell`) turns an unknown version into a pass. The check runs before any chain RPC.
199
+
200
+ ## Receipt versions
201
+
202
+ The signed JWS payload is the version. It is an exact JSON number. Strings, booleans, arrays, null, and non-integers are `unsupported_version`. `11.0` and `1.1e1` are the number 11.
203
+
204
+ | Signed field | Accepted |
205
+ |---|---|
206
+ | `v` | `11`, and the claims must not contain `payload_version` |
207
+ | `payload_version` | integers `1` through `10`, and `11` only when `issuer_root` is signed |
208
+ | refusal `payload_version` | integers `1`, `2`, `3` |
209
+ | neither field | outer version `4` or `5`, and no field introduced at v6 or later (`version_source: inferred`) |
210
+
211
+ An outer `v` or `issuer_signature.payload_version` that differs in value or type is `version_mismatch`. A `v` or `payload_version` in the JWS protected header is ignored.
212
+
213
+ Receipts issued after 2026-10-08 require `@xfuel/verify` >= 0.3.5. Older versions may print VERIFIED for formats they do not understand. `--help` and `--version` print this list.
214
+
215
+ ## API Reference
216
+
217
+ ### `verifyBinding(receipt)`
72
218
 
73
- `publishConfig` sets `access` to `public` and does not name an owner. On the registry, `chit402-verify` (latest `0.2.0`) and `@xfuel/verify` (latest `0.2.1`) are both maintained by the npm user `xfuel`. Publish `@xfuel/verify` first. `npm whoami` must print `xfuel`. A `404` on `PUT https://registry.npmjs.org/chit402-verify` is that login, not a missing package and not a new scope: the name already exists.
219
+ Verify payment binding locally. Returns:
220
+
221
+ ```typescript
222
+ {
223
+ verified: boolean;
224
+ expected: string | null;
225
+ recomputed: string | null;
226
+ matches: boolean;
227
+ covers: string[];
228
+ reason?: string;
229
+ }
230
+ ```
231
+
232
+ ### `verifyNullifier(receipt, options?)`
233
+
234
+ Verify nullifier is anchored on-chain. Requires network access.
235
+
236
+ ```typescript
237
+ {
238
+ verified: boolean;
239
+ nullifier: string | null;
240
+ anchored: boolean | null;
241
+ reason?: string;
242
+ }
243
+ ```
244
+
245
+ ### `verifyReceipt(receipt, options?)`
246
+
247
+ Full verification combining binding and optional nullifier check.
248
+
249
+ ```typescript
250
+ {
251
+ receipt_id: string;
252
+ binding: BindingVerification;
253
+ nullifier: NullifierVerification;
254
+ output_hash: string | null;
255
+ hub: string | null;
256
+ model: string | null;
257
+ amount_usdc: string | null;
258
+ tx: string | null;
259
+ overall: 'verified' | 'partial' | 'failed';
260
+ errors: string[];
261
+ }
262
+ ```
74
263
 
75
- ## Documentation
264
+ ## Build digest
76
265
 
77
- - [Chit402 Docs](https://chit402.com)
78
- - [API Reference](https://api.chit402.com)
266
+ `npm run digest` writes `BUILD_DIGEST.txt`. That file is the SHA-256 of the sorted `src/**/*.ts` listing, not a bit-reproducible `tsc` binary. The same sources produce the same digest. The receipt-tree genesis leaf copies this digest so a holder can see which verifier source the issuer vouches for. It does not prove the process that served the receipt ran that exact binary.
79
267
 
80
268
  ## License
81
269
 
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Bind an anchored tree head to the issuer.
3
+ *
4
+ * Anchor mode trusts a head only when its ES256 `issuer_signature` verifies
5
+ * under the same rules as a receipt: a JWKS key matched by kid, an embedded
6
+ * key whose RFC 7638 thumbprint is a pinned kid, or a kid in a verified
7
+ * issuer-history document. The signed payload must match the outer fields
8
+ * the anchor check uses.
9
+ *
10
+ * The Base sender and the Solana fee payer in that payload must be on the
11
+ * issuer's anchor-wallet list, and the transactions the RPC returns must
12
+ * have been sent by those wallets.
13
+ *
14
+ * The list is the package pin, plus wallets inside a verified
15
+ * `chit402.anchor_wallets.v1` document or a verified issuer-history
16
+ * payload's `anchor_wallets`. Two later sources are named and not read:
17
+ * the Base `ChitIssuerRoot` registry (draft #485) and the DNS TXT at
18
+ * `_issuer.chit402.com`. This module does not embed a registry address
19
+ * and does not resolve DNS.
20
+ */
21
+ import { type Es256Jwk } from './jws.js';
22
+ import { type IssuerHistoryDocument } from './issuer-history.js';
23
+ /** Confirmed sender of Base tx 0x1d8d7ea255170c8d4b87bef9382e13555dded2072fd877ce35f995f1ab54ee09. */
24
+ export declare const PINNED_BASE_ANCHOR_WALLET = "0x1844D1F5FE42aff1Cce6F776514Fd40374079582";
25
+ /** Fee payer of Solana memo 61RHMsPPseUc35v5oxDEtANEDCvXk5fmxZdrFDMknGWc5m7U8YhMfz4En1eFFj3z9n67ZtMiha1zkwnneL2LUiXk. */
26
+ export declare const PINNED_SOLANA_ANCHOR_FEE_PAYER = "BHTnbPu6UZ7zQZ7Qpkpz4LcUQbMN73YDsMtvaNXpEioD";
27
+ /** A head signed before `anchors.base.from` and `anchors.solana.fee_payer` existed. Never VERIFIED. */
28
+ export declare const LEGACY_HEAD_UNPINNED_SIGNER = "LEGACY_HEAD_UNPINNED_SIGNER";
29
+ export declare const ANCHOR_WALLETS_SCHEMA = "chit402.anchor_wallets.v1";
30
+ export declare const ANCHOR_WALLETS_JWT_TYP = "chit402-anchor-wallets+jwt";
31
+ /** Sources this version does not query. A later build can fill the same list. */
32
+ export declare const ANCHOR_WALLET_SOURCES_NOT_CONSULTED: readonly ["issuer_root", "dns"];
33
+ export declare const HEAD_TRUST_MESSAGES: Record<string, string>;
34
+ interface JwksLike {
35
+ keys?: Es256Jwk[];
36
+ }
37
+ export interface TreeHeadDocument {
38
+ schema?: string;
39
+ payload_version?: number;
40
+ root?: string | null;
41
+ tree_size?: number | null;
42
+ epoch?: number | null;
43
+ prev_epoch_root?: string | null;
44
+ prev_epoch_size?: number | null;
45
+ published_at?: string | null;
46
+ anchors?: {
47
+ base?: {
48
+ status?: string | null;
49
+ tx?: string | null;
50
+ calldata?: string | null;
51
+ chain_id?: number | null;
52
+ from?: string | null;
53
+ } | null;
54
+ solana?: {
55
+ status?: string | null;
56
+ signature?: string | null;
57
+ slot?: number | null;
58
+ cluster?: string | null;
59
+ memo?: string | null;
60
+ fee_payer?: string | null;
61
+ } | null;
62
+ } | null;
63
+ issuer_signature?: {
64
+ jws?: string;
65
+ kid?: string;
66
+ issuer_jwk?: Es256Jwk;
67
+ };
68
+ }
69
+ export interface HeadTrustResult {
70
+ ok: boolean;
71
+ reason: string | null;
72
+ message: string | null;
73
+ kid: string | null;
74
+ trust: 'jwks' | 'pinned_kid' | 'issuer_history' | null;
75
+ payload: Record<string, unknown> | null;
76
+ }
77
+ export interface AnchorWalletList {
78
+ base: string[];
79
+ solana: string[];
80
+ sources: Array<'pin' | 'well_known' | 'issuer_history'>;
81
+ not_consulted: readonly ['issuer_root', 'dns'];
82
+ }
83
+ /**
84
+ * True when a verified head anchors a chain but the signature does not name
85
+ * that chain's signer. Those fields were added after the epoch-1 head and
86
+ * after the epoch-2 head signed at 07:43 ET on 2026-10-07. A pending side
87
+ * is not this case.
88
+ */
89
+ export declare function headOmitsPinnedSigner(payload: Record<string, unknown> | null | undefined): boolean;
90
+ /** Signed payload must carry the same root, size, epoch, and anchors the check uses. */
91
+ export declare function headClaimsMatch(outer: TreeHeadDocument, payload: Record<string, unknown>): string | null;
92
+ export declare function verifyTreeHeadTrust(head: TreeHeadDocument | null | undefined, { jwks, trustedKids, issuerHistory, strictIssuerHistory, }?: {
93
+ jwks?: JwksLike;
94
+ trustedKids?: readonly string[];
95
+ issuerHistory?: IssuerHistoryDocument | null;
96
+ strictIssuerHistory?: boolean;
97
+ }): HeadTrustResult;
98
+ /**
99
+ * Named inclusion head. The gateway summary is `{ root, tree_size, signature }`
100
+ * and is not a tree-head document, so `headClaimsMatch` cannot run on it.
101
+ * Trust the JWS under JWKS or a pinned kid first, then use the verified
102
+ * payload as the head. A key carried on the summary is ignored unless that
103
+ * key is pinned. The summary root and size, when present, must match the payload.
104
+ * Returns null when the JWS is missing or untrusted: the caller must not
105
+ * treat the summary as a head.
106
+ */
107
+ export declare function headTrustedFromInclusion(inclusion: {
108
+ head?: unknown;
109
+ } | null | undefined, { jwks, trustedKids, }?: {
110
+ jwks?: JwksLike;
111
+ trustedKids?: readonly string[];
112
+ }): TreeHeadDocument | null;
113
+ export declare function verifyAnchorWalletDocument(doc: {
114
+ schema?: string;
115
+ base?: unknown;
116
+ solana?: unknown;
117
+ issuer_signature?: {
118
+ jws?: string;
119
+ issuer_jwk?: Es256Jwk;
120
+ };
121
+ } | null | undefined, { jwks, trustedKids }?: {
122
+ jwks?: JwksLike;
123
+ trustedKids?: readonly string[];
124
+ }): {
125
+ ok: true;
126
+ base: string[];
127
+ solana: string[];
128
+ } | {
129
+ ok: false;
130
+ reason: string;
131
+ };
132
+ export declare function compileAnchorWallets({ jwks, trustedKids, issuerHistory, published, }?: {
133
+ jwks?: JwksLike;
134
+ trustedKids?: readonly string[];
135
+ issuerHistory?: IssuerHistoryDocument | null;
136
+ published?: {
137
+ base: string[];
138
+ solana: string[];
139
+ } | null;
140
+ }): AnchorWalletList;
141
+ export declare function walletListed(list: readonly string[], value: string, chain: 'base' | 'solana'): boolean;
142
+ export declare function sameBaseAddress(left: string, right: string): boolean;
143
+ export {};
144
+ //# sourceMappingURL=anchor-trust.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anchor-trust.d.ts","sourceRoot":"","sources":["../src/anchor-trust.ts"],"names":[],"mappings":"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"}