zklicensing 0.1.0-beta.2 → 0.1.0-beta.21
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/README.md +417 -201
- package/build/agent.d.ts +371 -0
- package/build/agent.d.ts.map +1 -0
- package/build/agent.js +553 -0
- package/build/agent.js.map +1 -0
- package/build/agentActions.d.ts +841 -0
- package/build/agentActions.d.ts.map +1 -0
- package/build/agentActions.js +581 -0
- package/build/agentActions.js.map +1 -0
- package/build/agentRecord.d.ts +83 -0
- package/build/agentRecord.d.ts.map +1 -0
- package/build/agentRecord.js +69 -0
- package/build/agentRecord.js.map +1 -0
- package/build/agentVendor.d.ts +220 -0
- package/build/agentVendor.d.ts.map +1 -0
- package/build/agentVendor.js +306 -0
- package/build/agentVendor.js.map +1 -0
- package/build/appsLookup.d.ts +14 -0
- package/build/appsLookup.d.ts.map +1 -0
- package/build/appsLookup.js +12 -0
- package/build/appsLookup.js.map +1 -0
- package/build/archiveBootstrap.d.ts +31 -5
- package/build/archiveBootstrap.d.ts.map +1 -0
- package/build/archiveBootstrap.js +140 -47
- package/build/archiveBootstrap.js.map +1 -0
- package/build/atomicJson.d.ts +5 -0
- package/build/atomicJson.d.ts.map +1 -0
- package/build/atomicJson.js +55 -0
- package/build/atomicJson.js.map +1 -0
- package/build/bindClient.d.ts +85 -0
- package/build/bindClient.d.ts.map +1 -0
- package/build/bindClient.js +187 -0
- package/build/bindClient.js.map +1 -0
- package/build/buyClient.d.ts +27 -4
- package/build/buyClient.d.ts.map +1 -0
- package/build/buyClient.js +72 -26
- package/build/buyClient.js.map +1 -0
- package/build/chainHead.d.ts +61 -0
- package/build/chainHead.d.ts.map +1 -0
- package/build/chainHead.js +88 -0
- package/build/chainHead.js.map +1 -0
- package/build/compactMerkleMap.d.ts +72 -0
- package/build/compactMerkleMap.d.ts.map +1 -0
- package/build/compactMerkleMap.js +224 -0
- package/build/compactMerkleMap.js.map +1 -0
- package/build/contractInterface.d.ts +191 -51
- package/build/contractInterface.d.ts.map +1 -0
- package/build/contractInterface.js +234 -43
- package/build/contractInterface.js.map +1 -0
- package/build/contractTypes.d.ts +9 -0
- package/build/contractTypes.d.ts.map +1 -0
- package/build/contractTypes.js +28 -0
- package/build/contractTypes.js.map +1 -0
- package/build/countryStats.d.ts +12 -3
- package/build/countryStats.d.ts.map +1 -0
- package/build/countryStats.js +87 -23
- package/build/countryStats.js.map +1 -0
- package/build/deployClient.d.ts +138 -24
- package/build/deployClient.d.ts.map +1 -0
- package/build/deployClient.js +91 -31
- package/build/deployClient.js.map +1 -0
- package/build/deviceIdentity.d.ts +68 -0
- package/build/deviceIdentity.d.ts.map +1 -0
- package/build/deviceIdentity.js +209 -0
- package/build/deviceIdentity.js.map +1 -0
- package/build/freezeClient.d.ts +26 -6
- package/build/freezeClient.d.ts.map +1 -0
- package/build/freezeClient.js +30 -6
- package/build/freezeClient.js.map +1 -0
- package/build/generationClient.d.ts +6 -3
- package/build/generationClient.d.ts.map +1 -0
- package/build/generationClient.js +25 -38
- package/build/generationClient.js.map +1 -0
- package/build/holderSecret.d.ts +70 -0
- package/build/holderSecret.d.ts.map +1 -0
- package/build/holderSecret.js +76 -0
- package/build/holderSecret.js.map +1 -0
- package/build/index.d.ts +38 -38
- package/build/index.d.ts.map +1 -0
- package/build/index.js +97 -121
- package/build/index.js.map +1 -0
- package/build/keysClient.d.ts +142 -0
- package/build/keysClient.d.ts.map +1 -0
- package/build/keysClient.js +109 -0
- package/build/keysClient.js.map +1 -0
- package/build/licenseLeaf.d.ts +76 -0
- package/build/licenseLeaf.d.ts.map +1 -0
- package/build/licenseLeaf.js +189 -0
- package/build/licenseLeaf.js.map +1 -0
- package/build/licenseRecord.d.ts +68 -5
- package/build/licenseRecord.d.ts.map +1 -0
- package/build/licenseRecord.js +26 -1
- package/build/licenseRecord.js.map +1 -0
- package/build/licenseStore.d.ts +81 -4
- package/build/licenseStore.d.ts.map +1 -0
- package/build/licenseStore.js +400 -30
- package/build/licenseStore.js.map +1 -0
- package/build/licenseTrustless.d.ts +43 -0
- package/build/licenseTrustless.d.ts.map +1 -0
- package/build/licenseTrustless.js +180 -0
- package/build/licenseTrustless.js.map +1 -0
- package/build/manifestVerify.d.ts +29 -1
- package/build/manifestVerify.d.ts.map +1 -0
- package/build/manifestVerify.js +46 -4
- package/build/manifestVerify.js.map +1 -0
- package/build/minaPriceHistory.d.ts +9 -0
- package/build/minaPriceHistory.d.ts.map +1 -0
- package/build/minaPriceHistory.js +152 -0
- package/build/minaPriceHistory.js.map +1 -0
- package/build/onChainRoot.d.ts +60 -0
- package/build/onChainRoot.d.ts.map +1 -0
- package/build/onChainRoot.js +74 -0
- package/build/onChainRoot.js.map +1 -0
- package/build/ownershipLicenseHash.d.ts +25 -0
- package/build/ownershipLicenseHash.d.ts.map +1 -0
- package/build/ownershipLicenseHash.js +29 -0
- package/build/ownershipLicenseHash.js.map +1 -0
- package/build/ownershipSignature.d.ts +153 -0
- package/build/ownershipSignature.d.ts.map +1 -0
- package/build/ownershipSignature.js +297 -0
- package/build/ownershipSignature.js.map +1 -0
- package/build/permitCheckFlow.d.ts +155 -0
- package/build/permitCheckFlow.d.ts.map +1 -0
- package/build/permitCheckFlow.js +196 -0
- package/build/permitCheckFlow.js.map +1 -0
- package/build/permitDescribe.d.ts +124 -0
- package/build/permitDescribe.d.ts.map +1 -0
- package/build/permitDescribe.js +324 -0
- package/build/permitDescribe.js.map +1 -0
- package/build/permitInterface.d.ts +85 -0
- package/build/permitInterface.d.ts.map +1 -0
- package/build/permitInterface.js +121 -0
- package/build/permitInterface.js.map +1 -0
- package/build/permitMessages.d.ts +313 -0
- package/build/permitMessages.d.ts.map +1 -0
- package/build/permitMessages.js +462 -0
- package/build/permitMessages.js.map +1 -0
- package/build/permitProof.d.ts +108 -0
- package/build/permitProof.d.ts.map +1 -0
- package/build/permitProof.js +202 -0
- package/build/permitProof.js.map +1 -0
- package/build/permitRegistryRebuild.d.ts +166 -0
- package/build/permitRegistryRebuild.d.ts.map +1 -0
- package/build/permitRegistryRebuild.js +347 -0
- package/build/permitRegistryRebuild.js.map +1 -0
- package/build/permitTree.d.ts +88 -0
- package/build/permitTree.d.ts.map +1 -0
- package/build/permitTree.js +230 -0
- package/build/permitTree.js.map +1 -0
- package/build/permitsClient.d.ts +680 -0
- package/build/permitsClient.d.ts.map +1 -0
- package/build/permitsClient.js +597 -0
- package/build/permitsClient.js.map +1 -0
- package/build/proveErrors.d.ts +50 -0
- package/build/proveErrors.d.ts.map +1 -0
- package/build/proveErrors.js +76 -0
- package/build/proveErrors.js.map +1 -0
- package/build/receipt.d.ts +95 -0
- package/build/receipt.d.ts.map +1 -0
- package/build/receipt.js +84 -0
- package/build/receipt.js.map +1 -0
- package/build/refundClient.d.ts +7 -12
- package/build/refundClient.d.ts.map +1 -0
- package/build/refundClient.js +52 -21
- package/build/refundClient.js.map +1 -0
- package/build/registryTrustVerify.d.ts +78 -0
- package/build/registryTrustVerify.d.ts.map +1 -0
- package/build/registryTrustVerify.js +129 -0
- package/build/registryTrustVerify.js.map +1 -0
- package/build/releaseClient.d.ts +26 -0
- package/build/releaseClient.d.ts.map +1 -0
- package/build/releaseClient.js +65 -0
- package/build/releaseClient.js.map +1 -0
- package/build/renewClient.d.ts +28 -2
- package/build/renewClient.d.ts.map +1 -0
- package/build/renewClient.js +31 -27
- package/build/renewClient.js.map +1 -0
- package/build/seatName.d.ts +8 -0
- package/build/seatName.d.ts.map +1 -0
- package/build/seatName.js +136 -0
- package/build/seatName.js.map +1 -0
- package/build/slotConstants.d.ts +15 -0
- package/build/slotConstants.d.ts.map +1 -0
- package/build/slotConstants.js +17 -0
- package/build/slotConstants.js.map +1 -0
- package/build/statsClient.d.ts +61 -7
- package/build/statsClient.d.ts.map +1 -0
- package/build/statsClient.js +44 -5
- package/build/statsClient.js.map +1 -0
- package/build/successorChain.d.ts +35 -0
- package/build/successorChain.d.ts.map +1 -0
- package/build/successorChain.js +69 -0
- package/build/successorChain.js.map +1 -0
- package/build/taxId.d.ts +44 -0
- package/build/taxId.d.ts.map +1 -0
- package/build/taxId.js +212 -0
- package/build/taxId.js.map +1 -0
- package/build/trustAnchorVerify.d.ts +49 -0
- package/build/trustAnchorVerify.d.ts.map +1 -0
- package/build/trustAnchorVerify.js +432 -0
- package/build/trustAnchorVerify.js.map +1 -0
- package/build/trustAnchorVerifyCli.d.ts +45 -0
- package/build/trustAnchorVerifyCli.d.ts.map +1 -0
- package/build/trustAnchorVerifyCli.js +235 -0
- package/build/trustAnchorVerifyCli.js.map +1 -0
- package/build/txBroadcastClient.d.ts +26 -0
- package/build/txBroadcastClient.d.ts.map +1 -0
- package/build/txBroadcastClient.js +20 -0
- package/build/txBroadcastClient.js.map +1 -0
- package/build/unbindClient.d.ts +77 -0
- package/build/unbindClient.d.ts.map +1 -0
- package/build/unbindClient.js +169 -0
- package/build/unbindClient.js.map +1 -0
- package/build/units.d.ts +28 -0
- package/build/units.d.ts.map +1 -0
- package/build/units.js +65 -0
- package/build/units.js.map +1 -0
- package/build/vatRates.d.ts +54 -0
- package/build/vatRates.d.ts.map +1 -0
- package/build/vatRates.js +82 -0
- package/build/vatRates.js.map +1 -0
- package/build/vatRatesData.d.ts +5 -0
- package/build/vatRatesData.d.ts.map +1 -0
- package/build/vatRatesData.js +42 -0
- package/build/vatRatesData.js.map +1 -0
- package/build/vendorAccountClient.d.ts +66 -0
- package/build/vendorAccountClient.d.ts.map +1 -0
- package/build/vendorAccountClient.js +47 -0
- package/build/vendorAccountClient.js.map +1 -0
- package/build/verifyCore.d.ts +4 -1
- package/build/verifyCore.d.ts.map +1 -0
- package/build/verifyCore.js +21 -10
- package/build/verifyCore.js.map +1 -0
- package/build/verifyOffline.d.ts +85 -0
- package/build/verifyOffline.d.ts.map +1 -0
- package/build/verifyOffline.js +139 -0
- package/build/verifyOffline.js.map +1 -0
- package/build/verifyService.d.ts.map +1 -0
- package/build/verifyService.js +571 -501
- package/build/verifyService.js.map +1 -0
- package/build/verifyWithAncestors.d.ts +19 -0
- package/build/verifyWithAncestors.d.ts.map +1 -0
- package/build/verifyWithAncestors.js +127 -0
- package/build/verifyWithAncestors.js.map +1 -0
- package/build/zipToState.d.ts +2 -0
- package/build/zipToState.d.ts.map +1 -0
- package/build/zipToState.js +94 -0
- package/build/zipToState.js.map +1 -0
- package/package.json +141 -16
- package/src/agent.ts +682 -0
- package/src/agentActions.ts +637 -0
- package/src/agentRecord.ts +121 -0
- package/src/agentVendor.ts +356 -0
- package/src/appsLookup.ts +48 -0
- package/src/archiveBootstrap.ts +386 -0
- package/src/atomicJson.ts +53 -0
- package/src/bindClient.ts +297 -0
- package/src/buyClient.ts +344 -0
- package/src/chainHead.ts +106 -0
- package/src/compactMerkleMap.ts +222 -0
- package/src/contractInterface.ts +465 -0
- package/src/contractTypes.ts +31 -0
- package/src/countryStats.ts +200 -0
- package/src/deployClient.ts +517 -0
- package/src/deviceIdentity.ts +249 -0
- package/src/freezeClient.ts +162 -0
- package/src/generationClient.ts +145 -0
- package/src/holderSecret.ts +91 -0
- package/src/index.ts +362 -0
- package/src/keysClient.ts +135 -0
- package/src/licenseLeaf.ts +221 -0
- package/src/licenseRecord.ts +190 -0
- package/src/licenseStore.ts +767 -0
- package/src/licenseTrustless.ts +207 -0
- package/src/manifestVerify.ts +164 -0
- package/src/minaPriceHistory.ts +166 -0
- package/src/onChainRoot.ts +90 -0
- package/src/ownershipLicenseHash.ts +31 -0
- package/src/ownershipSignature.ts +421 -0
- package/src/permitCheckFlow.ts +227 -0
- package/src/permitDescribe.ts +362 -0
- package/src/permitInterface.ts +146 -0
- package/src/permitMessages.ts +572 -0
- package/src/permitProof.ts +230 -0
- package/src/permitRegistryRebuild.ts +423 -0
- package/src/permitTree.ts +232 -0
- package/src/permitsClient.ts +746 -0
- package/src/proveErrors.ts +98 -0
- package/src/receipt.ts +156 -0
- package/src/refundClient.ts +177 -0
- package/src/registryTrustVerify.ts +192 -0
- package/src/releaseClient.ts +101 -0
- package/src/renewClient.ts +234 -0
- package/src/seatName.ts +165 -0
- package/src/slotConstants.ts +18 -0
- package/src/statsClient.ts +249 -0
- package/src/successorChain.ts +87 -0
- package/src/taxId.ts +227 -0
- package/src/trustAnchorVerify.ts +550 -0
- package/src/trustAnchorVerifyCli.ts +234 -0
- package/src/txBroadcastClient.ts +48 -0
- package/src/unbindClient.ts +233 -0
- package/src/units.ts +74 -0
- package/src/vatRates.ts +100 -0
- package/src/vatRatesData.ts +43 -0
- package/src/vendorAccountClient.ts +120 -0
- package/src/verifyCore.ts +100 -0
- package/src/verifyOffline.ts +212 -0
- package/src/verifyService.ts +982 -0
- package/src/verifyWithAncestors.ts +163 -0
- package/src/zipToState.ts +94 -0
- package/build/licenseProof.d.ts +0 -26
- package/build/licenseProof.js +0 -41
- package/build/migrateClient.d.ts +0 -43
- package/build/migrateClient.js +0 -47
- package/build/ownership.d.ts +0 -34
- package/build/ownership.js +0 -147
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
// Copyright (c) 2025-2026 zkLicensing project developers
|
|
2
|
+
// SPDX-License-Identifier: BUSL-1.1
|
|
3
|
+
/**
|
|
4
|
+
* trustAnchorVerify.ts
|
|
5
|
+
*
|
|
6
|
+
* End-to-end trust-anchor verification for a single zkLicensing app.
|
|
7
|
+
*
|
|
8
|
+
* Given a vendor origin + a zkApp address + one or more pinned platform
|
|
9
|
+
* manifest public keys, this module performs the full "does this vendor
|
|
10
|
+
* page point at a real zkLicensing deployment for this vendor?" pipeline
|
|
11
|
+
* that the trust-anchor page walks a human buyer through — mechanically,
|
|
12
|
+
* with structured findings suitable for CI, monitoring, or a
|
|
13
|
+
* wallet/extension consumer.
|
|
14
|
+
*
|
|
15
|
+
* The verifier is address-keyed: buyers see zkApp addresses in their
|
|
16
|
+
* wallet popup, not opaque platform appIds, so the primary lookup is by
|
|
17
|
+
* address. The signed manifest served at
|
|
18
|
+
* `<origin>/.well-known/zklicensing/<zkAppAddress>.json` carries the
|
|
19
|
+
* appId inside its signed payload, so callers never need to know the
|
|
20
|
+
* appId out-of-band.
|
|
21
|
+
*
|
|
22
|
+
* Pipeline (each step yields a discrete Finding — no boolean collapse):
|
|
23
|
+
*
|
|
24
|
+
* 1. manifest_fetch — GET https://<origin>/.well-known/zklicensing/<address>.json
|
|
25
|
+
* 2. manifest_signature — Ed25519 verify against caller-provided pinned keys
|
|
26
|
+
* (any of the manifest's signatures: during a platform
|
|
27
|
+
* key rotation it carries the old and the new key's)
|
|
28
|
+
* 2b. manifest_network — signed for the network being checked (minaNetworkId)
|
|
29
|
+
* 3. manifest_address_in_generations — opts.address appears in the signed generations[]
|
|
30
|
+
* 3b. manifest_matches_backend — (opt-in, opts.crossCheck) vendor payload equals
|
|
31
|
+
* zklicensing.com/apps/by-address/<address> after
|
|
32
|
+
* independent signature-verify against same pins
|
|
33
|
+
* 4. chain_account_exists — fetchAccount succeeds at the address
|
|
34
|
+
* 5. chain_zkapp_uri_match — on-chain zkappUri equals opts.origin
|
|
35
|
+
* 6. chain_vk_hash_pinned — on-chain verification-key hash equals CANONICAL_VK_HASHES[generation]
|
|
36
|
+
* 7. chain_set_zkapp_uri_impossible — permissions.setZkappUri === Permissions.impossible()
|
|
37
|
+
* 8. chain_set_permissions_impossible — permissions.setPermissions === Permissions.impossible() (meta-freeze)
|
|
38
|
+
* 9. chain_set_verification_key_locked — permissions.setVerificationKey.auth === Permissions.impossible()
|
|
39
|
+
* 10. chain_send_proof_only — permissions.send === Permissions.proof()
|
|
40
|
+
* 11. chain_edit_state_proof_only — permissions.editState === Permissions.proof()
|
|
41
|
+
*
|
|
42
|
+
* Steps 5 + 7 close the URI-binding loop: (5) proves the contract claims
|
|
43
|
+
* this origin, (7) proves nobody can rewrite that claim. Steps 8–11 verify
|
|
44
|
+
* the rest of LicensingApp.init()'s permission matrix — catching the case
|
|
45
|
+
* where a deployer used the correct VK but skipped/altered init(), leaving
|
|
46
|
+
* default `signature()` permissions that would still let the deploy key
|
|
47
|
+
* drain escrow, rewrite state, or swap the circuit.
|
|
48
|
+
*
|
|
49
|
+
* Chain reads go to the Mina node's GraphQL API directly (chainHead.ts):
|
|
50
|
+
* no o1js is needed, and o1js's global Mina instance is never switched, so
|
|
51
|
+
* long-lived services can run the check concurrently.
|
|
52
|
+
*
|
|
53
|
+
* The pinned pubkey list is caller-supplied — the SDK ships NO baked-in
|
|
54
|
+
* pin. Source it from https://zklicensing.com/trustanchor.html (published
|
|
55
|
+
* next to each generation's VK hash). See the SDK README for details.
|
|
56
|
+
*/
|
|
57
|
+
import { canonicalize, manifestSignaturesOf, signedManifestOf, verifyManifestSignature } from './manifestVerify.js';
|
|
58
|
+
// The zkLicensing backend is mounted under /api/keeper on zklicensing.com —
|
|
59
|
+
// the bare /apps/... paths return 404 (they're not the app route, they're an
|
|
60
|
+
// unrelated marketing route). This is the concrete URL prefix, not just an
|
|
61
|
+
// origin. The `/api/keeper` path is a stable public route and must not be
|
|
62
|
+
// renamed here.
|
|
63
|
+
const BACKEND_URL_PREFIX = 'https://zklicensing.com/api/keeper';
|
|
64
|
+
const DEFAULT_FETCH_TIMEOUT_MS = 15000;
|
|
65
|
+
function normalizeOrigin(origin) {
|
|
66
|
+
return origin.replace(/\/+$/, '');
|
|
67
|
+
}
|
|
68
|
+
// Strip trailing slash / path from a URL so we can compare against zkappUri,
|
|
69
|
+
// which vendors typically set to their bare origin.
|
|
70
|
+
function urlOrigin(url) {
|
|
71
|
+
try {
|
|
72
|
+
const u = new URL(url);
|
|
73
|
+
return `${u.protocol}//${u.host}`;
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
async function fetchManifest(origin, address, timeoutMs) {
|
|
80
|
+
const originOk = origin.startsWith('https://');
|
|
81
|
+
if (!originOk) {
|
|
82
|
+
return { name: 'manifest_fetch', ok: false, detail: 'origin must be https://' };
|
|
83
|
+
}
|
|
84
|
+
let manifestUrl;
|
|
85
|
+
try {
|
|
86
|
+
manifestUrl = new URL(`/.well-known/zklicensing/${encodeURIComponent(address)}.json`, origin).href;
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return { name: 'manifest_fetch', ok: false, detail: 'origin is not a valid URL' };
|
|
90
|
+
}
|
|
91
|
+
const controller = new AbortController();
|
|
92
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
93
|
+
try {
|
|
94
|
+
const resp = await fetch(manifestUrl, { signal: controller.signal, redirect: 'follow' });
|
|
95
|
+
if (!resp.ok) {
|
|
96
|
+
return { name: 'manifest_fetch', ok: false, detail: `HTTP ${resp.status} from ${manifestUrl}` };
|
|
97
|
+
}
|
|
98
|
+
const text = await resp.text();
|
|
99
|
+
let parsed;
|
|
100
|
+
try {
|
|
101
|
+
parsed = JSON.parse(text);
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return { name: 'manifest_fetch', ok: false, detail: 'response is not valid JSON' };
|
|
105
|
+
}
|
|
106
|
+
return { name: 'manifest_fetch', ok: true, detail: `fetched ${manifestUrl}`, body: parsed };
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
return { name: 'manifest_fetch', ok: false, detail: `fetch failed: ${err?.message ?? String(err)}` };
|
|
110
|
+
}
|
|
111
|
+
finally {
|
|
112
|
+
clearTimeout(timer);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// Split a raw manifest JSON into { signature, payload }. The backend writes the
|
|
116
|
+
// payload fields at the top level plus { signature, publicKey } — we ignore
|
|
117
|
+
// publicKey (never trust the payload's self-declared key; only the
|
|
118
|
+
// caller-pinned list is authoritative). The same signed bytes are served at
|
|
119
|
+
// every /.well-known/zklicensing/<address>.json — one file per generation
|
|
120
|
+
// address, all carrying the same appId in the payload.
|
|
121
|
+
//
|
|
122
|
+
// We whitelist the signed fields (appId, current, generations, issuedAt)
|
|
123
|
+
// rather than blacklist non-signed ones. The backend appends advisory
|
|
124
|
+
// fields (e.g. `forkActivationSlot`) to the response AFTER signing, so a
|
|
125
|
+
// blacklist misses them and canonicalize() then hashes bytes the signer
|
|
126
|
+
// never saw — the signature never verifies.
|
|
127
|
+
function splitManifest(raw) {
|
|
128
|
+
const payload = signedManifestOf(raw);
|
|
129
|
+
return { signatures: manifestSignaturesOf(raw), payload };
|
|
130
|
+
}
|
|
131
|
+
/** True when one of `signatures` verifies over `payload` against a pinned key. */
|
|
132
|
+
async function anySignatureVerifies(payload, signatures, pinned) {
|
|
133
|
+
for (const sig of signatures)
|
|
134
|
+
if (await verifyManifestSignature(payload, sig, pinned))
|
|
135
|
+
return true;
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
// Optional cross-check against the zkLicensing backend's own copy of the
|
|
139
|
+
// signed generation list. Fetches `https://zklicensing.com/apps/by-address/
|
|
140
|
+
// {address}`, verifies its signature against the same caller-pinned keys (so
|
|
141
|
+
// a compromised backend URL cannot lie), strips signature/publicKey/issuedAt/
|
|
142
|
+
// app/network, and byte-compares canonicalized payloads against the vendor's
|
|
143
|
+
// `.well-known` copy. `issuedAt` is stripped because the backend re-stamps on
|
|
144
|
+
// every call; `app` and `network` are stripped because they are unsigned
|
|
145
|
+
// envelope fields the by-address endpoint tacks on.
|
|
146
|
+
async function checkBackendMatch(args) {
|
|
147
|
+
const name = 'manifest_matches_backend';
|
|
148
|
+
const url = `${BACKEND_URL_PREFIX}/apps/by-address/${encodeURIComponent(args.address)}`;
|
|
149
|
+
const controller = new AbortController();
|
|
150
|
+
const timer = setTimeout(() => controller.abort(), args.timeoutMs);
|
|
151
|
+
let body;
|
|
152
|
+
try {
|
|
153
|
+
const resp = await fetch(url, { signal: controller.signal, redirect: 'follow' });
|
|
154
|
+
if (!resp.ok)
|
|
155
|
+
return { name, ok: false, detail: `backend HTTP ${resp.status} from ${url}` };
|
|
156
|
+
body = await resp.json();
|
|
157
|
+
}
|
|
158
|
+
catch (err) {
|
|
159
|
+
return { name, ok: false, detail: `backend fetch failed: ${err?.message ?? String(err)}` };
|
|
160
|
+
}
|
|
161
|
+
finally {
|
|
162
|
+
clearTimeout(timer);
|
|
163
|
+
}
|
|
164
|
+
if (!body || typeof body !== 'object') {
|
|
165
|
+
return { name, ok: false, detail: 'backend response is not a JSON object' };
|
|
166
|
+
}
|
|
167
|
+
// Only the signed fields (same reason as splitManifest above): the backend
|
|
168
|
+
// appends envelope fields (publicKey, app, forkActivationSlot) after signing.
|
|
169
|
+
const backendSignatures = manifestSignaturesOf(body);
|
|
170
|
+
if (!backendSignatures.length) {
|
|
171
|
+
return { name, ok: false, detail: 'backend response missing signature' };
|
|
172
|
+
}
|
|
173
|
+
const backendPayload = signedManifestOf(body);
|
|
174
|
+
if (!backendPayload) {
|
|
175
|
+
return { name, ok: false, detail: 'backend response missing signed fields' };
|
|
176
|
+
}
|
|
177
|
+
if (!await anySignatureVerifies(backendPayload, backendSignatures, args.pinnedPublicKeysBase64)) {
|
|
178
|
+
return { name, ok: false, detail: 'backend response signature does not verify against pinned keys' };
|
|
179
|
+
}
|
|
180
|
+
const { issuedAt: _kIA, ...kRest } = backendPayload;
|
|
181
|
+
const { issuedAt: _vIA, ...vRest } = args.vendorPayload;
|
|
182
|
+
if (canonicalize(kRest) !== canonicalize(vRest)) {
|
|
183
|
+
return { name, ok: false, detail: 'vendor manifest content diverges from backend record (stale or drifted)' };
|
|
184
|
+
}
|
|
185
|
+
return { name, ok: true, detail: `vendor payload matches backend /apps/by-address/${args.address}` };
|
|
186
|
+
}
|
|
187
|
+
// Converts an o1js-decoded Permission (three booleans) back to its canonical
|
|
188
|
+
// enum string. Mirrors the switch inside o1js's own AuthRequired.toJSON — kept
|
|
189
|
+
// inline because o1js doesn't publicly export it.
|
|
190
|
+
export function permToString(p) {
|
|
191
|
+
const b = (v) => (typeof v?.toBoolean === 'function' ? v.toBoolean() : Boolean(v)) ? 1 : 0;
|
|
192
|
+
const key = `${b(p?.constant)}${b(p?.signatureNecessary)}${b(p?.signatureSufficient)}`;
|
|
193
|
+
switch (key) {
|
|
194
|
+
case '110': return 'Impossible';
|
|
195
|
+
case '101': return 'None';
|
|
196
|
+
case '000': return 'Proof';
|
|
197
|
+
case '011': return 'Signature';
|
|
198
|
+
case '001': return 'Either';
|
|
199
|
+
default: return undefined;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
// Reads the on-chain facts needed to close the trust loop for a single
|
|
203
|
+
// zkApp address, over the node's GraphQL API (no o1js, and no switch of
|
|
204
|
+
// o1js's global Mina instance, so long-lived hosts can call it safely).
|
|
205
|
+
async function readChainState(address, minaGraphqlUrl, _minaNetworkId, fetcher) {
|
|
206
|
+
try {
|
|
207
|
+
const { readZkappAccount } = await import('./chainHead.js');
|
|
208
|
+
const a = await readZkappAccount({ address, graphqlUrl: minaGraphqlUrl, fetcher });
|
|
209
|
+
if (!a.found)
|
|
210
|
+
return { accountFound: false, fetchError: `no account at ${address} via ${minaGraphqlUrl}` };
|
|
211
|
+
const p = a.permissions ?? {};
|
|
212
|
+
return {
|
|
213
|
+
accountFound: true,
|
|
214
|
+
zkappUri: a.zkappUri,
|
|
215
|
+
vkHash: a.vkHash,
|
|
216
|
+
setZkappUriIsImpossible: p.setZkappUri === 'Impossible',
|
|
217
|
+
setPermissionsIsImpossible: p.setPermissions === 'Impossible',
|
|
218
|
+
setVerificationKeyAuth: p.setVerificationKey?.auth,
|
|
219
|
+
setVerificationKeyTxnVersion: p.setVerificationKey?.txnVersion,
|
|
220
|
+
sendIsProof: p.send === 'Proof',
|
|
221
|
+
editStateIsProof: p.editState === 'Proof',
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
catch (err) {
|
|
225
|
+
return { accountFound: false, fetchError: err?.message ?? String(err) };
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
async function loadCanonicalVkHashes() {
|
|
229
|
+
try {
|
|
230
|
+
const m = await import('./contractInterface.js');
|
|
231
|
+
return m.CANONICAL_VK_HASHES ?? null;
|
|
232
|
+
}
|
|
233
|
+
catch {
|
|
234
|
+
return null;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
export async function verifyTrustAnchor(opts) {
|
|
238
|
+
const origin = normalizeOrigin(opts.origin);
|
|
239
|
+
const address = opts.address;
|
|
240
|
+
const findings = [];
|
|
241
|
+
const timeoutMs = opts.fetchTimeoutMs ?? DEFAULT_FETCH_TIMEOUT_MS;
|
|
242
|
+
// 1. manifest_fetch
|
|
243
|
+
const fetchResult = await fetchManifest(origin, address, timeoutMs);
|
|
244
|
+
findings.push({ name: fetchResult.name, ok: fetchResult.ok, detail: fetchResult.detail });
|
|
245
|
+
if (!fetchResult.ok) {
|
|
246
|
+
return { ok: false, origin, address, findings };
|
|
247
|
+
}
|
|
248
|
+
const { signatures, payload } = splitManifest(fetchResult.body);
|
|
249
|
+
// 2. manifest_signature
|
|
250
|
+
if (!signatures.length || !payload) {
|
|
251
|
+
findings.push({ name: 'manifest_signature', ok: false, detail: 'manifest missing signature or payload fields (appId, network, current, generations, issuedAt)' });
|
|
252
|
+
return { ok: false, origin, address, findings };
|
|
253
|
+
}
|
|
254
|
+
const sigOk = await anySignatureVerifies(payload, signatures, opts.pinnedPublicKeysBase64);
|
|
255
|
+
findings.push({
|
|
256
|
+
name: 'manifest_signature',
|
|
257
|
+
ok: sigOk,
|
|
258
|
+
detail: sigOk
|
|
259
|
+
? `Ed25519 verified against pinned key (1 of ${opts.pinnedPublicKeysBase64.length})`
|
|
260
|
+
: 'signature does not verify against any pinned key',
|
|
261
|
+
});
|
|
262
|
+
if (!sigOk) {
|
|
263
|
+
return { ok: false, origin, address, findings };
|
|
264
|
+
}
|
|
265
|
+
// appId is trusted only after signature verifies — it comes from the signed
|
|
266
|
+
// payload, not the caller.
|
|
267
|
+
const appId = payload.appId;
|
|
268
|
+
// 2b. manifest_network: signed for the network being checked (a devnet
|
|
269
|
+
// manifest never vouches for a mainnet contract, nor the other way round).
|
|
270
|
+
const expectedNetwork = (opts.minaNetworkId ?? 'mainnet') === 'mainnet' ? 'mainnet' : 'devnet';
|
|
271
|
+
findings.push({
|
|
272
|
+
name: 'manifest_network',
|
|
273
|
+
ok: payload.network === expectedNetwork,
|
|
274
|
+
detail: payload.network === expectedNetwork ? `signed for ${payload.network}` : `signed for ${payload.network}, checking ${expectedNetwork}`,
|
|
275
|
+
});
|
|
276
|
+
if (payload.network !== expectedNetwork) {
|
|
277
|
+
return { ok: false, origin, address, findings };
|
|
278
|
+
}
|
|
279
|
+
// 3. manifest_address_in_generations
|
|
280
|
+
const entry = payload.generations.find((g) => g.zkAppAddress === address);
|
|
281
|
+
findings.push({
|
|
282
|
+
name: 'manifest_address_in_generations',
|
|
283
|
+
ok: !!entry,
|
|
284
|
+
detail: entry
|
|
285
|
+
? `address maps to gen ${entry.gen} (${entry.status})`
|
|
286
|
+
: `address ${address} not in manifest generations for app "${appId}"`,
|
|
287
|
+
});
|
|
288
|
+
const generation = entry?.gen;
|
|
289
|
+
// 3b. manifest_matches_backend (opt-in)
|
|
290
|
+
if (opts.crossCheck) {
|
|
291
|
+
findings.push(await checkBackendMatch({
|
|
292
|
+
address,
|
|
293
|
+
vendorPayload: payload,
|
|
294
|
+
pinnedPublicKeysBase64: opts.pinnedPublicKeysBase64,
|
|
295
|
+
timeoutMs,
|
|
296
|
+
}));
|
|
297
|
+
}
|
|
298
|
+
if (opts.skipChainChecks) {
|
|
299
|
+
const allOk = findings.every((f) => f.ok);
|
|
300
|
+
return { ok: allOk, origin, appId, address, generation, findings };
|
|
301
|
+
}
|
|
302
|
+
if (!opts.minaGraphqlUrl) {
|
|
303
|
+
findings.push({ name: 'chain_account_exists', ok: false, detail: 'minaGraphqlUrl is required for chain checks' });
|
|
304
|
+
return { ok: false, origin, appId, address, generation, findings };
|
|
305
|
+
}
|
|
306
|
+
// 4-11: chain reads
|
|
307
|
+
const state = await readChainState(address, opts.minaGraphqlUrl, opts.minaNetworkId ?? 'mainnet');
|
|
308
|
+
findings.push({
|
|
309
|
+
name: 'chain_account_exists',
|
|
310
|
+
ok: state.accountFound,
|
|
311
|
+
detail: state.accountFound ? `account ${address.slice(0, 12)}… found` : (state.fetchError ?? 'account not found'),
|
|
312
|
+
});
|
|
313
|
+
if (!state.accountFound) {
|
|
314
|
+
return { ok: false, origin, appId, address, generation, findings };
|
|
315
|
+
}
|
|
316
|
+
const onChainOrigin = state.zkappUri ? urlOrigin(state.zkappUri) : null;
|
|
317
|
+
const originClean = urlOrigin(origin);
|
|
318
|
+
const uriOk = !!state.zkappUri && !!onChainOrigin && !!originClean && onChainOrigin === originClean;
|
|
319
|
+
findings.push({
|
|
320
|
+
name: 'chain_zkapp_uri_match',
|
|
321
|
+
ok: uriOk,
|
|
322
|
+
detail: state.zkappUri
|
|
323
|
+
? (uriOk ? `zkappUri "${state.zkappUri}" origin matches` : `zkappUri "${state.zkappUri}" origin ≠ "${originClean ?? origin}"`)
|
|
324
|
+
: 'zkappUri is empty on chain',
|
|
325
|
+
});
|
|
326
|
+
// Pinned by circuit: the on-chain VK must be one of the published circuit
|
|
327
|
+
// hashes. The manifest's `gen` counts this app's redeploys, which is not
|
|
328
|
+
// the circuit generation (a redeploy can keep the circuit, and an app
|
|
329
|
+
// deployed after a circuit bump starts at gen 1 on the newer circuit).
|
|
330
|
+
const canonicalVks = await loadCanonicalVkHashes();
|
|
331
|
+
const matchedCircuit = state.vkHash && canonicalVks
|
|
332
|
+
? Object.entries(canonicalVks).find(([, h]) => h === state.vkHash)?.[0]
|
|
333
|
+
: undefined;
|
|
334
|
+
const vkOk = matchedCircuit !== undefined;
|
|
335
|
+
findings.push({
|
|
336
|
+
name: 'chain_vk_hash_pinned',
|
|
337
|
+
ok: vkOk,
|
|
338
|
+
detail: vkOk
|
|
339
|
+
? `on-chain vkHash matches CANONICAL_VK_HASHES[${matchedCircuit}] (app gen ${generation ?? '?'})`
|
|
340
|
+
: !canonicalVks
|
|
341
|
+
? 'CANONICAL_VK_HASHES unavailable'
|
|
342
|
+
: `on-chain vkHash "${state.vkHash?.slice(0, 16) ?? 'missing'}…" is not a published circuit hash`,
|
|
343
|
+
});
|
|
344
|
+
findings.push({
|
|
345
|
+
name: 'chain_set_zkapp_uri_impossible',
|
|
346
|
+
ok: !!state.setZkappUriIsImpossible,
|
|
347
|
+
detail: state.setZkappUriIsImpossible
|
|
348
|
+
? 'permissions.setZkappUri = impossible (zkappUri is frozen)'
|
|
349
|
+
: 'permissions.setZkappUri ≠ impossible — vendor could rewrite the URI',
|
|
350
|
+
});
|
|
351
|
+
// The meta-freeze: without this, every other permission lock below is
|
|
352
|
+
// reversible with a single signature. Priority #1 among the extras.
|
|
353
|
+
findings.push({
|
|
354
|
+
name: 'chain_set_permissions_impossible',
|
|
355
|
+
ok: !!state.setPermissionsIsImpossible,
|
|
356
|
+
detail: state.setPermissionsIsImpossible
|
|
357
|
+
? 'permissions.setPermissions = impossible (permission matrix is meta-frozen)'
|
|
358
|
+
: 'permissions.setPermissions ≠ impossible — every other lock could be relaxed later',
|
|
359
|
+
});
|
|
360
|
+
// setVerificationKey lock, with hardfork-aware softening.
|
|
361
|
+
//
|
|
362
|
+
// The contract deploys with VerificationKey.impossibleDuringCurrentVersion(),
|
|
363
|
+
// which stores {auth: Impossible, txnVersion: <chain's txnVersion at deploy
|
|
364
|
+
// time>}. After a Mina hardfork the chain's current txnVersion advances
|
|
365
|
+
// past the stored value and the effective enforcement falls back to
|
|
366
|
+
// signature() — but the deploy key was discarded (LicensingApp.ts:546-547),
|
|
367
|
+
// so no one can sign the fallback update.
|
|
368
|
+
//
|
|
369
|
+
// The backend records the deploy-time txnVersion in the signed manifest as
|
|
370
|
+
// deployTxnVersion. We accept two states as OK, provided the on-chain
|
|
371
|
+
// stored txnVersion still matches the manifest-recorded value (which proves
|
|
372
|
+
// no one has re-set the permission since deploy):
|
|
373
|
+
//
|
|
374
|
+
// - auth = Impossible → normal, pre-hardfork state
|
|
375
|
+
// - auth = Signature → post-hardfork fallback (see above)
|
|
376
|
+
//
|
|
377
|
+
// Any mismatch — different txnVersion, or auth is some other string, or
|
|
378
|
+
// deployTxnVersion missing from an old manifest — falls back to the strict
|
|
379
|
+
// rule (auth === 'Impossible').
|
|
380
|
+
const onChainAuth = state.setVerificationKeyAuth;
|
|
381
|
+
const onChainTxnVersion = state.setVerificationKeyTxnVersion;
|
|
382
|
+
const manifestDeployTxnVersion = entry?.deployTxnVersion;
|
|
383
|
+
let vkLockOk = false;
|
|
384
|
+
let vkLockDetail;
|
|
385
|
+
if (manifestDeployTxnVersion !== undefined && onChainTxnVersion !== undefined && onChainTxnVersion === manifestDeployTxnVersion) {
|
|
386
|
+
if (onChainAuth === 'Impossible') {
|
|
387
|
+
vkLockOk = true;
|
|
388
|
+
vkLockDetail = `permissions.setVerificationKey.auth = impossible (circuit cannot be swapped; txnVersion ${onChainTxnVersion} matches deploy)`;
|
|
389
|
+
}
|
|
390
|
+
else if (onChainAuth === 'Signature') {
|
|
391
|
+
vkLockOk = true;
|
|
392
|
+
vkLockDetail = `permissions.setVerificationKey.auth = signature (post-hardfork fallback; deploy key was destroyed at deploy time; txnVersion ${onChainTxnVersion} matches deploy)`;
|
|
393
|
+
}
|
|
394
|
+
else {
|
|
395
|
+
vkLockDetail = `permissions.setVerificationKey.auth = "${onChainAuth ?? '?'}" — expected impossible or signature`;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
else if (manifestDeployTxnVersion === undefined) {
|
|
399
|
+
// Older manifest without deployTxnVersion — fall back to strict.
|
|
400
|
+
vkLockOk = onChainAuth === 'Impossible';
|
|
401
|
+
vkLockDetail = vkLockOk
|
|
402
|
+
? 'permissions.setVerificationKey.auth = impossible (circuit cannot be swapped; manifest omits deployTxnVersion — strict rule applied)'
|
|
403
|
+
: `permissions.setVerificationKey.auth = "${onChainAuth ?? '?'}" ≠ impossible — vendor could swap the circuit (manifest omits deployTxnVersion — strict rule applied)`;
|
|
404
|
+
}
|
|
405
|
+
else {
|
|
406
|
+
vkLockDetail = `on-chain setVerificationKey.txnVersion (${onChainTxnVersion ?? 'unknown'}) ≠ manifest deployTxnVersion (${manifestDeployTxnVersion}) — permission may have been re-set since deploy`;
|
|
407
|
+
}
|
|
408
|
+
findings.push({
|
|
409
|
+
name: 'chain_set_verification_key_locked',
|
|
410
|
+
ok: vkLockOk,
|
|
411
|
+
detail: vkLockDetail,
|
|
412
|
+
});
|
|
413
|
+
// send + editState must be proof() (not signature()): withdrawals and Merkle
|
|
414
|
+
// root advances only happen via a valid LicensingApp proof.
|
|
415
|
+
findings.push({
|
|
416
|
+
name: 'chain_send_proof_only',
|
|
417
|
+
ok: !!state.sendIsProof,
|
|
418
|
+
detail: state.sendIsProof
|
|
419
|
+
? 'permissions.send = proof() (escrow only leaves via a refund proof)'
|
|
420
|
+
: 'permissions.send ≠ proof() — vendor could drain escrow with a signature',
|
|
421
|
+
});
|
|
422
|
+
findings.push({
|
|
423
|
+
name: 'chain_edit_state_proof_only',
|
|
424
|
+
ok: !!state.editStateIsProof,
|
|
425
|
+
detail: state.editStateIsProof
|
|
426
|
+
? 'permissions.editState = proof() (Merkle root advances only via a proof)'
|
|
427
|
+
: 'permissions.editState ≠ proof() — vendor could rewrite the license root',
|
|
428
|
+
});
|
|
429
|
+
const allOk = findings.every((f) => f.ok);
|
|
430
|
+
return { ok: allOk, origin, appId, address, generation, findings };
|
|
431
|
+
}
|
|
432
|
+
//# sourceMappingURL=trustAnchorVerify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trustAnchorVerify.js","sourceRoot":"","sources":["../src/trustAnchorVerify.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* trustAnchorVerifyCli.ts
|
|
4
|
+
*
|
|
5
|
+
* Command-line front-end for verifyTrustAnchor(). Ships as the `zklicensing-verify-trust`
|
|
6
|
+
* bin — the sibling of `zklicensing-verify` (which is the verifyService HTTP daemon).
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* zklicensing-verify-trust \
|
|
10
|
+
* --origin https://store.example.com \
|
|
11
|
+
* --address B62q... \
|
|
12
|
+
* --pinned-key <base64-ed25519-pubkey> \
|
|
13
|
+
* [--mina-graphql https://api.minascan.io/node/mainnet/v1/graphql] \
|
|
14
|
+
* [--mina-network-id mainnet|testnet|devnet] \
|
|
15
|
+
* [--skip-chain-checks] \
|
|
16
|
+
* [--json]
|
|
17
|
+
*
|
|
18
|
+
* The manifest lives at `<origin>/.well-known/zklicensing/<address>.json` —
|
|
19
|
+
* one file per generation address, all signed by the same platform key. The
|
|
20
|
+
* appId is read out of the signed payload; callers never need to know it
|
|
21
|
+
* out-of-band, which lets buyers verify from just the address their wallet
|
|
22
|
+
* shows them (including addresses for retired generations).
|
|
23
|
+
*
|
|
24
|
+
* Permit registries:
|
|
25
|
+
* zklicensing-verify-trust --registry B62q... [--origin https://authority.example]
|
|
26
|
+
* [--mina-network-id mainnet|devnet] [--keeper-url https://zklicensing.com/api/keeper]
|
|
27
|
+
* [--no-well-known] [--mina-graphql <url>] [--json]
|
|
28
|
+
* checks the registry's verification key against the published PermitRegistry
|
|
29
|
+
* hashes, its locked permissions and network binding, the authority website
|
|
30
|
+
* written into it at deploy (on the --origin host, when given) and that the
|
|
31
|
+
* website's /.well-known/zkpermits/<address>.json claims it, and (with
|
|
32
|
+
* --keeper-url) that the keeper's authority keys, payout and website match.
|
|
33
|
+
*
|
|
34
|
+
* Exit codes:
|
|
35
|
+
* 0 — every finding passed
|
|
36
|
+
* 1 — one or more findings failed
|
|
37
|
+
* 2 — invalid arguments
|
|
38
|
+
*
|
|
39
|
+
* --pinned-key is required and may be repeated; the CLI ships NO baked-in
|
|
40
|
+
* pin. Source it from https://zklicensing.com/trustanchor.html (published
|
|
41
|
+
* next to each generation's VK hash). See the SDK README for details.
|
|
42
|
+
*/
|
|
43
|
+
import { type Finding } from './trustAnchorVerify.js';
|
|
44
|
+
export type { Finding };
|
|
45
|
+
//# sourceMappingURL=trustAnchorVerifyCli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trustAnchorVerifyCli.d.ts","sourceRoot":"","sources":["../src/trustAnchorVerifyCli.ts"],"names":[],"mappings":";AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,EAAqB,KAAK,OAAO,EAA0B,MAAM,wBAAwB,CAAC;AA2LjG,YAAY,EAAE,OAAO,EAAE,CAAC"}
|