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.
Files changed (317) hide show
  1. package/README.md +417 -201
  2. package/build/agent.d.ts +371 -0
  3. package/build/agent.d.ts.map +1 -0
  4. package/build/agent.js +553 -0
  5. package/build/agent.js.map +1 -0
  6. package/build/agentActions.d.ts +841 -0
  7. package/build/agentActions.d.ts.map +1 -0
  8. package/build/agentActions.js +581 -0
  9. package/build/agentActions.js.map +1 -0
  10. package/build/agentRecord.d.ts +83 -0
  11. package/build/agentRecord.d.ts.map +1 -0
  12. package/build/agentRecord.js +69 -0
  13. package/build/agentRecord.js.map +1 -0
  14. package/build/agentVendor.d.ts +220 -0
  15. package/build/agentVendor.d.ts.map +1 -0
  16. package/build/agentVendor.js +306 -0
  17. package/build/agentVendor.js.map +1 -0
  18. package/build/appsLookup.d.ts +14 -0
  19. package/build/appsLookup.d.ts.map +1 -0
  20. package/build/appsLookup.js +12 -0
  21. package/build/appsLookup.js.map +1 -0
  22. package/build/archiveBootstrap.d.ts +31 -5
  23. package/build/archiveBootstrap.d.ts.map +1 -0
  24. package/build/archiveBootstrap.js +140 -47
  25. package/build/archiveBootstrap.js.map +1 -0
  26. package/build/atomicJson.d.ts +5 -0
  27. package/build/atomicJson.d.ts.map +1 -0
  28. package/build/atomicJson.js +55 -0
  29. package/build/atomicJson.js.map +1 -0
  30. package/build/bindClient.d.ts +85 -0
  31. package/build/bindClient.d.ts.map +1 -0
  32. package/build/bindClient.js +187 -0
  33. package/build/bindClient.js.map +1 -0
  34. package/build/buyClient.d.ts +27 -4
  35. package/build/buyClient.d.ts.map +1 -0
  36. package/build/buyClient.js +72 -26
  37. package/build/buyClient.js.map +1 -0
  38. package/build/chainHead.d.ts +61 -0
  39. package/build/chainHead.d.ts.map +1 -0
  40. package/build/chainHead.js +88 -0
  41. package/build/chainHead.js.map +1 -0
  42. package/build/compactMerkleMap.d.ts +72 -0
  43. package/build/compactMerkleMap.d.ts.map +1 -0
  44. package/build/compactMerkleMap.js +224 -0
  45. package/build/compactMerkleMap.js.map +1 -0
  46. package/build/contractInterface.d.ts +191 -51
  47. package/build/contractInterface.d.ts.map +1 -0
  48. package/build/contractInterface.js +234 -43
  49. package/build/contractInterface.js.map +1 -0
  50. package/build/contractTypes.d.ts +9 -0
  51. package/build/contractTypes.d.ts.map +1 -0
  52. package/build/contractTypes.js +28 -0
  53. package/build/contractTypes.js.map +1 -0
  54. package/build/countryStats.d.ts +12 -3
  55. package/build/countryStats.d.ts.map +1 -0
  56. package/build/countryStats.js +87 -23
  57. package/build/countryStats.js.map +1 -0
  58. package/build/deployClient.d.ts +138 -24
  59. package/build/deployClient.d.ts.map +1 -0
  60. package/build/deployClient.js +91 -31
  61. package/build/deployClient.js.map +1 -0
  62. package/build/deviceIdentity.d.ts +68 -0
  63. package/build/deviceIdentity.d.ts.map +1 -0
  64. package/build/deviceIdentity.js +209 -0
  65. package/build/deviceIdentity.js.map +1 -0
  66. package/build/freezeClient.d.ts +26 -6
  67. package/build/freezeClient.d.ts.map +1 -0
  68. package/build/freezeClient.js +30 -6
  69. package/build/freezeClient.js.map +1 -0
  70. package/build/generationClient.d.ts +6 -3
  71. package/build/generationClient.d.ts.map +1 -0
  72. package/build/generationClient.js +25 -38
  73. package/build/generationClient.js.map +1 -0
  74. package/build/holderSecret.d.ts +70 -0
  75. package/build/holderSecret.d.ts.map +1 -0
  76. package/build/holderSecret.js +76 -0
  77. package/build/holderSecret.js.map +1 -0
  78. package/build/index.d.ts +38 -38
  79. package/build/index.d.ts.map +1 -0
  80. package/build/index.js +97 -121
  81. package/build/index.js.map +1 -0
  82. package/build/keysClient.d.ts +142 -0
  83. package/build/keysClient.d.ts.map +1 -0
  84. package/build/keysClient.js +109 -0
  85. package/build/keysClient.js.map +1 -0
  86. package/build/licenseLeaf.d.ts +76 -0
  87. package/build/licenseLeaf.d.ts.map +1 -0
  88. package/build/licenseLeaf.js +189 -0
  89. package/build/licenseLeaf.js.map +1 -0
  90. package/build/licenseRecord.d.ts +68 -5
  91. package/build/licenseRecord.d.ts.map +1 -0
  92. package/build/licenseRecord.js +26 -1
  93. package/build/licenseRecord.js.map +1 -0
  94. package/build/licenseStore.d.ts +81 -4
  95. package/build/licenseStore.d.ts.map +1 -0
  96. package/build/licenseStore.js +400 -30
  97. package/build/licenseStore.js.map +1 -0
  98. package/build/licenseTrustless.d.ts +43 -0
  99. package/build/licenseTrustless.d.ts.map +1 -0
  100. package/build/licenseTrustless.js +180 -0
  101. package/build/licenseTrustless.js.map +1 -0
  102. package/build/manifestVerify.d.ts +29 -1
  103. package/build/manifestVerify.d.ts.map +1 -0
  104. package/build/manifestVerify.js +46 -4
  105. package/build/manifestVerify.js.map +1 -0
  106. package/build/minaPriceHistory.d.ts +9 -0
  107. package/build/minaPriceHistory.d.ts.map +1 -0
  108. package/build/minaPriceHistory.js +152 -0
  109. package/build/minaPriceHistory.js.map +1 -0
  110. package/build/onChainRoot.d.ts +60 -0
  111. package/build/onChainRoot.d.ts.map +1 -0
  112. package/build/onChainRoot.js +74 -0
  113. package/build/onChainRoot.js.map +1 -0
  114. package/build/ownershipLicenseHash.d.ts +25 -0
  115. package/build/ownershipLicenseHash.d.ts.map +1 -0
  116. package/build/ownershipLicenseHash.js +29 -0
  117. package/build/ownershipLicenseHash.js.map +1 -0
  118. package/build/ownershipSignature.d.ts +153 -0
  119. package/build/ownershipSignature.d.ts.map +1 -0
  120. package/build/ownershipSignature.js +297 -0
  121. package/build/ownershipSignature.js.map +1 -0
  122. package/build/permitCheckFlow.d.ts +155 -0
  123. package/build/permitCheckFlow.d.ts.map +1 -0
  124. package/build/permitCheckFlow.js +196 -0
  125. package/build/permitCheckFlow.js.map +1 -0
  126. package/build/permitDescribe.d.ts +124 -0
  127. package/build/permitDescribe.d.ts.map +1 -0
  128. package/build/permitDescribe.js +324 -0
  129. package/build/permitDescribe.js.map +1 -0
  130. package/build/permitInterface.d.ts +85 -0
  131. package/build/permitInterface.d.ts.map +1 -0
  132. package/build/permitInterface.js +121 -0
  133. package/build/permitInterface.js.map +1 -0
  134. package/build/permitMessages.d.ts +313 -0
  135. package/build/permitMessages.d.ts.map +1 -0
  136. package/build/permitMessages.js +462 -0
  137. package/build/permitMessages.js.map +1 -0
  138. package/build/permitProof.d.ts +108 -0
  139. package/build/permitProof.d.ts.map +1 -0
  140. package/build/permitProof.js +202 -0
  141. package/build/permitProof.js.map +1 -0
  142. package/build/permitRegistryRebuild.d.ts +166 -0
  143. package/build/permitRegistryRebuild.d.ts.map +1 -0
  144. package/build/permitRegistryRebuild.js +347 -0
  145. package/build/permitRegistryRebuild.js.map +1 -0
  146. package/build/permitTree.d.ts +88 -0
  147. package/build/permitTree.d.ts.map +1 -0
  148. package/build/permitTree.js +230 -0
  149. package/build/permitTree.js.map +1 -0
  150. package/build/permitsClient.d.ts +680 -0
  151. package/build/permitsClient.d.ts.map +1 -0
  152. package/build/permitsClient.js +597 -0
  153. package/build/permitsClient.js.map +1 -0
  154. package/build/proveErrors.d.ts +50 -0
  155. package/build/proveErrors.d.ts.map +1 -0
  156. package/build/proveErrors.js +76 -0
  157. package/build/proveErrors.js.map +1 -0
  158. package/build/receipt.d.ts +95 -0
  159. package/build/receipt.d.ts.map +1 -0
  160. package/build/receipt.js +84 -0
  161. package/build/receipt.js.map +1 -0
  162. package/build/refundClient.d.ts +7 -12
  163. package/build/refundClient.d.ts.map +1 -0
  164. package/build/refundClient.js +52 -21
  165. package/build/refundClient.js.map +1 -0
  166. package/build/registryTrustVerify.d.ts +78 -0
  167. package/build/registryTrustVerify.d.ts.map +1 -0
  168. package/build/registryTrustVerify.js +129 -0
  169. package/build/registryTrustVerify.js.map +1 -0
  170. package/build/releaseClient.d.ts +26 -0
  171. package/build/releaseClient.d.ts.map +1 -0
  172. package/build/releaseClient.js +65 -0
  173. package/build/releaseClient.js.map +1 -0
  174. package/build/renewClient.d.ts +28 -2
  175. package/build/renewClient.d.ts.map +1 -0
  176. package/build/renewClient.js +31 -27
  177. package/build/renewClient.js.map +1 -0
  178. package/build/seatName.d.ts +8 -0
  179. package/build/seatName.d.ts.map +1 -0
  180. package/build/seatName.js +136 -0
  181. package/build/seatName.js.map +1 -0
  182. package/build/slotConstants.d.ts +15 -0
  183. package/build/slotConstants.d.ts.map +1 -0
  184. package/build/slotConstants.js +17 -0
  185. package/build/slotConstants.js.map +1 -0
  186. package/build/statsClient.d.ts +61 -7
  187. package/build/statsClient.d.ts.map +1 -0
  188. package/build/statsClient.js +44 -5
  189. package/build/statsClient.js.map +1 -0
  190. package/build/successorChain.d.ts +35 -0
  191. package/build/successorChain.d.ts.map +1 -0
  192. package/build/successorChain.js +69 -0
  193. package/build/successorChain.js.map +1 -0
  194. package/build/taxId.d.ts +44 -0
  195. package/build/taxId.d.ts.map +1 -0
  196. package/build/taxId.js +212 -0
  197. package/build/taxId.js.map +1 -0
  198. package/build/trustAnchorVerify.d.ts +49 -0
  199. package/build/trustAnchorVerify.d.ts.map +1 -0
  200. package/build/trustAnchorVerify.js +432 -0
  201. package/build/trustAnchorVerify.js.map +1 -0
  202. package/build/trustAnchorVerifyCli.d.ts +45 -0
  203. package/build/trustAnchorVerifyCli.d.ts.map +1 -0
  204. package/build/trustAnchorVerifyCli.js +235 -0
  205. package/build/trustAnchorVerifyCli.js.map +1 -0
  206. package/build/txBroadcastClient.d.ts +26 -0
  207. package/build/txBroadcastClient.d.ts.map +1 -0
  208. package/build/txBroadcastClient.js +20 -0
  209. package/build/txBroadcastClient.js.map +1 -0
  210. package/build/unbindClient.d.ts +77 -0
  211. package/build/unbindClient.d.ts.map +1 -0
  212. package/build/unbindClient.js +169 -0
  213. package/build/unbindClient.js.map +1 -0
  214. package/build/units.d.ts +28 -0
  215. package/build/units.d.ts.map +1 -0
  216. package/build/units.js +65 -0
  217. package/build/units.js.map +1 -0
  218. package/build/vatRates.d.ts +54 -0
  219. package/build/vatRates.d.ts.map +1 -0
  220. package/build/vatRates.js +82 -0
  221. package/build/vatRates.js.map +1 -0
  222. package/build/vatRatesData.d.ts +5 -0
  223. package/build/vatRatesData.d.ts.map +1 -0
  224. package/build/vatRatesData.js +42 -0
  225. package/build/vatRatesData.js.map +1 -0
  226. package/build/vendorAccountClient.d.ts +66 -0
  227. package/build/vendorAccountClient.d.ts.map +1 -0
  228. package/build/vendorAccountClient.js +47 -0
  229. package/build/vendorAccountClient.js.map +1 -0
  230. package/build/verifyCore.d.ts +4 -1
  231. package/build/verifyCore.d.ts.map +1 -0
  232. package/build/verifyCore.js +21 -10
  233. package/build/verifyCore.js.map +1 -0
  234. package/build/verifyOffline.d.ts +85 -0
  235. package/build/verifyOffline.d.ts.map +1 -0
  236. package/build/verifyOffline.js +139 -0
  237. package/build/verifyOffline.js.map +1 -0
  238. package/build/verifyService.d.ts.map +1 -0
  239. package/build/verifyService.js +571 -501
  240. package/build/verifyService.js.map +1 -0
  241. package/build/verifyWithAncestors.d.ts +19 -0
  242. package/build/verifyWithAncestors.d.ts.map +1 -0
  243. package/build/verifyWithAncestors.js +127 -0
  244. package/build/verifyWithAncestors.js.map +1 -0
  245. package/build/zipToState.d.ts +2 -0
  246. package/build/zipToState.d.ts.map +1 -0
  247. package/build/zipToState.js +94 -0
  248. package/build/zipToState.js.map +1 -0
  249. package/package.json +141 -16
  250. package/src/agent.ts +682 -0
  251. package/src/agentActions.ts +637 -0
  252. package/src/agentRecord.ts +121 -0
  253. package/src/agentVendor.ts +356 -0
  254. package/src/appsLookup.ts +48 -0
  255. package/src/archiveBootstrap.ts +386 -0
  256. package/src/atomicJson.ts +53 -0
  257. package/src/bindClient.ts +297 -0
  258. package/src/buyClient.ts +344 -0
  259. package/src/chainHead.ts +106 -0
  260. package/src/compactMerkleMap.ts +222 -0
  261. package/src/contractInterface.ts +465 -0
  262. package/src/contractTypes.ts +31 -0
  263. package/src/countryStats.ts +200 -0
  264. package/src/deployClient.ts +517 -0
  265. package/src/deviceIdentity.ts +249 -0
  266. package/src/freezeClient.ts +162 -0
  267. package/src/generationClient.ts +145 -0
  268. package/src/holderSecret.ts +91 -0
  269. package/src/index.ts +362 -0
  270. package/src/keysClient.ts +135 -0
  271. package/src/licenseLeaf.ts +221 -0
  272. package/src/licenseRecord.ts +190 -0
  273. package/src/licenseStore.ts +767 -0
  274. package/src/licenseTrustless.ts +207 -0
  275. package/src/manifestVerify.ts +164 -0
  276. package/src/minaPriceHistory.ts +166 -0
  277. package/src/onChainRoot.ts +90 -0
  278. package/src/ownershipLicenseHash.ts +31 -0
  279. package/src/ownershipSignature.ts +421 -0
  280. package/src/permitCheckFlow.ts +227 -0
  281. package/src/permitDescribe.ts +362 -0
  282. package/src/permitInterface.ts +146 -0
  283. package/src/permitMessages.ts +572 -0
  284. package/src/permitProof.ts +230 -0
  285. package/src/permitRegistryRebuild.ts +423 -0
  286. package/src/permitTree.ts +232 -0
  287. package/src/permitsClient.ts +746 -0
  288. package/src/proveErrors.ts +98 -0
  289. package/src/receipt.ts +156 -0
  290. package/src/refundClient.ts +177 -0
  291. package/src/registryTrustVerify.ts +192 -0
  292. package/src/releaseClient.ts +101 -0
  293. package/src/renewClient.ts +234 -0
  294. package/src/seatName.ts +165 -0
  295. package/src/slotConstants.ts +18 -0
  296. package/src/statsClient.ts +249 -0
  297. package/src/successorChain.ts +87 -0
  298. package/src/taxId.ts +227 -0
  299. package/src/trustAnchorVerify.ts +550 -0
  300. package/src/trustAnchorVerifyCli.ts +234 -0
  301. package/src/txBroadcastClient.ts +48 -0
  302. package/src/unbindClient.ts +233 -0
  303. package/src/units.ts +74 -0
  304. package/src/vatRates.ts +100 -0
  305. package/src/vatRatesData.ts +43 -0
  306. package/src/vendorAccountClient.ts +120 -0
  307. package/src/verifyCore.ts +100 -0
  308. package/src/verifyOffline.ts +212 -0
  309. package/src/verifyService.ts +982 -0
  310. package/src/verifyWithAncestors.ts +163 -0
  311. package/src/zipToState.ts +94 -0
  312. package/build/licenseProof.d.ts +0 -26
  313. package/build/licenseProof.js +0 -41
  314. package/build/migrateClient.d.ts +0 -43
  315. package/build/migrateClient.js +0 -47
  316. package/build/ownership.d.ts +0 -34
  317. 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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"}
@@ -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
- buyerAddress?: string;
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":"AAGA;;;;;;;;GAQG;AAQH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,WAAW,EAAI,MAAM,CAAC;IACtB,WAAW,EAAI,MAAM,CAAC;IACtB,WAAW,EAAI,MAAM,CAAC;IACtB,UAAU,EAAK,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,qLAAqL;IACrL,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,EAAI,MAAM,CAAC;IACvB,WAAW,EAAK,MAAM,CAAC;IACvB,UAAU,EAAM,MAAM,CAAC;IACvB,YAAY,EAAI,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAU,MAAM,CAAC;IACvB,SAAS,EAAO,MAAM,CAAC;IAMvB,SAAS,CAAC,EAAQ,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAI3B,OAAO,CAAC,EAAE,KAAK,CAAC;QACd,SAAS,EAAS,MAAM,CAAC;QACzB,gBAAgB,EAAE,MAAM,CAAC;QACzB,WAAW,EAAO,MAAM,CAAC;QACzB,WAAW,EAAO,MAAM,CAAC;KAC1B,CAAC,CAAC;IACH,YAAY,EAAI,MAAM,CAAC;IAQvB,YAAY,CAAC,EAAG,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAO,MAAM,CAAC;IAIvB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,KAAK,CAAC,EAAU,MAAM,CAAC;IACvB,OAAO,CAAC,EAAQ,OAAO,CAAC;IACxB,YAAY,CAAC,EAAG,MAAM,CAAC;IAIvB,YAAY,CAAC,EAAG,aAAa,CAAC;IAG9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAG3B,IAAI,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,UAAU,GAAG,WAAW,CAAC;IAGvD,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAY7B,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAG5B,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IAKrB,aAAa,CAAC,EAAE,MAAM,CAAC;IAOvB,QAAQ,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,gBAAgB,CAAC;QAAC,aAAa,CAAC,EAAE,iBAAiB,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAKtM,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAMhC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAMhC,UAAU,CAAC,EAAE,OAAO,CAAC;IAKrB,cAAc,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IAGhD,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAKlC,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC,CAAC;AAIF,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAErC,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,GAAG,aAAa,GAAG,SAAS,CAAC;AAE1F,4EAA4E;AAC5E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,wFAAwF;IACxF,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAI/F;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEtD"}
@@ -1,6 +1,31 @@
1
1
  // Copyright (c) 2025-2026 zkLicensing project developers
2
- // All rights reserved.
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"}
@@ -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): Promise<boolean>;
37
- export declare function recordRelease(zkAppAddress: string, licenseHash: string, releaseSlot?: number): Promise<boolean>;
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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"}