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/licenseStore.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Copyright (c) 2025-2026 zkLicensing project developers
|
|
2
|
-
//
|
|
2
|
+
// SPDX-License-Identifier: BUSL-1.1
|
|
3
3
|
/**
|
|
4
4
|
* licenseStore.ts
|
|
5
5
|
*
|
|
@@ -13,24 +13,27 @@
|
|
|
13
13
|
* Used by:
|
|
14
14
|
* - interact.ts / buyLicense.ts (CLI) — reads/writes directly
|
|
15
15
|
* - keeperService.ts — exposes the same logic over HTTP
|
|
16
|
-
* - proofServer.ts — reads expirySlot for a given licenseHash
|
|
17
16
|
*/
|
|
18
|
-
import fs from 'fs/promises';
|
|
19
17
|
import { Bool, Field, MerkleMap, MerkleMapWitness, Poseidon, PublicKey, UInt32, UInt64 } from 'o1js';
|
|
20
|
-
import { GRACE_PERIOD_N, REFUND_WINDOW_N } from './contractInterface.js';
|
|
18
|
+
import { GRACE_PERIOD_N, REFUND_WINDOW_N, effectiveExpirySlot } from './contractInterface.js';
|
|
19
|
+
import { computeDeviceSlotsRoot, DEVICE_SLOT_CAP_N, leafFromRecord, leafHash } from './licenseLeaf.js';
|
|
21
20
|
import { PENDING_REAP_SLOTS as _PENDING_REAP_SLOTS } from './licenseRecord.js';
|
|
21
|
+
import { readJsonOr, writeJsonAtomic } from './atomicJson.js';
|
|
22
22
|
export const PENDING_REAP_SLOTS = _PENDING_REAP_SLOTS;
|
|
23
23
|
export function licenseStorePath() {
|
|
24
24
|
return process.env.LICENSE_STORE_PATH ?? 'licenses.json';
|
|
25
25
|
}
|
|
26
|
+
const fileBackend = {
|
|
27
|
+
// Missing file → empty store; a damaged file is an error (see atomicJson).
|
|
28
|
+
read: () => readJsonOr(licenseStorePath(), []),
|
|
29
|
+
write: records => writeJsonAtomic(licenseStorePath(), records),
|
|
30
|
+
};
|
|
31
|
+
let backend = fileBackend;
|
|
32
|
+
export function setLicenseStoreBackend(b) {
|
|
33
|
+
backend = b ?? fileBackend;
|
|
34
|
+
}
|
|
26
35
|
export async function readRecords() {
|
|
27
|
-
|
|
28
|
-
try {
|
|
29
|
-
raw = JSON.parse(await fs.readFile(licenseStorePath(), 'utf8'));
|
|
30
|
-
}
|
|
31
|
-
catch {
|
|
32
|
-
return [];
|
|
33
|
-
}
|
|
36
|
+
const raw = await backend.read();
|
|
34
37
|
if (!Array.isArray(raw))
|
|
35
38
|
return [];
|
|
36
39
|
const records = raw;
|
|
@@ -44,7 +47,7 @@ export async function readRecords() {
|
|
|
44
47
|
return filtered;
|
|
45
48
|
}
|
|
46
49
|
async function writeRecords(records) {
|
|
47
|
-
await
|
|
50
|
+
await backend.write(records);
|
|
48
51
|
}
|
|
49
52
|
// Serialize all read-modify-write operations against licenses.json. Each
|
|
50
53
|
// mutating function does (readRecords → mutate → writeRecords); without a lock,
|
|
@@ -54,7 +57,8 @@ async function writeRecords(records) {
|
|
|
54
57
|
// back-to-back) racing with /confirm/* writes from buyer flows.
|
|
55
58
|
let writeChain = Promise.resolve();
|
|
56
59
|
function withWriteLock(fn) {
|
|
57
|
-
const
|
|
60
|
+
const locked = () => (backend.withLock ? backend.withLock(fn) : fn());
|
|
61
|
+
const result = writeChain.then(locked, locked);
|
|
58
62
|
writeChain = result.then(() => { }, () => { });
|
|
59
63
|
return result;
|
|
60
64
|
}
|
|
@@ -64,29 +68,47 @@ function recordsForApp(records, zkAppAddress) {
|
|
|
64
68
|
return records.filter(r => r.zkAppAddress === zkAppAddress);
|
|
65
69
|
}
|
|
66
70
|
// Rebuild the license MerkleMap for a single zkApp. Only inserts entries
|
|
67
|
-
// with expirySlot > 0.
|
|
71
|
+
// with expirySlot > 0. The value stored at each key is `leaf.hash()` — the
|
|
72
|
+
// Poseidon commitment over (licenseHash, expirySlot, cap, deviceSlotsRoot,
|
|
73
|
+
// deviceSlotsFilled) — matching what LicensingApp writes. Records that
|
|
74
|
+
// predate device binding rebuild to a leaf with empty slots (see
|
|
75
|
+
// leafFromRecord for the exact defaults); on those records the rebuilt
|
|
76
|
+
// root matches what the old contract wrote, but any mutation call will
|
|
77
|
+
// fail the in-circuit hash check until the missing fields are backfilled
|
|
78
|
+
// from chain events.
|
|
68
79
|
export function buildMap(records, zkAppAddress) {
|
|
69
80
|
const map = new MerkleMap();
|
|
70
81
|
for (const r of recordsForApp(records, zkAppAddress)) {
|
|
71
82
|
if (r.expirySlot !== 0) {
|
|
72
|
-
map.set(Field(r.licenseHash),
|
|
83
|
+
map.set(Field(r.licenseHash), leafHash(leafFromRecord(r)));
|
|
73
84
|
}
|
|
74
85
|
}
|
|
75
86
|
return map;
|
|
76
87
|
}
|
|
88
|
+
// The license expiry the escrow commitment was made against — the expiry at
|
|
89
|
+
// purchase time, before any renewal. `initialExpirySlot` is written at every
|
|
90
|
+
// issue path (prove/buy staging, the licenseIssued event apply); the
|
|
91
|
+
// `expirySlot` fallback only covers legacy records, which cannot have been
|
|
92
|
+
// renewed without also receiving the backfill.
|
|
93
|
+
export function escrowExpirySlot(r) {
|
|
94
|
+
return r.initialExpirySlot ?? r.expirySlot;
|
|
95
|
+
}
|
|
77
96
|
// Rebuild the escrow MerkleMap for a single zkApp:
|
|
78
|
-
// licenseHash → escrowCommitment(amount, slot, buyerKey).
|
|
79
|
-
// entries with live escrow (not released, not refunded
|
|
97
|
+
// licenseHash → escrowCommitment(amount, slot, buyerKey, initialExpirySlot).
|
|
98
|
+
// Only includes entries with live escrow (not released, not refunded, not an
|
|
99
|
+
// escrowless purchase) and a known buyer. Must match LicensingApp.ts
|
|
100
|
+
// escrowCommitment field-for-field.
|
|
80
101
|
export function buildEscrowMap(records, zkAppAddress) {
|
|
81
102
|
const map = new MerkleMap();
|
|
82
103
|
for (const r of recordsForApp(records, zkAppAddress)) {
|
|
83
|
-
if (!r.released && !r.refunded && r.purchaseSlot > 0 && r.buyerAddress) {
|
|
104
|
+
if (!r.released && !r.refunded && !r.escrowless && r.purchaseSlot > 0 && r.buyerAddress) {
|
|
84
105
|
const buyerKey = PublicKey.fromBase58(r.buyerAddress);
|
|
85
106
|
const commitment = Poseidon.hash([
|
|
86
107
|
UInt64.from(BigInt(r.purchaseAmount)).value,
|
|
87
108
|
UInt32.from(r.purchaseSlot).value,
|
|
88
109
|
buyerKey.x,
|
|
89
110
|
buyerKey.isOdd.toField(),
|
|
111
|
+
UInt32.from(escrowExpirySlot(r)).value,
|
|
90
112
|
]);
|
|
91
113
|
map.set(Field(r.licenseHash), commitment);
|
|
92
114
|
}
|
|
@@ -124,20 +146,79 @@ export async function getLicense(zkAppAddress, licenseHash) {
|
|
|
124
146
|
}
|
|
125
147
|
// Determine the status of a license. A license in the 7-day grace window is
|
|
126
148
|
// still considered 'active' so renewal is not urgently forced.
|
|
127
|
-
export function licenseStatus(record, currentSlot) {
|
|
149
|
+
export function licenseStatus(record, currentSlot, forkActivationSlot = 0) {
|
|
128
150
|
if (!record)
|
|
129
151
|
return 'unknown';
|
|
152
|
+
if (record.transferredTo)
|
|
153
|
+
return 'transferred';
|
|
130
154
|
if (record.expirySlot === 0)
|
|
131
155
|
return 'refunded';
|
|
132
|
-
if (record.expirySlot + GRACE_PERIOD_N < currentSlot)
|
|
156
|
+
if (effectiveExpirySlot(record.expirySlot, forkActivationSlot) + GRACE_PERIOD_N < currentSlot)
|
|
133
157
|
return 'expired';
|
|
134
158
|
return 'active';
|
|
135
159
|
}
|
|
160
|
+
/**
|
|
161
|
+
* A redeployed app's successor starts with every license of `from` (its
|
|
162
|
+
* frozen tree, checked on chain): copy them to `to`, marked carriedOverFrom
|
|
163
|
+
* (not new sales). Refunded and already-present licenses are skipped.
|
|
164
|
+
* Returns how many were copied.
|
|
165
|
+
*/
|
|
166
|
+
export async function carryOverRecords(from, to) {
|
|
167
|
+
return withWriteLock(async () => {
|
|
168
|
+
const records = await readRecords();
|
|
169
|
+
const present = new Set(records.filter(r => r.zkAppAddress === to).map(r => r.licenseHash));
|
|
170
|
+
const copies = records
|
|
171
|
+
.filter(r => r.zkAppAddress === from && r.expirySlot > 0 && !present.has(r.licenseHash))
|
|
172
|
+
.map((r) => ({
|
|
173
|
+
// License state only: the sale, its renewals and its escrow stay on
|
|
174
|
+
// the earlier deployment's record, so they're counted once.
|
|
175
|
+
zkAppAddress: to, carriedOverFrom: from,
|
|
176
|
+
licenseHash: r.licenseHash, expirySlot: r.expirySlot,
|
|
177
|
+
purchaseSlot: 0, purchaseAmount: '0', txHash: r.txHash, createdAt: r.createdAt,
|
|
178
|
+
buyerAddress: r.buyerAddress, deviceCap: r.deviceCap, deviceSlotsRoot: r.deviceSlotsRoot,
|
|
179
|
+
deviceSlotsFilled: r.deviceSlotsFilled, devices: r.devices,
|
|
180
|
+
initialExpirySlot: r.initialExpirySlot, tier: r.tier,
|
|
181
|
+
renewedAtLeastOnce: r.renewedAtLeastOnce || (r.renewals?.length ?? 0) > 0 || undefined,
|
|
182
|
+
}));
|
|
183
|
+
if (copies.length)
|
|
184
|
+
await writeRecords([...records, ...copies]);
|
|
185
|
+
return copies.length;
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* A forced retirement left `zkAppAddress`'s escrowed purchases on the
|
|
190
|
+
* retired contract: marks them stranded (no refund or release follows).
|
|
191
|
+
* Returns how many.
|
|
192
|
+
*/
|
|
193
|
+
export async function markEscrowStranded(zkAppAddress, txHash, at = new Date().toISOString()) {
|
|
194
|
+
return withWriteLock(async () => {
|
|
195
|
+
const records = await readRecords();
|
|
196
|
+
let n = 0;
|
|
197
|
+
for (const r of records) {
|
|
198
|
+
if (r.zkAppAddress !== zkAppAddress || r.released || r.refunded || r.escrowless || r.escrowStranded || !(r.purchaseSlot > 0))
|
|
199
|
+
continue;
|
|
200
|
+
r.escrowStranded = { txHash, at };
|
|
201
|
+
n++;
|
|
202
|
+
}
|
|
203
|
+
if (n)
|
|
204
|
+
await writeRecords(records);
|
|
205
|
+
return n;
|
|
206
|
+
});
|
|
207
|
+
}
|
|
136
208
|
// Add or update a license record (upsert by composite key).
|
|
137
209
|
export async function upsertLicense(record) {
|
|
138
210
|
if (!record.zkAppAddress) {
|
|
139
211
|
throw new Error('upsertLicense: record.zkAppAddress is required');
|
|
140
212
|
}
|
|
213
|
+
// Populate the empty-slot mirror at insert time when the license is capped.
|
|
214
|
+
// Without this, /confirm/buy writes deviceCap:N but leaves deviceSlotsRoot
|
|
215
|
+
// and deviceSlotsFilled undefined until the first bind — leafFromRecord's
|
|
216
|
+
// fallbacks paper over it for hash reconstruction, but every consumer that
|
|
217
|
+
// reads the mirror directly (preflight logs, /license responses, offline
|
|
218
|
+
// verify) would see undefined and either misreport or need its own fallback.
|
|
219
|
+
if ((record.deviceCap ?? 0) > 0 && (record.deviceSlotsRoot === undefined || record.deviceSlotsFilled === undefined)) {
|
|
220
|
+
refreshSlotMirror(record);
|
|
221
|
+
}
|
|
141
222
|
return withWriteLock(async () => {
|
|
142
223
|
const records = await readRecords();
|
|
143
224
|
const idx = records.findIndex(r => r.zkAppAddress === record.zkAppAddress && r.licenseHash === record.licenseHash);
|
|
@@ -176,17 +257,47 @@ export async function updateExpiry(zkAppAddress, licenseHash, expirySlot, opts =
|
|
|
176
257
|
return true;
|
|
177
258
|
});
|
|
178
259
|
}
|
|
179
|
-
// Clear license and escrow data after a
|
|
180
|
-
|
|
260
|
+
// Clear license and escrow data after a refund. Also flips `refunded`.
|
|
261
|
+
//
|
|
262
|
+
// Two modes:
|
|
263
|
+
// provisional=false (default, called from archive event-sync on a canonical
|
|
264
|
+
// refundIssued event): sets refunded=true, zeros expiry/purchase, clears
|
|
265
|
+
// pending. This is the authoritative confirm — includes upgrading a prior
|
|
266
|
+
// 'fast' flip.
|
|
267
|
+
// provisional=true (called from the tx-land watcher on first bestchain
|
|
268
|
+
// observation): sets refunded='fast' and records provisionalFlipAtSlot,
|
|
269
|
+
// but does NOT zero expirySlot/purchaseSlot yet — those stay live until
|
|
270
|
+
// the event is canonical, so a reorg revert restores refunded=false
|
|
271
|
+
// without needing snapshots.
|
|
272
|
+
export async function recordRefund(zkAppAddress, licenseHash, opts) {
|
|
181
273
|
return withWriteLock(async () => {
|
|
182
274
|
const records = await readRecords();
|
|
183
275
|
const record = records.find(r => r.zkAppAddress === zkAppAddress && r.licenseHash === licenseHash);
|
|
184
276
|
if (!record)
|
|
185
277
|
return false;
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
278
|
+
if (opts?.provisional) {
|
|
279
|
+
// Preserve expirySlot/purchaseSlot for revertability. UI treats
|
|
280
|
+
// 'fast' as refunded (truthy); circuit ops see 409 via pre-flight
|
|
281
|
+
// guards if the local state diverges from chain during the window.
|
|
282
|
+
if (record.refunded !== true)
|
|
283
|
+
record.refunded = 'fast';
|
|
284
|
+
if (opts.nowSlot !== undefined)
|
|
285
|
+
record.provisionalFlipAtSlot = opts.nowSlot;
|
|
286
|
+
}
|
|
287
|
+
else {
|
|
288
|
+
record.expirySlot = 0;
|
|
289
|
+
record.purchaseSlot = 0;
|
|
290
|
+
record.purchaseAmount = '0';
|
|
291
|
+
record.refunded = true;
|
|
292
|
+
// /confirm/refund wrote pending:true optimistically; the on-chain event
|
|
293
|
+
// landing is what authorizes clearing it. Without this the SDK poller
|
|
294
|
+
// (which requires pending===false && status==='refunded') hangs forever.
|
|
295
|
+
delete record.pending;
|
|
296
|
+
delete record.pendingPrior;
|
|
297
|
+
delete record.provedAtSlot;
|
|
298
|
+
// Any prior 'fast' provisional flip is now confirmed — drop the marker.
|
|
299
|
+
delete record.provisionalFlipAtSlot;
|
|
300
|
+
}
|
|
190
301
|
await writeRecords(records);
|
|
191
302
|
return true;
|
|
192
303
|
});
|
|
@@ -194,15 +305,63 @@ export async function recordRefund(zkAppAddress, licenseHash) {
|
|
|
194
305
|
// Mark escrow as released. Preserves purchaseAmount/purchaseSlot so stats can
|
|
195
306
|
// compute released revenue. The `released` flag is the truth signal —
|
|
196
307
|
// buildEscrowMap and getReleasableRecords filter on it directly.
|
|
197
|
-
|
|
308
|
+
//
|
|
309
|
+
// Two modes: same semantics as recordRefund above.
|
|
310
|
+
// provisional=true → released='fast', provisionalFlipAtSlot=nowSlot
|
|
311
|
+
// provisional=false → released=true (upgrades any 'fast' state), clears
|
|
312
|
+
// provisionalFlipAtSlot
|
|
313
|
+
export async function recordRelease(zkAppAddress, licenseHash, releaseSlot, txHash, opts) {
|
|
198
314
|
return withWriteLock(async () => {
|
|
199
315
|
const records = await readRecords();
|
|
200
316
|
const record = records.find(r => r.zkAppAddress === zkAppAddress && r.licenseHash === licenseHash);
|
|
201
317
|
if (!record)
|
|
202
318
|
return false;
|
|
203
|
-
|
|
319
|
+
if (opts?.provisional) {
|
|
320
|
+
if (record.released !== true)
|
|
321
|
+
record.released = 'fast';
|
|
322
|
+
if (opts.nowSlot !== undefined)
|
|
323
|
+
record.provisionalFlipAtSlot = opts.nowSlot;
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
record.released = true;
|
|
327
|
+
delete record.provisionalFlipAtSlot;
|
|
328
|
+
}
|
|
204
329
|
if (releaseSlot !== undefined)
|
|
205
330
|
record.releaseSlot = releaseSlot;
|
|
331
|
+
if (txHash !== undefined)
|
|
332
|
+
record.releaseTxHash = txHash;
|
|
333
|
+
await writeRecords(records);
|
|
334
|
+
return true;
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
// Roll back a provisional 'fast' flip that never got confirmed by the archive.
|
|
338
|
+
// Called by the reorg-revert reaper after REORG_REVERT_AFTER_SLOTS elapses
|
|
339
|
+
// without a canonical event. Only reverts if the field is still 'fast' —
|
|
340
|
+
// confirmed (true) flips are irreversible from this path.
|
|
341
|
+
export async function revertProvisionalFlip(zkAppAddress, licenseHash, kind) {
|
|
342
|
+
return withWriteLock(async () => {
|
|
343
|
+
const records = await readRecords();
|
|
344
|
+
const record = records.find(r => r.zkAppAddress === zkAppAddress && r.licenseHash === licenseHash);
|
|
345
|
+
if (!record)
|
|
346
|
+
return false;
|
|
347
|
+
if (kind === 'release') {
|
|
348
|
+
if (record.released !== 'fast')
|
|
349
|
+
return false;
|
|
350
|
+
record.released = false;
|
|
351
|
+
delete record.releaseSlot;
|
|
352
|
+
delete record.releaseTxHash;
|
|
353
|
+
}
|
|
354
|
+
else {
|
|
355
|
+
if (record.refunded !== 'fast')
|
|
356
|
+
return false;
|
|
357
|
+
record.refunded = false;
|
|
358
|
+
// expirySlot/purchaseSlot were never zeroed for provisional refunds, so
|
|
359
|
+
// nothing to restore there.
|
|
360
|
+
}
|
|
361
|
+
// Clear the marker only if no OTHER field is still provisional.
|
|
362
|
+
if (record.released !== 'fast' && record.refunded !== 'fast') {
|
|
363
|
+
delete record.provisionalFlipAtSlot;
|
|
364
|
+
}
|
|
206
365
|
await writeRecords(records);
|
|
207
366
|
return true;
|
|
208
367
|
});
|
|
@@ -217,6 +376,7 @@ export async function confirmRecord(zkAppAddress, licenseHash) {
|
|
|
217
376
|
if (!record.pending)
|
|
218
377
|
return false;
|
|
219
378
|
delete record.pending;
|
|
379
|
+
delete record.pendingPrior;
|
|
220
380
|
delete record.provedAtSlot;
|
|
221
381
|
await writeRecords(records);
|
|
222
382
|
return true;
|
|
@@ -237,6 +397,7 @@ export async function applyLicenseIssued(zkAppAddress, licenseHash, fields) {
|
|
|
237
397
|
if (record) {
|
|
238
398
|
if (record.pending) {
|
|
239
399
|
delete record.pending;
|
|
400
|
+
delete record.pendingPrior;
|
|
240
401
|
delete record.provedAtSlot;
|
|
241
402
|
dirty = true;
|
|
242
403
|
}
|
|
@@ -252,9 +413,29 @@ export async function applyLicenseIssued(zkAppAddress, licenseHash, fields) {
|
|
|
252
413
|
record.escrowless = true;
|
|
253
414
|
dirty = true;
|
|
254
415
|
}
|
|
416
|
+
// Backfill leaf fields if the record was created before the event
|
|
417
|
+
// carried them, or if a prior partial rehydrate is still missing them.
|
|
418
|
+
if (fields.deviceCap !== undefined && record.deviceCap === undefined) {
|
|
419
|
+
record.deviceCap = fields.deviceCap;
|
|
420
|
+
dirty = true;
|
|
421
|
+
}
|
|
422
|
+
if (fields.deviceSlotsRoot !== undefined && record.deviceSlotsRoot === undefined) {
|
|
423
|
+
record.deviceSlotsRoot = fields.deviceSlotsRoot;
|
|
424
|
+
dirty = true;
|
|
425
|
+
}
|
|
426
|
+
if (fields.deviceSlotsFilled !== undefined && record.deviceSlotsFilled === undefined) {
|
|
427
|
+
record.deviceSlotsFilled = fields.deviceSlotsFilled;
|
|
428
|
+
dirty = true;
|
|
429
|
+
}
|
|
430
|
+
if (record.buyerAddress === undefined) {
|
|
431
|
+
// Legacy record predating the required-buyerAddress change — backfill
|
|
432
|
+
// from the fresh event so it becomes enumerable via /licenses?buyer=.
|
|
433
|
+
record.buyerAddress = fields.buyerAddress;
|
|
434
|
+
dirty = true;
|
|
435
|
+
}
|
|
255
436
|
}
|
|
256
437
|
else {
|
|
257
|
-
|
|
438
|
+
const inserted = {
|
|
258
439
|
zkAppAddress,
|
|
259
440
|
licenseHash,
|
|
260
441
|
expirySlot: fields.expirySlot,
|
|
@@ -265,13 +446,200 @@ export async function applyLicenseIssued(zkAppAddress, licenseHash, fields) {
|
|
|
265
446
|
initialExpirySlot: fields.expirySlot,
|
|
266
447
|
...(fields.tier ? { tier: fields.tier } : {}),
|
|
267
448
|
...(fields.escrowless === true ? { escrowless: true } : {}),
|
|
268
|
-
|
|
449
|
+
...(fields.deviceCap !== undefined ? { deviceCap: fields.deviceCap } : {}),
|
|
450
|
+
...(fields.deviceSlotsRoot !== undefined ? { deviceSlotsRoot: fields.deviceSlotsRoot } : {}),
|
|
451
|
+
...(fields.deviceSlotsFilled !== undefined ? { deviceSlotsFilled: fields.deviceSlotsFilled } : {}),
|
|
452
|
+
buyerAddress: fields.buyerAddress,
|
|
453
|
+
};
|
|
454
|
+
// Same rationale as upsertLicense: populate the empty-slot mirror on
|
|
455
|
+
// first insert so the record is immediately queryable without relying
|
|
456
|
+
// on leafFromRecord's undefined fallbacks.
|
|
457
|
+
if ((inserted.deviceCap ?? 0) > 0 && (inserted.deviceSlotsRoot === undefined || inserted.deviceSlotsFilled === undefined)) {
|
|
458
|
+
refreshSlotMirror(inserted);
|
|
459
|
+
}
|
|
460
|
+
records.push(inserted);
|
|
269
461
|
dirty = true;
|
|
270
462
|
}
|
|
271
463
|
if (dirty)
|
|
272
464
|
await writeRecords(records);
|
|
273
465
|
});
|
|
274
466
|
}
|
|
467
|
+
// Apply a licenseRenewed event atomically: clear any pending /confirm/renew
|
|
468
|
+
// write, align expirySlot with the event, and flip renewedAtLeastOnce.
|
|
469
|
+
// Symmetric to applyLicenseIssued — the archive-events path is what closes
|
|
470
|
+
// out a renew that the bestChain sweep missed (tx landed after the sweep's
|
|
471
|
+
// BESTCHAIN_DEPTH window rolled past), and without a pending-clear step here
|
|
472
|
+
// the flag on a landed record could be stuck forever.
|
|
473
|
+
//
|
|
474
|
+
// Does NOT append to renewals[] — that log is populated at /confirm/renew
|
|
475
|
+
// time from the intent (which carries amount + txHash); the archive event
|
|
476
|
+
// carries only newExpiry, so replaying it must not overwrite the richer
|
|
477
|
+
// confirm-time entry.
|
|
478
|
+
export async function applyLicenseRenewed(zkAppAddress, licenseHash, fields) {
|
|
479
|
+
return withWriteLock(async () => {
|
|
480
|
+
const records = await readRecords();
|
|
481
|
+
const record = records.find(r => r.zkAppAddress === zkAppAddress && r.licenseHash === licenseHash);
|
|
482
|
+
if (!record)
|
|
483
|
+
return false;
|
|
484
|
+
let dirty = false;
|
|
485
|
+
if (record.pending) {
|
|
486
|
+
delete record.pending;
|
|
487
|
+
delete record.pendingPrior;
|
|
488
|
+
delete record.provedAtSlot;
|
|
489
|
+
dirty = true;
|
|
490
|
+
}
|
|
491
|
+
if (record.expirySlot !== fields.newExpiry) {
|
|
492
|
+
record.expirySlot = fields.newExpiry;
|
|
493
|
+
dirty = true;
|
|
494
|
+
}
|
|
495
|
+
if (!record.renewedAtLeastOnce) {
|
|
496
|
+
record.renewedAtLeastOnce = true;
|
|
497
|
+
dirty = true;
|
|
498
|
+
}
|
|
499
|
+
if (dirty)
|
|
500
|
+
await writeRecords(records);
|
|
501
|
+
return true;
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
/**
|
|
505
|
+
* A license moved to a new owner key (transferLicense): the license state
|
|
506
|
+
* (expiry, cap, bound devices) goes to a record under `to`, with no sale of
|
|
507
|
+
* its own (the sale and its receipt stay on the original record), listed
|
|
508
|
+
* under `wallet` (the transfer's sender, the new owner's wallet, which
|
|
509
|
+
* paid), and the original leaves the licenses tree (expirySlot 0) marked
|
|
510
|
+
* `transferredTo`.
|
|
511
|
+
*/
|
|
512
|
+
export async function applyLicenseTransferred(zkAppAddress, from, to, opts = {}) {
|
|
513
|
+
return withWriteLock(async () => {
|
|
514
|
+
const records = await readRecords();
|
|
515
|
+
const old = records.find(r => r.zkAppAddress === zkAppAddress && r.licenseHash === from);
|
|
516
|
+
if (!old)
|
|
517
|
+
return false;
|
|
518
|
+
if (old.transferredTo === to)
|
|
519
|
+
return true; // already applied
|
|
520
|
+
const moved = {
|
|
521
|
+
zkAppAddress, licenseHash: to, expirySlot: old.expirySlot, purchaseSlot: 0, purchaseAmount: '0',
|
|
522
|
+
txHash: opts.txHash ?? '', createdAt: new Date().toISOString(), buyerAddress: opts.wallet ?? '',
|
|
523
|
+
transferredFrom: from,
|
|
524
|
+
...(old.deviceCap !== undefined ? { deviceCap: old.deviceCap } : {}),
|
|
525
|
+
...(old.deviceSlotsRoot !== undefined ? { deviceSlotsRoot: old.deviceSlotsRoot } : {}),
|
|
526
|
+
...(old.deviceSlotsFilled !== undefined ? { deviceSlotsFilled: old.deviceSlotsFilled } : {}),
|
|
527
|
+
...(old.devices ? { devices: old.devices.map(d => ({ ...d })) } : {}),
|
|
528
|
+
...(old.escrowless ? { escrowless: true } : {}),
|
|
529
|
+
...(old.tier ? { tier: old.tier } : {}),
|
|
530
|
+
};
|
|
531
|
+
const existing = records.findIndex(r => r.zkAppAddress === zkAppAddress && r.licenseHash === to);
|
|
532
|
+
if (existing >= 0)
|
|
533
|
+
records[existing] = moved;
|
|
534
|
+
else
|
|
535
|
+
records.push(moved);
|
|
536
|
+
old.transferredTo = to;
|
|
537
|
+
old.expirySlot = 0;
|
|
538
|
+
delete old.devices;
|
|
539
|
+
delete old.pending;
|
|
540
|
+
delete old.pendingPrior;
|
|
541
|
+
delete old.provedAtSlot;
|
|
542
|
+
await writeRecords(records);
|
|
543
|
+
return true;
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
// Recompute deviceSlotsRoot + deviceSlotsFilled from the record's mirror after
|
|
547
|
+
// a bind/unbind mutation. `leafFromRecord` uses those two persisted fields when
|
|
548
|
+
// building the on-chain leaf hash; if they drift from the on-chain state the
|
|
549
|
+
// next mutation call fails the in-circuit leaf-hash assert. Mirror the exact
|
|
550
|
+
// packing the circuit uses (packSlotTimes: freedAt in low 32 bits, boundAt in
|
|
551
|
+
// high 32) so the fold matches the on-chain deviceSlotsRoot bit-for-bit.
|
|
552
|
+
function refreshSlotMirror(record) {
|
|
553
|
+
const devices = record.devices ?? [];
|
|
554
|
+
const occupied = [];
|
|
555
|
+
const freedAt = [];
|
|
556
|
+
for (let i = 0; i < DEVICE_SLOT_CAP_N; i++) {
|
|
557
|
+
const entry = devices.find(d => d.slotIndex === i);
|
|
558
|
+
const occ = entry?.deviceCommitment ?? '0';
|
|
559
|
+
occupied.push(Field(occ));
|
|
560
|
+
const boundAt = BigInt(entry?.boundAtSlot ?? 0);
|
|
561
|
+
const freed = BigInt(entry?.freedAtSlot ?? 0);
|
|
562
|
+
// packSlotTimes(boundAt, freedAt) in licenseLeaf.ts: freedAt low 32, boundAt high 32.
|
|
563
|
+
const packed = freed + (boundAt << 32n);
|
|
564
|
+
freedAt.push(Field(packed));
|
|
565
|
+
}
|
|
566
|
+
record.deviceSlotsRoot = computeDeviceSlotsRoot(occupied, freedAt).toString();
|
|
567
|
+
record.deviceSlotsFilled = devices.filter(d => d.deviceCommitment !== '0').length;
|
|
568
|
+
}
|
|
569
|
+
// Apply a deviceBound event atomically: mirrors the on-chain slot mutation
|
|
570
|
+
// into the record.devices[] array and recomputes deviceSlotsRoot / filled so
|
|
571
|
+
// leafFromRecord reconstructs the exact leaf hash the chain committed.
|
|
572
|
+
//
|
|
573
|
+
// `boundAtSlot` MUST be the circuit's proof-time `globalSlotSinceGenesis` (the
|
|
574
|
+
// value emitted in `DeviceBoundEvent.boundAtSlot`). The block slot when the tx
|
|
575
|
+
// landed is NOT interchangeable: TOLERANCE_WINDOW allows them to differ, and
|
|
576
|
+
// any drift flips the packed `freedAt` field → wrong leaf → root divergence.
|
|
577
|
+
export async function applyDeviceBound(zkAppAddress, licenseHash, fields) {
|
|
578
|
+
return withWriteLock(async () => {
|
|
579
|
+
const records = await readRecords();
|
|
580
|
+
const record = records.find(r => r.zkAppAddress === zkAppAddress && r.licenseHash === licenseHash);
|
|
581
|
+
if (!record)
|
|
582
|
+
return false;
|
|
583
|
+
const devices = (record.devices ??= []);
|
|
584
|
+
// Ensure the array is long enough — pad with empty slots.
|
|
585
|
+
while (devices.length <= fields.slotIndex) {
|
|
586
|
+
devices.push({ slotIndex: devices.length, deviceCommitment: '0', boundAtSlot: 0, freedAtSlot: 0 });
|
|
587
|
+
}
|
|
588
|
+
devices[fields.slotIndex] = {
|
|
589
|
+
slotIndex: fields.slotIndex,
|
|
590
|
+
deviceCommitment: fields.deviceCommitment,
|
|
591
|
+
boundAtSlot: fields.boundAtSlot,
|
|
592
|
+
freedAtSlot: 0, // pristine → fresh bind resets freedAt
|
|
593
|
+
};
|
|
594
|
+
refreshSlotMirror(record);
|
|
595
|
+
await writeRecords(records);
|
|
596
|
+
return true;
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
// Apply a deviceUnbound event atomically. Preserves boundAtSlot for audit,
|
|
600
|
+
// stamps freedAtSlot for the cooldown timer the circuit's next bind enforces.
|
|
601
|
+
//
|
|
602
|
+
// `freedAtSlot` MUST be the circuit's proof-time `globalSlotSinceGenesis` (the
|
|
603
|
+
// value emitted in `DeviceUnboundEvent.freedAtSlot`). Same reason as
|
|
604
|
+
// `applyDeviceBound.boundAtSlot`.
|
|
605
|
+
export async function applyDeviceUnbound(zkAppAddress, licenseHash, fields) {
|
|
606
|
+
return withWriteLock(async () => {
|
|
607
|
+
const records = await readRecords();
|
|
608
|
+
const record = records.find(r => r.zkAppAddress === zkAppAddress && r.licenseHash === licenseHash);
|
|
609
|
+
if (!record || !record.devices)
|
|
610
|
+
return false;
|
|
611
|
+
const slot = record.devices.find(d => d.slotIndex === fields.slotIndex);
|
|
612
|
+
if (!slot)
|
|
613
|
+
return false;
|
|
614
|
+
slot.deviceCommitment = '0';
|
|
615
|
+
slot.freedAtSlot = fields.freedAtSlot;
|
|
616
|
+
// boundAtSlot stays as the last bind time — historical / audit.
|
|
617
|
+
refreshSlotMirror(record);
|
|
618
|
+
await writeRecords(records);
|
|
619
|
+
return true;
|
|
620
|
+
});
|
|
621
|
+
}
|
|
622
|
+
// Undo a pending change whose transaction failed on chain or never landed:
|
|
623
|
+
// restore the record it replaced (a renewal or refund), or remove it (a
|
|
624
|
+
// purchase). With `txHash`, only if the pending change is that transaction's.
|
|
625
|
+
export async function revertPending(zkAppAddress, licenseHash, txHash) {
|
|
626
|
+
return withWriteLock(async () => {
|
|
627
|
+
const records = await readRecords();
|
|
628
|
+
const idx = records.findIndex(r => r.zkAppAddress === zkAppAddress && r.licenseHash === licenseHash);
|
|
629
|
+
if (idx < 0)
|
|
630
|
+
return false;
|
|
631
|
+
const record = records[idx];
|
|
632
|
+
if (!record.pending || (txHash !== undefined && record.txHash !== txHash))
|
|
633
|
+
return false;
|
|
634
|
+
const outcome = record.pendingPrior ? 'restored' : 'removed';
|
|
635
|
+
if (record.pendingPrior)
|
|
636
|
+
records[idx] = record.pendingPrior;
|
|
637
|
+
else
|
|
638
|
+
records.splice(idx, 1);
|
|
639
|
+
await writeRecords(records);
|
|
640
|
+
return outcome;
|
|
641
|
+
});
|
|
642
|
+
}
|
|
275
643
|
// Delete a record entirely (used to reap stale pending entries the buyer never submitted).
|
|
276
644
|
export async function deleteRecord(zkAppAddress, licenseHash) {
|
|
277
645
|
return withWriteLock(async () => {
|
|
@@ -296,6 +664,8 @@ export async function getReleasableRecords(currentSlot) {
|
|
|
296
664
|
const records = await readRecords();
|
|
297
665
|
return records.filter((r) => !r.released &&
|
|
298
666
|
!r.refunded &&
|
|
667
|
+
!r.escrowless &&
|
|
668
|
+
!r.escrowStranded &&
|
|
299
669
|
r.purchaseSlot > 0 &&
|
|
300
670
|
r.zkAppAddress &&
|
|
301
671
|
currentSlot > r.purchaseSlot + REFUND_WINDOW_N);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"licenseStore.js","sourceRoot":"","sources":["../src/licenseStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export type TrustlessLicenseVerification = {
|
|
2
|
+
valid: boolean;
|
|
3
|
+
expiresAt: string | null;
|
|
4
|
+
expirySlot: number;
|
|
5
|
+
inGracePeriod: boolean;
|
|
6
|
+
remainingDays: number;
|
|
7
|
+
reason: string | null;
|
|
8
|
+
trustless: true;
|
|
9
|
+
/** The contract address the license was checked at (another generation of the app's contract, if that's where it is). */
|
|
10
|
+
resolvedAddress: string;
|
|
11
|
+
/** LicensingApp release (generation) of that contract, from its verification key. */
|
|
12
|
+
generation: number | null;
|
|
13
|
+
/** Current slot, as the Mina node reported it. */
|
|
14
|
+
slot: number;
|
|
15
|
+
/** Whether the app's generation list came signed by the platform ("verified") or only the given address and its on-chain successors were checked. */
|
|
16
|
+
generations: 'verified' | 'given-address-only';
|
|
17
|
+
};
|
|
18
|
+
type ContractHead = {
|
|
19
|
+
found: boolean;
|
|
20
|
+
root?: string;
|
|
21
|
+
forkSlot?: number;
|
|
22
|
+
vkHash?: string;
|
|
23
|
+
editState?: string;
|
|
24
|
+
setPermissions?: string;
|
|
25
|
+
setVerificationKey?: string;
|
|
26
|
+
slot: number;
|
|
27
|
+
};
|
|
28
|
+
/** Why a contract isn't a genuine, locked LicensingApp, or null. */
|
|
29
|
+
export declare function contractProblem(c: ContractHead): string | null;
|
|
30
|
+
export declare function verifyLicenseTrustless(opts: {
|
|
31
|
+
keeperUrl: string;
|
|
32
|
+
network: 'devnet' | 'mainnet';
|
|
33
|
+
zkAppAddress: string;
|
|
34
|
+
licenseHash: string;
|
|
35
|
+
/** Your own Mina node (default: a public one per network). */
|
|
36
|
+
graphqlUrl?: string;
|
|
37
|
+
fetcher?: typeof fetch;
|
|
38
|
+
pinnedPublicKeysBase64?: readonly string[];
|
|
39
|
+
/** Wait between the two witness reads when the keeper is behind the chain (ms). */
|
|
40
|
+
retryDelayMs?: number;
|
|
41
|
+
}): Promise<TrustlessLicenseVerification>;
|
|
42
|
+
export {};
|
|
43
|
+
//# sourceMappingURL=licenseTrustless.d.ts.map
|