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,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* licenseLeaf.ts
|
|
3
|
+
*
|
|
4
|
+
* On-chain leaf value stored at every occupied `licensesRoot` slot. Bundles
|
|
5
|
+
* the license expiry with the device-binding state (cap, slot commitments,
|
|
6
|
+
* fill counter) so a single tree lookup returns everything a verifier or a
|
|
7
|
+
* `/prove/bind` call needs.
|
|
8
|
+
*
|
|
9
|
+
* Wire shape (in order of hash preimage):
|
|
10
|
+
* licenseHash Field the tree key, also carried in the leaf
|
|
11
|
+
* so a stolen witness can't be re-pointed
|
|
12
|
+
* at another entry. Doubles as the owner-
|
|
13
|
+
* pubkey commitment — buyLicense asserts
|
|
14
|
+
* licenseHash == Poseidon(pk.x, pk.isOdd)
|
|
15
|
+
* so bind/unbind's ownership check reads
|
|
16
|
+
* the same field as the tree key. Storing
|
|
17
|
+
* them separately would be pure redundancy.
|
|
18
|
+
* expirySlot UInt32→Field UInt32 packed into a Field
|
|
19
|
+
* cap UInt32→Field 0 disables /prove/bind; ≤DEVICE_SLOT_CAP
|
|
20
|
+
* (kept as UInt32 in-circuit because o1js's
|
|
21
|
+
* provable types don't include UInt8)
|
|
22
|
+
* deviceSlotsRoot Field Poseidon fold over the 10 slot fields
|
|
23
|
+
* below (2 fields × DEVICE_SLOT_CAP)
|
|
24
|
+
* deviceSlotsFilled UInt32→Field how many of the DEVICE_SLOT_CAP slots
|
|
25
|
+
* are currently non-empty — carried
|
|
26
|
+
* alongside the fold so `bind()` can do
|
|
27
|
+
* a cheap "cap - filled > 0" check
|
|
28
|
+
* without re-summing the array
|
|
29
|
+
*
|
|
30
|
+
* DEVICE_SLOT_CAP is fixed at 5 so the slot arrays have a size known to the
|
|
31
|
+
* circuit at compile time. `cap` in the leaf may be smaller — it's a
|
|
32
|
+
* per-license limit; slots [cap..DEVICE_SLOT_CAP) must always stay empty
|
|
33
|
+
* (Field(0)) and `bind()` rejects any write to them. `cap = 0` disables
|
|
34
|
+
* binding entirely; `bind()` rejects immediately without ever touching a
|
|
35
|
+
* slot.
|
|
36
|
+
*
|
|
37
|
+
* Slot encoding (fields carried in the fold, per slot i):
|
|
38
|
+
* occupied[i] Field 0 (empty) or Poseidon(devicePubKeyHash)
|
|
39
|
+
* freedAt[i] Field packed (boundAtSlot << 32) | freedAtSlot; both
|
|
40
|
+
* are UInt32-range Mina slot numbers. On a fresh
|
|
41
|
+
* empty slot both halves are 0. On bind, boundAt
|
|
42
|
+
* gets the current slot and freedAt stays 0. On
|
|
43
|
+
* unbind, freedAt gets the current slot (boundAt
|
|
44
|
+
* is preserved for audit / cooldown math).
|
|
45
|
+
*
|
|
46
|
+
* The struct + helpers live in the SDK (not the circuit package) so both
|
|
47
|
+
* the on-chain `@method` bodies AND the off-chain backend / verifier /
|
|
48
|
+
* dashboards can share a single source of truth for the leaf hash. The
|
|
49
|
+
* circuit re-exports them from `LicensingApp.ts` so existing consumers
|
|
50
|
+
* that import from there keep working.
|
|
51
|
+
*/
|
|
52
|
+
import { Field, PublicKey, UInt32 } from 'o1js';
|
|
53
|
+
import type { LicenseRecord } from './licenseRecord.js';
|
|
54
|
+
export declare const DEVICE_SLOT_CAP_N = 5;
|
|
55
|
+
export declare const DEVICE_SLOT_CAP: UInt32;
|
|
56
|
+
export declare const EMPTY_DEVICE_SLOTS_ROOT: Field;
|
|
57
|
+
export declare function ownerPubKeyHash(pub: PublicKey): Field;
|
|
58
|
+
export declare function packSlotTimes(boundAtSlot: UInt32, freedAtSlot: UInt32): Field;
|
|
59
|
+
export declare function unpackSlotTimes(packed: Field): {
|
|
60
|
+
boundAtSlot: UInt32;
|
|
61
|
+
freedAtSlot: UInt32;
|
|
62
|
+
};
|
|
63
|
+
export declare function computeDeviceSlotsRoot(occupied: Field[], freedAt: Field[]): Field;
|
|
64
|
+
export declare const DeviceSlot: any;
|
|
65
|
+
export type DeviceSlot = any;
|
|
66
|
+
export declare function emptyDeviceSlot(): DeviceSlot;
|
|
67
|
+
export declare const DeviceSlots: any;
|
|
68
|
+
export type DeviceSlots = any;
|
|
69
|
+
export declare function emptyDeviceSlots(): DeviceSlots;
|
|
70
|
+
export declare function deviceSlotsHash(ds: DeviceSlots): Field;
|
|
71
|
+
export declare const LicenseLeaf: any;
|
|
72
|
+
export type LicenseLeaf = any;
|
|
73
|
+
export declare function leafHash(leaf: LicenseLeaf): Field;
|
|
74
|
+
export declare function freshLeaf(licenseHash: Field, expirySlot: UInt32, cap: UInt32): LicenseLeaf;
|
|
75
|
+
export declare function leafFromRecord(record: LicenseRecord): LicenseLeaf;
|
|
76
|
+
//# sourceMappingURL=licenseLeaf.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"licenseLeaf.d.ts","sourceRoot":"","sources":["../src/licenseLeaf.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AAEH,OAAO,EAAE,KAAK,EAAsB,SAAS,EAAU,MAAM,EAAE,MAAM,MAAM,CAAC;AAC5E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAMxD,eAAO,MAAM,iBAAiB,IAAI,CAAC;AACnC,eAAO,MAAM,eAAe,QAAiC,CAAC;AAK9D,eAAO,MAAM,uBAAuB,EAAE,KAErC,CAAC;AAOF,wBAAgB,eAAe,CAAC,GAAG,EAAE,SAAS,GAAG,KAAK,CAErD;AASD,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,KAAK,CAE7E;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,KAAK,GAAG;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAQ3F;AAMD,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,KAAK,EAAE,EACjB,OAAO,EAAG,KAAK,EAAE,GAChB,KAAK,CAYP;AAYD,eAAO,MAAM,UAAU,EAAE,GAGvB,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,GAAG,CAAC;AAE7B,wBAAgB,eAAe,IAAI,UAAU,CAE5C;AAID,eAAO,MAAM,WAAW,EAAE,GAExB,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,GAAG,CAAC;AAE9B,wBAAgB,gBAAgB,IAAI,WAAW,CAI9C;AAKD,wBAAgB,eAAe,CAAC,EAAE,EAAE,WAAW,GAAG,KAAK,CAMtD;AAMD,eAAO,MAAM,WAAW,EAAE,GAMxB,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,GAAG,CAAC;AAE9B,wBAAgB,QAAQ,CAAC,IAAI,EAAE,WAAW,GAAG,KAAK,CAQjD;AAID,wBAAgB,SAAS,CACvB,WAAW,EAAE,KAAK,EAClB,UAAU,EAAG,MAAM,EACnB,GAAG,EAAU,MAAM,GAClB,WAAW,CAQb;AAMD,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,GAAG,WAAW,CAUjE"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
// Copyright (c) 2025-2026 zkLicensing project developers
|
|
2
|
+
// SPDX-License-Identifier: BUSL-1.1
|
|
3
|
+
/**
|
|
4
|
+
* licenseLeaf.ts
|
|
5
|
+
*
|
|
6
|
+
* On-chain leaf value stored at every occupied `licensesRoot` slot. Bundles
|
|
7
|
+
* the license expiry with the device-binding state (cap, slot commitments,
|
|
8
|
+
* fill counter) so a single tree lookup returns everything a verifier or a
|
|
9
|
+
* `/prove/bind` call needs.
|
|
10
|
+
*
|
|
11
|
+
* Wire shape (in order of hash preimage):
|
|
12
|
+
* licenseHash Field the tree key, also carried in the leaf
|
|
13
|
+
* so a stolen witness can't be re-pointed
|
|
14
|
+
* at another entry. Doubles as the owner-
|
|
15
|
+
* pubkey commitment — buyLicense asserts
|
|
16
|
+
* licenseHash == Poseidon(pk.x, pk.isOdd)
|
|
17
|
+
* so bind/unbind's ownership check reads
|
|
18
|
+
* the same field as the tree key. Storing
|
|
19
|
+
* them separately would be pure redundancy.
|
|
20
|
+
* expirySlot UInt32→Field UInt32 packed into a Field
|
|
21
|
+
* cap UInt32→Field 0 disables /prove/bind; ≤DEVICE_SLOT_CAP
|
|
22
|
+
* (kept as UInt32 in-circuit because o1js's
|
|
23
|
+
* provable types don't include UInt8)
|
|
24
|
+
* deviceSlotsRoot Field Poseidon fold over the 10 slot fields
|
|
25
|
+
* below (2 fields × DEVICE_SLOT_CAP)
|
|
26
|
+
* deviceSlotsFilled UInt32→Field how many of the DEVICE_SLOT_CAP slots
|
|
27
|
+
* are currently non-empty — carried
|
|
28
|
+
* alongside the fold so `bind()` can do
|
|
29
|
+
* a cheap "cap - filled > 0" check
|
|
30
|
+
* without re-summing the array
|
|
31
|
+
*
|
|
32
|
+
* DEVICE_SLOT_CAP is fixed at 5 so the slot arrays have a size known to the
|
|
33
|
+
* circuit at compile time. `cap` in the leaf may be smaller — it's a
|
|
34
|
+
* per-license limit; slots [cap..DEVICE_SLOT_CAP) must always stay empty
|
|
35
|
+
* (Field(0)) and `bind()` rejects any write to them. `cap = 0` disables
|
|
36
|
+
* binding entirely; `bind()` rejects immediately without ever touching a
|
|
37
|
+
* slot.
|
|
38
|
+
*
|
|
39
|
+
* Slot encoding (fields carried in the fold, per slot i):
|
|
40
|
+
* occupied[i] Field 0 (empty) or Poseidon(devicePubKeyHash)
|
|
41
|
+
* freedAt[i] Field packed (boundAtSlot << 32) | freedAtSlot; both
|
|
42
|
+
* are UInt32-range Mina slot numbers. On a fresh
|
|
43
|
+
* empty slot both halves are 0. On bind, boundAt
|
|
44
|
+
* gets the current slot and freedAt stays 0. On
|
|
45
|
+
* unbind, freedAt gets the current slot (boundAt
|
|
46
|
+
* is preserved for audit / cooldown math).
|
|
47
|
+
*
|
|
48
|
+
* The struct + helpers live in the SDK (not the circuit package) so both
|
|
49
|
+
* the on-chain `@method` bodies AND the off-chain backend / verifier /
|
|
50
|
+
* dashboards can share a single source of truth for the leaf hash. The
|
|
51
|
+
* circuit re-exports them from `LicensingApp.ts` so existing consumers
|
|
52
|
+
* that import from there keep working.
|
|
53
|
+
*/
|
|
54
|
+
import { Field, Poseidon, Provable, Struct, UInt32 } from 'o1js';
|
|
55
|
+
// Fixed slot-array width. Per the device-binding-noncustodial plan: 5 is
|
|
56
|
+
// the sweet spot between "enough seats for a normal user" and "witnesses
|
|
57
|
+
// stay small." Changing this is a hardfork migration (would flip every
|
|
58
|
+
// leaf hash) — not a runtime tunable.
|
|
59
|
+
export const DEVICE_SLOT_CAP_N = 5;
|
|
60
|
+
export const DEVICE_SLOT_CAP = UInt32.from(DEVICE_SLOT_CAP_N);
|
|
61
|
+
// Poseidon-fold of DEVICE_SLOT_CAP × 2 = 10 zero Fields, used as the
|
|
62
|
+
// initial deviceSlotsRoot on every freshly-minted leaf. Precomputed once
|
|
63
|
+
// at module load so `freshLeaf()` doesn't reconstruct it per-call.
|
|
64
|
+
export const EMPTY_DEVICE_SLOTS_ROOT = Poseidon.hash(Array.from({ length: DEVICE_SLOT_CAP_N * 2 }, () => Field(0)));
|
|
65
|
+
// Poseidon-bound identity of the passphrase-derived ownership pubkey.
|
|
66
|
+
// The full PublicKey is (x: Field, isOdd: Bool); Poseidon(x, isOdd.toField())
|
|
67
|
+
// gives a single Field commitment. The buy circuit asserts this equals
|
|
68
|
+
// `licenseHash`, so the leaf carries no separate owner-pubkey field —
|
|
69
|
+
// `licenseHash` IS the on-chain owner-pubkey commitment.
|
|
70
|
+
export function ownerPubKeyHash(pub) {
|
|
71
|
+
return Poseidon.hash([pub.x, pub.isOdd.toField()]);
|
|
72
|
+
}
|
|
73
|
+
// Pack (boundAtSlot, freedAtSlot) into a single Field. Both are Mina
|
|
74
|
+
// slot numbers (UInt32-range, ≤ 2^32-1), so the concatenation fits in 64
|
|
75
|
+
// bits. Layout mirrors packPrices in LicensingApp.ts — low bits first so
|
|
76
|
+
// the more frequently-read half (freedAt, checked by every bind cooldown)
|
|
77
|
+
// unpacks with a single mask.
|
|
78
|
+
const SHIFT_32 = Field(1n << 32n);
|
|
79
|
+
export function packSlotTimes(boundAtSlot, freedAtSlot) {
|
|
80
|
+
return freedAtSlot.value.add(boundAtSlot.value.mul(SHIFT_32));
|
|
81
|
+
}
|
|
82
|
+
export function unpackSlotTimes(packed) {
|
|
83
|
+
// toBits(64) enforces the high 190 bits are zero — belt-and-suspenders
|
|
84
|
+
// since we only ever write via packSlotTimes, but keeps the circuit
|
|
85
|
+
// sound against an adversarially-crafted slot in a future upgrade.
|
|
86
|
+
const bits = packed.toBits(64);
|
|
87
|
+
const freedAtSlot = UInt32.Unsafe.fromField(Field.fromBits(bits.slice(0, 32)));
|
|
88
|
+
const boundAtSlot = UInt32.Unsafe.fromField(Field.fromBits(bits.slice(32, 64)));
|
|
89
|
+
return { boundAtSlot, freedAtSlot };
|
|
90
|
+
}
|
|
91
|
+
// Fold the parallel slot arrays into `deviceSlotsRoot`. Same order every
|
|
92
|
+
// time — occupied[0], freedAt[0], occupied[1], freedAt[1], ... — so a
|
|
93
|
+
// buyer that reconstructs the fold off-chain (verifier, dashboard) gets
|
|
94
|
+
// the same commitment the circuit computed.
|
|
95
|
+
export function computeDeviceSlotsRoot(occupied, freedAt) {
|
|
96
|
+
if (occupied.length !== DEVICE_SLOT_CAP_N || freedAt.length !== DEVICE_SLOT_CAP_N) {
|
|
97
|
+
throw new Error(`computeDeviceSlotsRoot expects exactly ${DEVICE_SLOT_CAP_N} entries in each array ` +
|
|
98
|
+
`(got occupied=${occupied.length}, freedAt=${freedAt.length})`);
|
|
99
|
+
}
|
|
100
|
+
const fields = [];
|
|
101
|
+
for (let i = 0; i < DEVICE_SLOT_CAP_N; i++) {
|
|
102
|
+
fields.push(occupied[i], freedAt[i]);
|
|
103
|
+
}
|
|
104
|
+
return Poseidon.hash(fields);
|
|
105
|
+
}
|
|
106
|
+
// Per-slot payload. The Struct wrapper is what lets o1js serialize this
|
|
107
|
+
// inside larger provable structures — it also gives us a fixed
|
|
108
|
+
// two-Field width so DeviceSlots.slots can be a `Provable.Array` of a
|
|
109
|
+
// well-known type instead of a bag of loose Fields.
|
|
110
|
+
//
|
|
111
|
+
// Same `const X: any = Struct(...)` pattern as contractInterface.ts —
|
|
112
|
+
// annotating as `any` sidesteps TS2742 (o1js sits outside the package
|
|
113
|
+
// rootDir under npm hoisting, so tsc can't emit portable declarations
|
|
114
|
+
// for the inferred Struct class). Instance methods and `static empty()`
|
|
115
|
+
// therefore live as standalone helpers below rather than on the class.
|
|
116
|
+
export const DeviceSlot = Struct({
|
|
117
|
+
occupied: Field, // 0 or Poseidon(devicePubKeyHash)
|
|
118
|
+
freedAt: Field, // packSlotTimes(boundAtSlot, freedAtSlot)
|
|
119
|
+
});
|
|
120
|
+
export function emptyDeviceSlot() {
|
|
121
|
+
return new DeviceSlot({ occupied: Field(0), freedAt: Field(0) });
|
|
122
|
+
}
|
|
123
|
+
// Fixed-width slot array. `Provable.Array(DeviceSlot, N)` promises the
|
|
124
|
+
// circuit an exact length so witnesses can address slots by static index.
|
|
125
|
+
export const DeviceSlots = Struct({
|
|
126
|
+
slots: Provable.Array(DeviceSlot, DEVICE_SLOT_CAP_N),
|
|
127
|
+
});
|
|
128
|
+
export function emptyDeviceSlots() {
|
|
129
|
+
return new DeviceSlots({
|
|
130
|
+
slots: Array.from({ length: DEVICE_SLOT_CAP_N }, () => emptyDeviceSlot()),
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
// In-circuit fold — takes a DeviceSlots value so it composes cleanly
|
|
134
|
+
// inside `@method` bodies. The array length is fixed by the Struct's
|
|
135
|
+
// Provable.Array declaration, so no runtime length guard is needed.
|
|
136
|
+
export function deviceSlotsHash(ds) {
|
|
137
|
+
const fields = [];
|
|
138
|
+
for (const s of ds.slots) {
|
|
139
|
+
fields.push(s.occupied, s.freedAt);
|
|
140
|
+
}
|
|
141
|
+
return Poseidon.hash(fields);
|
|
142
|
+
}
|
|
143
|
+
// The leaf value itself. `LicensingApp.buyLicense` builds one of these
|
|
144
|
+
// with EMPTY_DEVICE_SLOTS_ROOT and writes leafHash(leaf) into licensesRoot;
|
|
145
|
+
// subsequent mutations (renew, refund, migrate, bind, unbind) each build
|
|
146
|
+
// a new leaf with the appropriate field(s) updated and write its hash.
|
|
147
|
+
export const LicenseLeaf = Struct({
|
|
148
|
+
licenseHash: Field,
|
|
149
|
+
expirySlot: UInt32,
|
|
150
|
+
cap: UInt32,
|
|
151
|
+
deviceSlotsRoot: Field,
|
|
152
|
+
deviceSlotsFilled: UInt32,
|
|
153
|
+
});
|
|
154
|
+
export function leafHash(leaf) {
|
|
155
|
+
return Poseidon.hash([
|
|
156
|
+
leaf.licenseHash,
|
|
157
|
+
leaf.expirySlot.value,
|
|
158
|
+
leaf.cap.value,
|
|
159
|
+
leaf.deviceSlotsRoot,
|
|
160
|
+
leaf.deviceSlotsFilled.value,
|
|
161
|
+
]);
|
|
162
|
+
}
|
|
163
|
+
// Construct the leaf a fresh buy writes into the tree — no devices bound
|
|
164
|
+
// yet, filled counter at zero, slot-fold at the precomputed empty root.
|
|
165
|
+
export function freshLeaf(licenseHash, expirySlot, cap) {
|
|
166
|
+
return new LicenseLeaf({
|
|
167
|
+
licenseHash,
|
|
168
|
+
expirySlot,
|
|
169
|
+
cap,
|
|
170
|
+
deviceSlotsRoot: EMPTY_DEVICE_SLOTS_ROOT,
|
|
171
|
+
deviceSlotsFilled: UInt32.zero,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
// Reconstruct the leaf that lives at `record.licenseHash` in the licensesRoot
|
|
175
|
+
// MerkleMap. `LicenseRecord` optionally persists the device-binding fields;
|
|
176
|
+
// anything missing falls back to the fresh-leaf defaults, matching the state
|
|
177
|
+
// a just-issued license was minted with.
|
|
178
|
+
export function leafFromRecord(record) {
|
|
179
|
+
return new LicenseLeaf({
|
|
180
|
+
licenseHash: Field(record.licenseHash),
|
|
181
|
+
expirySlot: UInt32.from(record.expirySlot),
|
|
182
|
+
cap: UInt32.from(record.deviceCap ?? 0),
|
|
183
|
+
deviceSlotsRoot: record.deviceSlotsRoot !== undefined
|
|
184
|
+
? Field(record.deviceSlotsRoot)
|
|
185
|
+
: EMPTY_DEVICE_SLOTS_ROOT,
|
|
186
|
+
deviceSlotsFilled: UInt32.from(record.deviceSlotsFilled ?? 0),
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=licenseLeaf.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"licenseLeaf.js","sourceRoot":"","sources":["../src/licenseLeaf.ts"],"names":[],"mappings":"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"}
|
package/build/licenseRecord.d.ts
CHANGED
|
@@ -7,7 +7,22 @@
|
|
|
7
7
|
* the same type without dragging in filesystem code. licenseStore.ts
|
|
8
8
|
* re-exports these to keep existing Node imports working.
|
|
9
9
|
*/
|
|
10
|
+
export type FiatRateSnapshot = {
|
|
11
|
+
minaEurRate: number;
|
|
12
|
+
minaUsdRate: number;
|
|
13
|
+
minaGbpRate: number;
|
|
14
|
+
recordedAt: string;
|
|
15
|
+
};
|
|
10
16
|
export type LicenseRecord = {
|
|
17
|
+
/** Carried over from this earlier deployment when the app was redeployed (its successor starts with the same licenses): license state only, the sale stays on the earlier record. */
|
|
18
|
+
carriedOverFrom?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Moved to another owner key (transferLicense): this record keeps the sale,
|
|
21
|
+
* and the license itself is the record under `transferredTo` (which names
|
|
22
|
+
* its origin in `transferredFrom`, with no sale of its own).
|
|
23
|
+
*/
|
|
24
|
+
transferredTo?: string;
|
|
25
|
+
transferredFrom?: string;
|
|
11
26
|
zkAppAddress: string;
|
|
12
27
|
licenseHash: string;
|
|
13
28
|
expirySlot: number;
|
|
@@ -15,25 +30,73 @@ export type LicenseRecord = {
|
|
|
15
30
|
purchaseAmount: string;
|
|
16
31
|
txHash: string;
|
|
17
32
|
createdAt: string;
|
|
18
|
-
|
|
33
|
+
deviceCap?: number;
|
|
34
|
+
deviceSlotsRoot?: string;
|
|
35
|
+
deviceSlotsFilled?: number;
|
|
36
|
+
devices?: Array<{
|
|
37
|
+
slotIndex: number;
|
|
38
|
+
deviceCommitment: string;
|
|
39
|
+
boundAtSlot: number;
|
|
40
|
+
freedAtSlot: number;
|
|
41
|
+
}>;
|
|
42
|
+
buyerAddress: string;
|
|
19
43
|
buyerCountry?: string;
|
|
44
|
+
buyerZip?: string;
|
|
45
|
+
buyerIpCountry?: string | null;
|
|
46
|
+
geoDb?: string;
|
|
20
47
|
pending?: boolean;
|
|
21
48
|
provedAtSlot?: number;
|
|
49
|
+
pendingPrior?: LicenseRecord;
|
|
22
50
|
initialExpirySlot?: number;
|
|
23
|
-
tier?: 'monthly' | 'yearly' | 'fiveYear';
|
|
51
|
+
tier?: 'monthly' | 'yearly' | 'fiveYear' | 'perpetual';
|
|
24
52
|
renewedAtLeastOnce?: boolean;
|
|
25
|
-
refunded?: boolean;
|
|
26
|
-
released?: boolean;
|
|
53
|
+
refunded?: boolean | 'fast';
|
|
54
|
+
released?: boolean | 'fast';
|
|
27
55
|
releaseSlot?: number;
|
|
56
|
+
releaseTxHash?: string;
|
|
28
57
|
renewals?: Array<{
|
|
29
58
|
slot: number;
|
|
30
59
|
amount: string;
|
|
31
60
|
newExpiry: number;
|
|
32
61
|
txHash?: string;
|
|
62
|
+
fiatSnapshot?: FiatRateSnapshot;
|
|
63
|
+
waiverGivenBy?: AgentWaiverRecord;
|
|
64
|
+
ipCountry?: string | null;
|
|
65
|
+
geoDb?: string;
|
|
33
66
|
}>;
|
|
67
|
+
fiatSnapshot?: FiatRateSnapshot;
|
|
34
68
|
refundWaiverAcceptedAt?: string;
|
|
35
69
|
escrowless?: boolean;
|
|
70
|
+
escrowStranded?: {
|
|
71
|
+
txHash: string;
|
|
72
|
+
at: string;
|
|
73
|
+
};
|
|
74
|
+
waiverGivenBy?: AgentWaiverRecord;
|
|
75
|
+
provisionalFlipAtSlot?: number;
|
|
36
76
|
};
|
|
37
77
|
export declare const PENDING_REAP_SLOTS = 60;
|
|
38
|
-
export type LicenseStatus = 'active' | 'refunded' | 'expired' | 'unknown';
|
|
78
|
+
export type LicenseStatus = 'active' | 'refunded' | 'expired' | 'transferred' | 'unknown';
|
|
79
|
+
/** A withdrawal waiver an agent gave under the buyer's standing consent. */
|
|
80
|
+
export type AgentWaiverRecord = {
|
|
81
|
+
agent: string;
|
|
82
|
+
owner: string;
|
|
83
|
+
/** SHA-256 of the signed statement; the full consent is in the keeper's consent log. */
|
|
84
|
+
statementSha256: string;
|
|
85
|
+
issuedAt: string;
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* The file name of the license receipt a buyer downloads: `license-<appId>.json`,
|
|
89
|
+
* so an app looks for its own file and a buyer's receipts for different apps
|
|
90
|
+
* don't collide. Falls back to the zkApp address when there is no app ID (a
|
|
91
|
+
* contract that isn't registered as an app).
|
|
92
|
+
*/
|
|
93
|
+
export declare function licenseFileName(appId: string | null | undefined, zkAppAddress?: string): string;
|
|
94
|
+
/**
|
|
95
|
+
* The 98/2 split exactly as the licensing circuit pays it (LicensingApp:
|
|
96
|
+
* fee = amount.div(50), vendor = amount.sub(fee)); the two always add up to
|
|
97
|
+
* the amount. Use these for every off-chain figure, so dashboards, stats
|
|
98
|
+
* and tax exports match the on-chain payouts to the nanomina.
|
|
99
|
+
*/
|
|
100
|
+
export declare function platformFeeNano(amount: bigint): bigint;
|
|
101
|
+
export declare function vendorShareNano(amount: bigint): bigint;
|
|
39
102
|
//# sourceMappingURL=licenseRecord.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"licenseRecord.d.ts","sourceRoot":"","sources":["../src/licenseRecord.ts"],"names":[],"mappings":"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"}
|
package/build/licenseRecord.js
CHANGED
|
@@ -1,6 +1,31 @@
|
|
|
1
1
|
// Copyright (c) 2025-2026 zkLicensing project developers
|
|
2
|
-
//
|
|
2
|
+
// SPDX-License-Identifier: BUSL-1.1
|
|
3
3
|
// Reap pending records this many slots after prove time if no event ever lands.
|
|
4
4
|
// 60 slots ≈ 90 minutes — a generous window for tx inclusion under devnet conditions.
|
|
5
5
|
export const PENDING_REAP_SLOTS = 60;
|
|
6
|
+
/**
|
|
7
|
+
* The file name of the license receipt a buyer downloads: `license-<appId>.json`,
|
|
8
|
+
* so an app looks for its own file and a buyer's receipts for different apps
|
|
9
|
+
* don't collide. Falls back to the zkApp address when there is no app ID (a
|
|
10
|
+
* contract that isn't registered as an app).
|
|
11
|
+
*/
|
|
12
|
+
export function licenseFileName(appId, zkAppAddress) {
|
|
13
|
+
if (appId && /^[a-z0-9][a-z0-9-]{1,38}[a-z0-9]$/.test(appId))
|
|
14
|
+
return `license-${appId}.json`;
|
|
15
|
+
if (zkAppAddress && /^B62q[1-9A-HJ-NP-Za-km-z]{51}$/.test(zkAppAddress))
|
|
16
|
+
return `license-${zkAppAddress}.json`;
|
|
17
|
+
return 'license.json';
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The 98/2 split exactly as the licensing circuit pays it (LicensingApp:
|
|
21
|
+
* fee = amount.div(50), vendor = amount.sub(fee)); the two always add up to
|
|
22
|
+
* the amount. Use these for every off-chain figure, so dashboards, stats
|
|
23
|
+
* and tax exports match the on-chain payouts to the nanomina.
|
|
24
|
+
*/
|
|
25
|
+
export function platformFeeNano(amount) {
|
|
26
|
+
return amount / 50n;
|
|
27
|
+
}
|
|
28
|
+
export function vendorShareNano(amount) {
|
|
29
|
+
return amount - amount / 50n;
|
|
30
|
+
}
|
|
6
31
|
//# sourceMappingURL=licenseRecord.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"licenseRecord.js","sourceRoot":"","sources":["../src/licenseRecord.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,oCAAoC;AAqJpC,gFAAgF;AAChF,sFAAsF;AACtF,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAarC;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,KAAgC,EAAE,YAAqB;IACrF,IAAI,KAAK,IAAI,mCAAmC,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,WAAW,KAAK,OAAO,CAAC;IAC7F,IAAI,YAAY,IAAI,gCAAgC,CAAC,IAAI,CAAC,YAAY,CAAC;QAAE,OAAO,WAAW,YAAY,OAAO,CAAC;IAC/G,OAAO,cAAc,CAAC;AACxB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,MAAc;IAC5C,OAAO,MAAM,GAAG,GAAG,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAAc;IAC5C,OAAO,MAAM,GAAG,MAAM,GAAG,GAAG,CAAC;AAC/B,CAAC"}
|
package/build/licenseStore.d.ts
CHANGED
|
@@ -1,11 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* licenseStore.ts
|
|
3
|
+
*
|
|
4
|
+
* Off-chain MerkleMap state for the licensing system.
|
|
5
|
+
*
|
|
6
|
+
* Records are keyed by (zkAppAddress, licenseHash). Each LicensingApp deploys
|
|
7
|
+
* its own on-chain MerkleMap, so a passphrase used on two different apps
|
|
8
|
+
* produces the same `licenseHash` but two distinct records. Lookups that omit
|
|
9
|
+
* `zkAppAddress` would collide across apps — every API here takes it.
|
|
10
|
+
*
|
|
11
|
+
* Used by:
|
|
12
|
+
* - interact.ts / buyLicense.ts (CLI) — reads/writes directly
|
|
13
|
+
* - keeperService.ts — exposes the same logic over HTTP
|
|
14
|
+
*/
|
|
1
15
|
import { MerkleMap, MerkleMapWitness } from 'o1js';
|
|
2
16
|
import { type LicenseRecord as _LicenseRecord, type LicenseStatus as _LicenseStatus } from './licenseRecord.js';
|
|
3
17
|
export type LicenseRecord = _LicenseRecord;
|
|
4
18
|
export type LicenseStatus = _LicenseStatus;
|
|
19
|
+
export type { AgentWaiverRecord } from './licenseRecord.js';
|
|
5
20
|
export declare const PENDING_REAP_SLOTS = 60;
|
|
6
21
|
export declare function licenseStorePath(): string;
|
|
22
|
+
/**
|
|
23
|
+
* Where records live. Default: the JSON file at licenseStorePath() (the
|
|
24
|
+
* verify service and SDK users). The keeper installs its SQLite store with
|
|
25
|
+
* setLicenseStoreBackend, including a lock that works across processes.
|
|
26
|
+
*/
|
|
27
|
+
export type LicenseStoreBackend = {
|
|
28
|
+
read(): Promise<unknown>;
|
|
29
|
+
write(records: LicenseRecord[]): Promise<void>;
|
|
30
|
+
/** Wraps each read-modify-write; default none (in-process lock only). */
|
|
31
|
+
withLock?<T>(fn: () => Promise<T>): Promise<T>;
|
|
32
|
+
};
|
|
33
|
+
export declare function setLicenseStoreBackend(b: LicenseStoreBackend | null): void;
|
|
7
34
|
export declare function readRecords(): Promise<LicenseRecord[]>;
|
|
8
35
|
export declare function buildMap(records: LicenseRecord[], zkAppAddress: string): MerkleMap;
|
|
36
|
+
export declare function escrowExpirySlot(r: LicenseRecord): number;
|
|
9
37
|
export declare function buildEscrowMap(records: LicenseRecord[], zkAppAddress: string): MerkleMap;
|
|
10
38
|
export declare function serializeWitness(witness: MerkleMapWitness): {
|
|
11
39
|
isLefts: boolean[];
|
|
@@ -22,7 +50,20 @@ export declare function getWitness(zkAppAddress: string, licenseHash: string): P
|
|
|
22
50
|
serialized: ReturnType<typeof serializeWitness>;
|
|
23
51
|
}>;
|
|
24
52
|
export declare function getLicense(zkAppAddress: string, licenseHash: string): Promise<LicenseRecord | null>;
|
|
25
|
-
export declare function licenseStatus(record: LicenseRecord | null, currentSlot: number): LicenseStatus;
|
|
53
|
+
export declare function licenseStatus(record: LicenseRecord | null, currentSlot: number, forkActivationSlot?: number): LicenseStatus;
|
|
54
|
+
/**
|
|
55
|
+
* A redeployed app's successor starts with every license of `from` (its
|
|
56
|
+
* frozen tree, checked on chain): copy them to `to`, marked carriedOverFrom
|
|
57
|
+
* (not new sales). Refunded and already-present licenses are skipped.
|
|
58
|
+
* Returns how many were copied.
|
|
59
|
+
*/
|
|
60
|
+
export declare function carryOverRecords(from: string, to: string): Promise<number>;
|
|
61
|
+
/**
|
|
62
|
+
* A forced retirement left `zkAppAddress`'s escrowed purchases on the
|
|
63
|
+
* retired contract: marks them stranded (no refund or release follows).
|
|
64
|
+
* Returns how many.
|
|
65
|
+
*/
|
|
66
|
+
export declare function markEscrowStranded(zkAppAddress: string, txHash: string, at?: string): Promise<number>;
|
|
26
67
|
export declare function upsertLicense(record: LicenseRecord): Promise<void>;
|
|
27
68
|
export declare function updateExpiry(zkAppAddress: string, licenseHash: string, expirySlot: number, opts?: {
|
|
28
69
|
markRenewed?: boolean;
|
|
@@ -33,16 +74,52 @@ export declare function updateExpiry(zkAppAddress: string, licenseHash: string,
|
|
|
33
74
|
txHash?: string;
|
|
34
75
|
};
|
|
35
76
|
}): Promise<boolean>;
|
|
36
|
-
export declare function recordRefund(zkAppAddress: string, licenseHash: string
|
|
37
|
-
|
|
77
|
+
export declare function recordRefund(zkAppAddress: string, licenseHash: string, opts?: {
|
|
78
|
+
provisional?: boolean;
|
|
79
|
+
nowSlot?: number;
|
|
80
|
+
}): Promise<boolean>;
|
|
81
|
+
export declare function recordRelease(zkAppAddress: string, licenseHash: string, releaseSlot?: number, txHash?: string, opts?: {
|
|
82
|
+
provisional?: boolean;
|
|
83
|
+
nowSlot?: number;
|
|
84
|
+
}): Promise<boolean>;
|
|
85
|
+
export declare function revertProvisionalFlip(zkAppAddress: string, licenseHash: string, kind: 'release' | 'refund'): Promise<boolean>;
|
|
38
86
|
export declare function confirmRecord(zkAppAddress: string, licenseHash: string): Promise<boolean>;
|
|
39
87
|
export declare function applyLicenseIssued(zkAppAddress: string, licenseHash: string, fields: {
|
|
40
88
|
expirySlot: number;
|
|
41
89
|
purchaseSlot: number;
|
|
42
90
|
purchaseAmount: string;
|
|
43
|
-
tier?: 'monthly' | 'yearly' | 'fiveYear';
|
|
91
|
+
tier?: 'monthly' | 'yearly' | 'fiveYear' | 'perpetual';
|
|
44
92
|
escrowless?: boolean;
|
|
93
|
+
deviceCap?: number;
|
|
94
|
+
deviceSlotsRoot?: string;
|
|
95
|
+
deviceSlotsFilled?: number;
|
|
96
|
+
buyerAddress: string;
|
|
45
97
|
}): Promise<void>;
|
|
98
|
+
export declare function applyLicenseRenewed(zkAppAddress: string, licenseHash: string, fields: {
|
|
99
|
+
newExpiry: number;
|
|
100
|
+
}): Promise<boolean>;
|
|
101
|
+
/**
|
|
102
|
+
* A license moved to a new owner key (transferLicense): the license state
|
|
103
|
+
* (expiry, cap, bound devices) goes to a record under `to`, with no sale of
|
|
104
|
+
* its own (the sale and its receipt stay on the original record), listed
|
|
105
|
+
* under `wallet` (the transfer's sender, the new owner's wallet, which
|
|
106
|
+
* paid), and the original leaves the licenses tree (expirySlot 0) marked
|
|
107
|
+
* `transferredTo`.
|
|
108
|
+
*/
|
|
109
|
+
export declare function applyLicenseTransferred(zkAppAddress: string, from: string, to: string, opts?: {
|
|
110
|
+
wallet?: string;
|
|
111
|
+
txHash?: string;
|
|
112
|
+
}): Promise<boolean>;
|
|
113
|
+
export declare function applyDeviceBound(zkAppAddress: string, licenseHash: string, fields: {
|
|
114
|
+
slotIndex: number;
|
|
115
|
+
deviceCommitment: string;
|
|
116
|
+
boundAtSlot: number;
|
|
117
|
+
}): Promise<boolean>;
|
|
118
|
+
export declare function applyDeviceUnbound(zkAppAddress: string, licenseHash: string, fields: {
|
|
119
|
+
slotIndex: number;
|
|
120
|
+
freedAtSlot: number;
|
|
121
|
+
}): Promise<boolean>;
|
|
122
|
+
export declare function revertPending(zkAppAddress: string, licenseHash: string, txHash?: string): Promise<'restored' | 'removed' | false>;
|
|
46
123
|
export declare function deleteRecord(zkAppAddress: string, licenseHash: string): Promise<boolean>;
|
|
47
124
|
export declare function getStalePendingRecords(currentSlot: number, maxAgeSlots?: number): Promise<LicenseRecord[]>;
|
|
48
125
|
export declare function getReleasableRecords(currentSlot: number): Promise<LicenseRecord[]>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"licenseStore.d.ts","sourceRoot":"","sources":["../src/licenseStore.ts"],"names":[],"mappings":"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"}
|