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
package/build/index.js
CHANGED
|
@@ -1,54 +1,42 @@
|
|
|
1
1
|
// Copyright (c) 2025-2026 zkLicensing project developers
|
|
2
|
-
//
|
|
2
|
+
// SPDX-License-Identifier: BUSL-1.1
|
|
3
3
|
/**
|
|
4
4
|
* verifyLicense — client SDK.
|
|
5
5
|
*
|
|
6
|
-
* Calls the
|
|
7
|
-
* license has closed; from that point on returns from a
|
|
8
|
-
* never touches the network again. The refund-window
|
|
9
|
-
* side: the
|
|
10
|
-
* response, computed from its own record of
|
|
11
|
-
* against the on-chain `currentSlot`.
|
|
12
|
-
*
|
|
13
|
-
* file, so a user who forges
|
|
14
|
-
* branch prematurely.
|
|
6
|
+
* Calls the licensing service's GET /verify until the on-chain refund
|
|
7
|
+
* window for the license has closed; from that point on returns from a
|
|
8
|
+
* local anchor and never touches the network again. The refund-window
|
|
9
|
+
* decision is server-side: the service returns `refundWindowClosed:
|
|
10
|
+
* boolean` on its /verify response, computed from its own record of
|
|
11
|
+
* `purchaseSlot + REFUND_WINDOW_N` against the on-chain `currentSlot`.
|
|
12
|
+
* The SDK gates anchor writes on that boolean and never trusts a
|
|
13
|
+
* `purchaseSlot` supplied by the local license file, so a user who forges
|
|
14
|
+
* their proof metadata cannot force the offline branch prematurely.
|
|
15
15
|
*
|
|
16
16
|
* Anchor purity: every field persisted in the Anchor derives from the
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
17
|
+
* service's /verify response — `anchoredSlot`, `expirySlot`. The only
|
|
18
|
+
* client-supplied input to the offline branch is `proof.expirySlot`,
|
|
19
|
+
* used solely as the loadAnchor binding key. A tampered license file
|
|
20
|
+
* therefore never gets a wrong answer; it gets no offline branch at all
|
|
21
|
+
* and falls through to the licensing service on every call.
|
|
22
22
|
*/
|
|
23
|
-
import { REFUND_WINDOW_N, GRACE_PERIOD_N, MS_PER_SLOT_N, SLOTS_PER_DAY_N, } from './
|
|
23
|
+
import { REFUND_WINDOW_N, GRACE_PERIOD_N, MS_PER_SLOT_N, SLOTS_PER_DAY_N, } from './slotConstants.js';
|
|
24
24
|
const MS_PER_SLOT = MS_PER_SLOT_N;
|
|
25
25
|
const SLOTS_PER_DAY = SLOTS_PER_DAY_N;
|
|
26
|
+
// The one and only verify endpoint. Every issued license routes here
|
|
27
|
+
// regardless of network — the platform verifier resolves devnet vs
|
|
28
|
+
// mainnet from the zkAppAddress (each deployment is unique per network).
|
|
29
|
+
// Tests inject a mock via VerifyOptions.fetcher, not by rewriting this URL.
|
|
30
|
+
export const DEFAULT_VERIFIER_URL = 'https://zklicensing.com/api/verify';
|
|
31
|
+
// Anchor records are keyed by (zkAppAddress, licenseHash). zkAppAddress
|
|
32
|
+
// is generation-scoped by construction: each redeploy puts the
|
|
33
|
+
// LicensingApp at a fresh address (see backend's finalizeRedeploy and
|
|
34
|
+
// AppRecord.deploymentHistory[]), so keying on it implicitly captures
|
|
35
|
+
// generation. An anchor for a retired address is orphaned once the license
|
|
36
|
+
// file names the successor, and re-created cleanly on its next verify.
|
|
26
37
|
const ANCHOR_KEY_PREFIX = 'zklic_anchor_';
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
return `${ACTIVATION_KEY_PREFIX}${zkAppAddress}_${licenseHash}`;
|
|
30
|
-
}
|
|
31
|
-
export function loadActivation(storage, zkAppAddress, licenseHash, nowMs = Date.now()) {
|
|
32
|
-
try {
|
|
33
|
-
const raw = storage.getItem(activationKey(zkAppAddress, licenseHash));
|
|
34
|
-
if (!raw)
|
|
35
|
-
return null;
|
|
36
|
-
const rec = JSON.parse(raw);
|
|
37
|
-
if (nowMs > rec.expiresAt)
|
|
38
|
-
return null;
|
|
39
|
-
return rec;
|
|
40
|
-
}
|
|
41
|
-
catch {
|
|
42
|
-
return null;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
export function saveActivation(storage, zkAppAddress, licenseHash, rec) {
|
|
46
|
-
try {
|
|
47
|
-
storage.setItem(activationKey(zkAppAddress, licenseHash), JSON.stringify(rec));
|
|
48
|
-
}
|
|
49
|
-
catch {
|
|
50
|
-
/* quota / read-only — non-fatal */
|
|
51
|
-
}
|
|
38
|
+
function anchorKey(zkAppAddress, licenseHash) {
|
|
39
|
+
return `${ANCHOR_KEY_PREFIX}${zkAppAddress}_${licenseHash}`;
|
|
52
40
|
}
|
|
53
41
|
function defaultStorage() {
|
|
54
42
|
if (typeof globalThis !== 'undefined' && globalThis.localStorage) {
|
|
@@ -56,19 +44,20 @@ function defaultStorage() {
|
|
|
56
44
|
}
|
|
57
45
|
return null;
|
|
58
46
|
}
|
|
59
|
-
function loadAnchor(storage, licenseHash, expirySlot) {
|
|
47
|
+
function loadAnchor(storage, zkAppAddress, licenseHash, expirySlot) {
|
|
60
48
|
try {
|
|
61
|
-
const raw = storage.getItem(
|
|
49
|
+
const raw = storage.getItem(anchorKey(zkAppAddress, licenseHash));
|
|
62
50
|
if (!raw)
|
|
63
51
|
return null;
|
|
64
52
|
const a = JSON.parse(raw);
|
|
65
|
-
// `a.expirySlot` is the
|
|
66
|
-
// `expirySlot` argument is the LOCAL
|
|
67
|
-
// file agrees with chain truth as of anchoring ⇒ offline is
|
|
68
|
-
// Mismatch has two honest meanings:
|
|
53
|
+
// `a.expirySlot` is the SERVICE's value captured at anchor time;
|
|
54
|
+
// the `expirySlot` argument is the LOCAL license file's value. Match
|
|
55
|
+
// ⇒ local file agrees with chain truth as of anchoring ⇒ offline is
|
|
56
|
+
// safe. Mismatch has two honest meanings:
|
|
69
57
|
// - renewal: chain moved, local file updated ⇒ re-anchor via chain check
|
|
70
|
-
// - forgery: local file edited ⇒ every call falls through to the
|
|
71
|
-
// which reports truth. The forger gets no
|
|
58
|
+
// - forgery: local file edited ⇒ every call falls through to the
|
|
59
|
+
// licensing service, which reports truth. The forger gets no
|
|
60
|
+
// offline branch at all.
|
|
72
61
|
if (a.expirySlot !== expirySlot)
|
|
73
62
|
return null;
|
|
74
63
|
return a;
|
|
@@ -77,9 +66,9 @@ function loadAnchor(storage, licenseHash, expirySlot) {
|
|
|
77
66
|
return null;
|
|
78
67
|
}
|
|
79
68
|
}
|
|
80
|
-
function saveAnchor(storage, licenseHash, anchor) {
|
|
69
|
+
function saveAnchor(storage, zkAppAddress, licenseHash, anchor) {
|
|
81
70
|
try {
|
|
82
|
-
storage.setItem(
|
|
71
|
+
storage.setItem(anchorKey(zkAppAddress, licenseHash), JSON.stringify(anchor));
|
|
83
72
|
}
|
|
84
73
|
catch {
|
|
85
74
|
// Storage may be full or read-only; the offline path simply won't activate.
|
|
@@ -90,72 +79,38 @@ function computeRemainingDays(expirySlot, currentSlot) {
|
|
|
90
79
|
return 0;
|
|
91
80
|
return Math.floor((expirySlot - currentSlot) / SLOTS_PER_DAY);
|
|
92
81
|
}
|
|
93
|
-
// Renew the activation token when within this window of expiry. Picked so
|
|
94
|
-
// that a daily verify call has many chances to refresh before the token dies.
|
|
95
|
-
const TOKEN_RENEW_THRESHOLD_MS = 24 * 60 * 60 * 1000;
|
|
96
|
-
async function tryActivate(storage, zkAppAddress, licenseHash, current, bootstrapSecretHash, prover, verifierUrl, fetcher, nowMs) {
|
|
97
|
-
const secretHash = current?.secretHash ?? bootstrapSecretHash;
|
|
98
|
-
if (!secretHash)
|
|
99
|
-
return current;
|
|
100
|
-
// Existing token still fresh — nothing to do.
|
|
101
|
-
if (current?.token && current.expiresAt - nowMs > TOKEN_RENEW_THRESHOLD_MS)
|
|
102
|
-
return current;
|
|
103
|
-
try {
|
|
104
|
-
const base = verifierUrl.replace(/\/+$/, '');
|
|
105
|
-
const challengeResp = await fetcher(`${base}/challenge?licenseHash=${encodeURIComponent(licenseHash)}`);
|
|
106
|
-
if (!challengeResp.ok)
|
|
107
|
-
return current;
|
|
108
|
-
const { nonce } = (await challengeResp.json());
|
|
109
|
-
const proofJson = await prover({ licenseHash, nonce, secretHash });
|
|
110
|
-
const respondResp = await fetcher(`${base}/respond`, {
|
|
111
|
-
method: 'POST',
|
|
112
|
-
headers: { 'Content-Type': 'application/json' },
|
|
113
|
-
body: JSON.stringify({ zkAppAddress, proof: proofJson }),
|
|
114
|
-
});
|
|
115
|
-
if (!respondResp.ok)
|
|
116
|
-
return current;
|
|
117
|
-
const { token, expiresAt } = (await respondResp.json());
|
|
118
|
-
const next = { token, expiresAt, secretHash };
|
|
119
|
-
saveActivation(storage, zkAppAddress, licenseHash, next);
|
|
120
|
-
return next;
|
|
121
|
-
}
|
|
122
|
-
catch {
|
|
123
|
-
return current;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
82
|
function offlineCheck(anchor, nowMs) {
|
|
127
83
|
const elapsedSlots = Math.max(0, Math.floor((nowMs - anchor.anchoredAtMs) / MS_PER_SLOT));
|
|
128
84
|
const estCurrentSlot = anchor.anchoredSlot + elapsedSlots;
|
|
129
|
-
const
|
|
130
|
-
const
|
|
131
|
-
const
|
|
85
|
+
const until = anchor.effectiveExpirySlot ?? anchor.expirySlot;
|
|
86
|
+
const expired = estCurrentSlot > until + GRACE_PERIOD_N;
|
|
87
|
+
const inGracePeriod = !expired && estCurrentSlot > until;
|
|
88
|
+
const expiresAt = new Date(nowMs + (until - estCurrentSlot) * MS_PER_SLOT).toISOString();
|
|
132
89
|
return {
|
|
133
90
|
valid: !expired,
|
|
134
91
|
expirySlot: anchor.expirySlot,
|
|
135
92
|
expiresAt,
|
|
136
93
|
currentSlot: estCurrentSlot,
|
|
137
94
|
inGracePeriod,
|
|
138
|
-
remainingDays: computeRemainingDays(
|
|
95
|
+
remainingDays: computeRemainingDays(until, estCurrentSlot),
|
|
139
96
|
reason: expired
|
|
140
97
|
? 'License has expired'
|
|
141
98
|
: inGracePeriod
|
|
142
99
|
? 'License is in grace period — renew to avoid interruption'
|
|
143
100
|
: null,
|
|
144
101
|
source: 'offline',
|
|
145
|
-
ownership: anchor.ownership,
|
|
146
102
|
};
|
|
147
103
|
}
|
|
148
104
|
export async function verifyLicense(proof, options = {}) {
|
|
149
105
|
const storage = options.storage === null ? null : options.storage ?? defaultStorage();
|
|
150
106
|
const fetcher = options.fetcher ?? (typeof fetch !== 'undefined' ? fetch : undefined);
|
|
151
107
|
const nowFn = options.now ?? (() => Date.now());
|
|
152
|
-
const verifierUrl = options.verifierUrl ?? proof.verifierUrl;
|
|
153
108
|
if (storage) {
|
|
154
|
-
const anchor = loadAnchor(storage, proof.licenseHash, proof.expirySlot);
|
|
109
|
+
const anchor = loadAnchor(storage, proof.zkAppAddress, proof.licenseHash, proof.expirySlot);
|
|
155
110
|
if (anchor)
|
|
156
111
|
return offlineCheck(anchor, nowFn());
|
|
157
112
|
}
|
|
158
|
-
if (!
|
|
113
|
+
if (!fetcher) {
|
|
159
114
|
return {
|
|
160
115
|
valid: false,
|
|
161
116
|
expirySlot: proof.expirySlot,
|
|
@@ -163,24 +118,13 @@ export async function verifyLicense(proof, options = {}) {
|
|
|
163
118
|
currentSlot: 0,
|
|
164
119
|
inGracePeriod: false,
|
|
165
120
|
remainingDays: 0,
|
|
166
|
-
reason: 'No
|
|
121
|
+
reason: 'No fetch implementation available; cannot verify',
|
|
167
122
|
source: 'chain',
|
|
168
|
-
ownership: 'unverified',
|
|
169
123
|
};
|
|
170
124
|
}
|
|
171
|
-
|
|
172
|
-
? loadActivation(storage, proof.zkAppAddress, proof.licenseHash, nowFn())
|
|
173
|
-
: null;
|
|
174
|
-
if (storage && options.prover && (activation || options.secretHash)) {
|
|
175
|
-
activation = await tryActivate(storage, proof.zkAppAddress, proof.licenseHash, activation, options.secretHash, options.prover, verifierUrl, fetcher, nowFn());
|
|
176
|
-
}
|
|
177
|
-
const tokenParam = activation?.token
|
|
178
|
-
? `&token=${encodeURIComponent(activation.token)}`
|
|
179
|
-
: '';
|
|
180
|
-
const url = `${verifierUrl.replace(/\/+$/, '')}` +
|
|
125
|
+
const url = `${DEFAULT_VERIFIER_URL}` +
|
|
181
126
|
`?licenseHash=${encodeURIComponent(proof.licenseHash)}` +
|
|
182
|
-
`&zkAppAddress=${encodeURIComponent(proof.zkAppAddress)}
|
|
183
|
-
tokenParam;
|
|
127
|
+
`&zkAppAddress=${encodeURIComponent(proof.zkAppAddress)}`;
|
|
184
128
|
let data;
|
|
185
129
|
try {
|
|
186
130
|
const resp = await fetcher(url);
|
|
@@ -194,7 +138,6 @@ export async function verifyLicense(proof, options = {}) {
|
|
|
194
138
|
remainingDays: 0,
|
|
195
139
|
reason: `Verification request failed (HTTP ${resp.status})`,
|
|
196
140
|
source: 'chain',
|
|
197
|
-
ownership: 'unverified',
|
|
198
141
|
};
|
|
199
142
|
}
|
|
200
143
|
data = await resp.json();
|
|
@@ -209,13 +152,12 @@ export async function verifyLicense(proof, options = {}) {
|
|
|
209
152
|
remainingDays: 0,
|
|
210
153
|
reason: err?.message ?? 'Verification request errored',
|
|
211
154
|
source: 'chain',
|
|
212
|
-
ownership: 'unverified',
|
|
213
155
|
};
|
|
214
156
|
}
|
|
215
|
-
//
|
|
216
|
-
// the null-safe form may be written into the anchor; the
|
|
217
|
-
// display value below falls back to the local
|
|
218
|
-
// fields, which is safe (display only).
|
|
157
|
+
// Service's authoritative expiry, or null if the response omits it.
|
|
158
|
+
// Only the null-safe form may be written into the anchor; the
|
|
159
|
+
// chain-result display value below falls back to the local license file
|
|
160
|
+
// for user-facing fields, which is safe (display only).
|
|
219
161
|
const respExpirySlotStrict = typeof data.expirySlot === 'number' ? data.expirySlot : null;
|
|
220
162
|
const respExpirySlot = respExpirySlotStrict ?? proof.expirySlot;
|
|
221
163
|
const respCurrentSlot = typeof data.currentSlot === 'number' ? data.currentSlot : 0;
|
|
@@ -230,24 +172,24 @@ export async function verifyLicense(proof, options = {}) {
|
|
|
230
172
|
: computeRemainingDays(respExpirySlot, respCurrentSlot),
|
|
231
173
|
reason: data.reason ?? null,
|
|
232
174
|
source: 'chain',
|
|
233
|
-
ownership: data.ownership === 'verified' ? 'verified' : 'unverified',
|
|
234
175
|
};
|
|
235
|
-
// Anchor gate uses the
|
|
236
|
-
// knows the true purchaseSlot (stored in its LicenseRecord)
|
|
237
|
-
// currentSlot; the SDK never trusts a purchaseSlot or
|
|
238
|
-
// by the local
|
|
239
|
-
// be forged. If the
|
|
240
|
-
// offline path — no anchor
|
|
176
|
+
// Anchor gate uses the service's own refund-window decision. The
|
|
177
|
+
// service knows the true purchaseSlot (stored in its LicenseRecord)
|
|
178
|
+
// and the true currentSlot; the SDK never trusts a purchaseSlot or
|
|
179
|
+
// expirySlot supplied by the local license file, since that file is
|
|
180
|
+
// client-writable and could be forged. If the service omits
|
|
181
|
+
// `expirySlot`, we fail-closed on the offline path — no anchor
|
|
182
|
+
// written, subsequent calls stay online.
|
|
241
183
|
if (storage &&
|
|
242
184
|
result.valid &&
|
|
243
185
|
data.refundWindowClosed === true &&
|
|
244
186
|
typeof data.currentSlot === 'number' &&
|
|
245
187
|
respExpirySlotStrict !== null) {
|
|
246
|
-
saveAnchor(storage, proof.licenseHash, {
|
|
188
|
+
saveAnchor(storage, proof.zkAppAddress, proof.licenseHash, {
|
|
247
189
|
anchoredSlot: data.currentSlot,
|
|
248
190
|
anchoredAtMs: nowFn(),
|
|
249
191
|
expirySlot: respExpirySlotStrict,
|
|
250
|
-
|
|
192
|
+
...(typeof data.effectiveExpirySlot === 'number' ? { effectiveExpirySlot: data.effectiveExpirySlot } : {}),
|
|
251
193
|
});
|
|
252
194
|
}
|
|
253
195
|
return result;
|
|
@@ -255,4 +197,38 @@ export async function verifyLicense(proof, options = {}) {
|
|
|
255
197
|
// Re-exported so tests and downstream tooling can reference the same values
|
|
256
198
|
// the SDK uses internally without re-deriving them.
|
|
257
199
|
export { REFUND_WINDOW_N, GRACE_PERIOD_N, MS_PER_SLOT };
|
|
200
|
+
const bindClient = () => import('./bindClient.js');
|
|
201
|
+
const unbindClient = () => import('./unbindClient.js');
|
|
202
|
+
const deviceIdentityModule = () => import('./deviceIdentity.js');
|
|
203
|
+
export async function proveBind(...a) { return (await bindClient()).proveBind(...a); }
|
|
204
|
+
export async function confirmBind(...a) { return (await bindClient()).confirmBind(...a); }
|
|
205
|
+
export async function pollBindStatus(...a) { return (await bindClient()).pollBindStatus(...a); }
|
|
206
|
+
export async function fetchBindingState(...a) { return (await bindClient()).fetchBindingState(...a); }
|
|
207
|
+
export async function proveUnbind(...a) { return (await unbindClient()).proveUnbind(...a); }
|
|
208
|
+
export async function confirmUnbind(...a) { return (await unbindClient()).confirmUnbind(...a); }
|
|
209
|
+
export async function pollUnbindStatus(...a) { return (await unbindClient()).pollUnbindStatus(...a); }
|
|
210
|
+
export async function getOrCreateDeviceIdentity(...a) { return (await deviceIdentityModule()).getOrCreateDeviceIdentity(...a); }
|
|
211
|
+
// Non-custodial trust anchor for `verifyOffline`. Reads the live
|
|
212
|
+
// `licensesRoot` (zkapp.appState[0]) directly from Mina — pair it with
|
|
213
|
+
// `verifyOffline` when you do not want to trust the licensing service's
|
|
214
|
+
// reported root. Also available at the `zklicensing/on-chain-root`
|
|
215
|
+
// subpath. o1js is imported lazily so callers that skip this helper
|
|
216
|
+
// don't pay the o1js dep cost at load time.
|
|
217
|
+
export { fetchOnChainLicensesRoot, DEFAULT_MINA_GRAPHQL_URLS } from './onChainRoot.js';
|
|
218
|
+
// The receipt file a buyer downloads: `license-<appId>.json`. Look for it
|
|
219
|
+
// under this name in your app's data folder. Also available at the
|
|
220
|
+
// `zklicensing/record` subpath.
|
|
221
|
+
export { licenseFileName, platformFeeNano, vendorShareNano } from './licenseRecord.js';
|
|
222
|
+
// Human-readable seat names for the device-binding UI ("Silent Otter",
|
|
223
|
+
// "Curious Panda"). Deterministic in `licenseHash + slotIndex + boundAtSlot`,
|
|
224
|
+
// so every viewer of the same license computes the same name per slot
|
|
225
|
+
// without a naming sidecar. Also available at the `zklicensing/seat-name`
|
|
226
|
+
// subpath.
|
|
227
|
+
export { seatNameFor, SEAT_NAME_COMBINATIONS } from './seatName.js';
|
|
228
|
+
// Vendor-signed escrow release. The licensing service proves the release tx
|
|
229
|
+
// with the vendor's address as fee payer and returns unsigned tx JSON; the
|
|
230
|
+
// vendor's wallet signs the fee-payer AU and broadcasts. Removes the
|
|
231
|
+
// service's own feepayer key from the release critical path — vendors can
|
|
232
|
+
// release even when the auto-release loop is disabled.
|
|
233
|
+
export { proveVendorRelease, confirmVendorRelease } from './releaseClient.js';
|
|
258
234
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* keysClient.ts — key changes on a licensing app, through the keeper.
|
|
3
|
+
*
|
|
4
|
+
* - The keys an app holds on chain (vendor, payout address and a pending
|
|
5
|
+
* change, platform key and treasury).
|
|
6
|
+
* - Payout address: the vendor proposes a new one (their wallet sends it);
|
|
7
|
+
* it takes effect PAYOUT_DELAY_SLOTS_N slots (48 h) later unless
|
|
8
|
+
* cancelled. The keeper applies it then; anyone may (applyPayout).
|
|
9
|
+
* - Vendor account move: the current and the new wallet both sign a text
|
|
10
|
+
* and, for every live deployment, the contract's vendorKeyMessage.
|
|
11
|
+
* - License transfer (resale): the new owner opens it with the public key
|
|
12
|
+
* of their new passphrase (the passphrase never leaves their device), the
|
|
13
|
+
* current owner signs, the new owner signs, and the new owner's wallet
|
|
14
|
+
* sends it. Only once nothing of the purchase is in escrow.
|
|
15
|
+
*
|
|
16
|
+
* Signatures over fields are Mina Schnorr signatures (base58), as an
|
|
17
|
+
* o1js `Signature` or a wallet's `signFields` gives.
|
|
18
|
+
*/
|
|
19
|
+
import { type PrivateKey } from 'o1js';
|
|
20
|
+
export type KeysClientOptions = {
|
|
21
|
+
keeperUrl: string;
|
|
22
|
+
fetcher?: typeof fetch;
|
|
23
|
+
};
|
|
24
|
+
export type AppKeys = {
|
|
25
|
+
appId: string;
|
|
26
|
+
network: 'devnet' | 'mainnet';
|
|
27
|
+
zkAppAddress: string;
|
|
28
|
+
slot: number;
|
|
29
|
+
vendor: string;
|
|
30
|
+
vendorNonce: number;
|
|
31
|
+
payout: string;
|
|
32
|
+
pendingPayout: {
|
|
33
|
+
payout: string;
|
|
34
|
+
effectiveSlot: number;
|
|
35
|
+
} | null;
|
|
36
|
+
platform: {
|
|
37
|
+
key: string;
|
|
38
|
+
treasury: string;
|
|
39
|
+
epoch: number;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
export type LicenseTransfer = {
|
|
43
|
+
id: string;
|
|
44
|
+
network: 'devnet' | 'mainnet';
|
|
45
|
+
zkAppAddress: string;
|
|
46
|
+
from: string;
|
|
47
|
+
to: string;
|
|
48
|
+
newOwner: string;
|
|
49
|
+
leafHash: string;
|
|
50
|
+
validUntil: number;
|
|
51
|
+
message: string[];
|
|
52
|
+
oldOwner?: string;
|
|
53
|
+
status: 'signing' | 'ready' | 'sent' | 'done';
|
|
54
|
+
createdAt: string;
|
|
55
|
+
txHash?: string;
|
|
56
|
+
};
|
|
57
|
+
/** A wallet that signs texts and fields (Auro's signMessage / signFields shapes). */
|
|
58
|
+
export type MoveWallet = {
|
|
59
|
+
address: string;
|
|
60
|
+
signMessage(message: string): Promise<{
|
|
61
|
+
field: string;
|
|
62
|
+
scalar: string;
|
|
63
|
+
}>;
|
|
64
|
+
signFields(fields: string[]): Promise<string>;
|
|
65
|
+
};
|
|
66
|
+
export declare class KeysError extends Error {
|
|
67
|
+
readonly status: number;
|
|
68
|
+
readonly code?: string | undefined;
|
|
69
|
+
constructor(message: string, status: number, code?: string | undefined);
|
|
70
|
+
}
|
|
71
|
+
export declare function createKeysClient(opts: KeysClientOptions): {
|
|
72
|
+
/** The keys the app holds on chain. */
|
|
73
|
+
getAppKeys: (zkAppAddress: string) => Promise<AppKeys>;
|
|
74
|
+
/** Proves a payout change for the vendor's wallet to sign and send (its `vendorAddress` must be the app's vendor key). */
|
|
75
|
+
provePayout: (a: {
|
|
76
|
+
zkAppAddress: string;
|
|
77
|
+
vendorAddress: string;
|
|
78
|
+
payout: string;
|
|
79
|
+
}) => Promise<{
|
|
80
|
+
provenTxJson: string;
|
|
81
|
+
payout: string;
|
|
82
|
+
}>;
|
|
83
|
+
/** Proves the cancellation of a pending payout change (vendor's wallet). */
|
|
84
|
+
provePayoutCancel: (a: {
|
|
85
|
+
zkAppAddress: string;
|
|
86
|
+
vendorAddress: string;
|
|
87
|
+
}) => Promise<{
|
|
88
|
+
provenTxJson: string;
|
|
89
|
+
cancelled: string;
|
|
90
|
+
}>;
|
|
91
|
+
/** Proves applying a payout change past its delay, with any fee payer (the keeper does it itself). */
|
|
92
|
+
provePayoutApply: (a: {
|
|
93
|
+
zkAppAddress: string;
|
|
94
|
+
feePayer: string;
|
|
95
|
+
}) => Promise<{
|
|
96
|
+
provenTxJson: string;
|
|
97
|
+
payout: string;
|
|
98
|
+
}>;
|
|
99
|
+
/**
|
|
100
|
+
* Moves the vendor account from `from` to `to`: both wallets sign the
|
|
101
|
+
* move and every live deployment's key change. The keeper's records move
|
|
102
|
+
* at once; it sends the contract changes (or anyone, with /prove/vendor-key).
|
|
103
|
+
* `network` is the one the wallets' text signatures are made on.
|
|
104
|
+
*/
|
|
105
|
+
moveVendorAccount(a: {
|
|
106
|
+
network: "devnet" | "mainnet";
|
|
107
|
+
from: MoveWallet;
|
|
108
|
+
to: MoveWallet;
|
|
109
|
+
}): Promise<{
|
|
110
|
+
moved: {
|
|
111
|
+
from: string;
|
|
112
|
+
to: string;
|
|
113
|
+
};
|
|
114
|
+
changes: unknown[];
|
|
115
|
+
keeperSends: boolean;
|
|
116
|
+
}>;
|
|
117
|
+
/** The new owner opens a transfer with the public key of their new passphrase (deriveOwnershipKeypair). */
|
|
118
|
+
openTransfer: (a: {
|
|
119
|
+
zkAppAddress: string;
|
|
120
|
+
licenseHash: string;
|
|
121
|
+
newOwnerPubKey: string;
|
|
122
|
+
}) => Promise<LicenseTransfer>;
|
|
123
|
+
getTransfer: (id: string) => Promise<LicenseTransfer>;
|
|
124
|
+
/**
|
|
125
|
+
* Signs the transfer with an ownership key: the current owner's (`role:
|
|
126
|
+
* 'old'`; from findOwnershipKeypair, since a license carried over from an
|
|
127
|
+
* earlier generation is keyed to that one's address) or the new owner's
|
|
128
|
+
* (`'new'`; deriveOwnershipKeypair with the transfer's zkAppAddress). The message is checked first
|
|
129
|
+
* against the transfer's details.
|
|
130
|
+
*/
|
|
131
|
+
signTransfer(id: string, role: "old" | "new", ownerKey: PrivateKey): Promise<LicenseTransfer>;
|
|
132
|
+
/** Both signed: proves the transfer for `feePayer` (the new owner's wallet) to sign and send. */
|
|
133
|
+
proveTransfer: (id: string, feePayer: string) => Promise<{
|
|
134
|
+
provenTxJson: string;
|
|
135
|
+
transferId: string;
|
|
136
|
+
}>;
|
|
137
|
+
confirmTransfer: (id: string, txHash: string) => Promise<{
|
|
138
|
+
ok: true;
|
|
139
|
+
}>;
|
|
140
|
+
};
|
|
141
|
+
export type KeysClient = ReturnType<typeof createKeysClient>;
|
|
142
|
+
//# sourceMappingURL=keysClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keysClient.d.ts","sourceRoot":"","sources":["../src/keysClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// Copyright (c) 2025-2026 zkLicensing project developers
|
|
2
|
+
// SPDX-License-Identifier: BUSL-1.1
|
|
3
|
+
/**
|
|
4
|
+
* keysClient.ts — key changes on a licensing app, through the keeper.
|
|
5
|
+
*
|
|
6
|
+
* - The keys an app holds on chain (vendor, payout address and a pending
|
|
7
|
+
* change, platform key and treasury).
|
|
8
|
+
* - Payout address: the vendor proposes a new one (their wallet sends it);
|
|
9
|
+
* it takes effect PAYOUT_DELAY_SLOTS_N slots (48 h) later unless
|
|
10
|
+
* cancelled. The keeper applies it then; anyone may (applyPayout).
|
|
11
|
+
* - Vendor account move: the current and the new wallet both sign a text
|
|
12
|
+
* and, for every live deployment, the contract's vendorKeyMessage.
|
|
13
|
+
* - License transfer (resale): the new owner opens it with the public key
|
|
14
|
+
* of their new passphrase (the passphrase never leaves their device), the
|
|
15
|
+
* current owner signs, the new owner signs, and the new owner's wallet
|
|
16
|
+
* sends it. Only once nothing of the purchase is in escrow.
|
|
17
|
+
*
|
|
18
|
+
* Signatures over fields are Mina Schnorr signatures (base58), as an
|
|
19
|
+
* o1js `Signature` or a wallet's `signFields` gives.
|
|
20
|
+
*/
|
|
21
|
+
import { Field, PublicKey, Signature, UInt32 } from 'o1js';
|
|
22
|
+
import { licenseTransferMessage, vendorKeyMessage } from './contractInterface.js';
|
|
23
|
+
import { networkField } from './permitMessages.js';
|
|
24
|
+
import { ownerPubKeyHash } from './licenseLeaf.js';
|
|
25
|
+
export class KeysError extends Error {
|
|
26
|
+
status;
|
|
27
|
+
code;
|
|
28
|
+
constructor(message, status, code) {
|
|
29
|
+
super(message);
|
|
30
|
+
this.status = status;
|
|
31
|
+
this.code = code;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export function createKeysClient(opts) {
|
|
35
|
+
const base = opts.keeperUrl.replace(/\/+$/, '');
|
|
36
|
+
const f = opts.fetcher ?? fetch;
|
|
37
|
+
async function call(method, path, body) {
|
|
38
|
+
const r = await f(base + path, { method, headers: { 'content-type': 'application/json' }, ...(body === undefined ? {} : { body: JSON.stringify(body) }) });
|
|
39
|
+
const json = await r.json().catch(() => null);
|
|
40
|
+
if (!r.ok)
|
|
41
|
+
throw new KeysError(json?.error ?? `${method} ${path} failed (${r.status})`, r.status, json?.code);
|
|
42
|
+
return json;
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
/** The keys the app holds on chain. */
|
|
46
|
+
getAppKeys: (zkAppAddress) => call('GET', `/app-keys?zkAppAddress=${encodeURIComponent(zkAppAddress)}`),
|
|
47
|
+
/** Proves a payout change for the vendor's wallet to sign and send (its `vendorAddress` must be the app's vendor key). */
|
|
48
|
+
provePayout: (a) => call('POST', '/prove/payout', a),
|
|
49
|
+
/** Proves the cancellation of a pending payout change (vendor's wallet). */
|
|
50
|
+
provePayoutCancel: (a) => call('POST', '/prove/payout/cancel', a),
|
|
51
|
+
/** Proves applying a payout change past its delay, with any fee payer (the keeper does it itself). */
|
|
52
|
+
provePayoutApply: (a) => call('POST', '/prove/payout/apply', a),
|
|
53
|
+
/**
|
|
54
|
+
* Moves the vendor account from `from` to `to`: both wallets sign the
|
|
55
|
+
* move and every live deployment's key change. The keeper's records move
|
|
56
|
+
* at once; it sends the contract changes (or anyone, with /prove/vendor-key).
|
|
57
|
+
* `network` is the one the wallets' text signatures are made on.
|
|
58
|
+
*/
|
|
59
|
+
async moveVendorAccount(a) {
|
|
60
|
+
const prep = await call('POST', '/vendors/move/prepare', { from: a.from.address, to: a.to.address });
|
|
61
|
+
// Check each message is the key change it says it is before signing.
|
|
62
|
+
for (const c of prep.changes) {
|
|
63
|
+
const expected = vendorKeyMessage({ network: networkField(c.network), app: PublicKey.fromBase58(c.zkAppAddress), nonce: UInt32.from(c.nonce), vendor: PublicKey.fromBase58(a.to.address) }).map(String);
|
|
64
|
+
if (expected.join() !== c.message.join())
|
|
65
|
+
throw new KeysError(`The key change for ${c.zkAppAddress} is not the one asked for: not signing`, 0, 'SIGNATURE_INVALID');
|
|
66
|
+
}
|
|
67
|
+
const changes = [];
|
|
68
|
+
for (const c of prep.changes)
|
|
69
|
+
changes.push({ zkAppAddress: c.zkAppAddress, oldSignature: await a.from.signFields(c.message), newSignature: await a.to.signFields(c.message) });
|
|
70
|
+
return call('POST', '/vendors/move', {
|
|
71
|
+
network: a.network, from: a.from.address, to: a.to.address,
|
|
72
|
+
oldTextSignature: await a.from.signMessage(prep.text), newTextSignature: await a.to.signMessage(prep.text), changes,
|
|
73
|
+
});
|
|
74
|
+
},
|
|
75
|
+
// ── license transfer ────────────────────────────────────────────────────
|
|
76
|
+
/** The new owner opens a transfer with the public key of their new passphrase (deriveOwnershipKeypair). */
|
|
77
|
+
openTransfer: (a) => call('POST', '/transfers', a).then(r => r.transfer),
|
|
78
|
+
getTransfer: (id) => call('GET', `/transfers/${encodeURIComponent(id)}`).then(r => r.transfer),
|
|
79
|
+
/**
|
|
80
|
+
* Signs the transfer with an ownership key: the current owner's (`role:
|
|
81
|
+
* 'old'`; from findOwnershipKeypair, since a license carried over from an
|
|
82
|
+
* earlier generation is keyed to that one's address) or the new owner's
|
|
83
|
+
* (`'new'`; deriveOwnershipKeypair with the transfer's zkAppAddress). The message is checked first
|
|
84
|
+
* against the transfer's details.
|
|
85
|
+
*/
|
|
86
|
+
async signTransfer(id, role, ownerKey) {
|
|
87
|
+
const t = await call('GET', `/transfers/${encodeURIComponent(id)}`).then(r => r.transfer);
|
|
88
|
+
const pub = ownerKey.toPublicKey();
|
|
89
|
+
if (role === 'old' && ownerPubKeyHash(pub).toString() !== t.from)
|
|
90
|
+
throw new KeysError('This passphrase does not own the license', 0, 'FORBIDDEN');
|
|
91
|
+
if (role === 'new' && pub.toBase58() !== t.newOwner)
|
|
92
|
+
throw new KeysError('This passphrase is not the one the transfer was opened for', 0, 'FORBIDDEN');
|
|
93
|
+
const expected = licenseTransferMessage({
|
|
94
|
+
network: networkField(t.network), app: PublicKey.fromBase58(t.zkAppAddress), leafHash: Field(t.leafHash), to: Field(t.to), validUntil: UInt32.from(t.validUntil),
|
|
95
|
+
}).map(String);
|
|
96
|
+
if (expected.join() !== t.message.join() || ownerPubKeyHash(PublicKey.fromBase58(t.newOwner)).toString() !== t.to) {
|
|
97
|
+
throw new KeysError('The transfer message does not match its details: not signing', 0, 'SIGNATURE_INVALID');
|
|
98
|
+
}
|
|
99
|
+
const signature = Signature.create(ownerKey, t.message.map(x => Field(x))).toBase58();
|
|
100
|
+
return call('POST', `/transfers/${encodeURIComponent(id)}/signatures`, {
|
|
101
|
+
role, signature, ...(role === 'old' ? { ownerPubKey: pub.toBase58() } : {}),
|
|
102
|
+
}).then(r => r.transfer);
|
|
103
|
+
},
|
|
104
|
+
/** Both signed: proves the transfer for `feePayer` (the new owner's wallet) to sign and send. */
|
|
105
|
+
proveTransfer: (id, feePayer) => call('POST', '/prove/transfer', { id, feePayer }),
|
|
106
|
+
confirmTransfer: (id, txHash) => call('POST', '/confirm/transfer', { id, txHash }),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=keysClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keysClient.js","sourceRoot":"","sources":["../src/keysClient.ts"],"names":[],"mappings":"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"}
|