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
@@ -1,5 +1,5 @@
1
1
  // Copyright (c) 2025-2026 zkLicensing project developers
2
- // All rights reserved.
2
+ // SPDX-License-Identifier: BUSL-1.1
3
3
  /**
4
4
  * contractInterface.ts
5
5
  *
@@ -12,33 +12,45 @@
12
12
  * about durations are published here so a public verify service can replay
13
13
  * the archive without pulling in the contract source.
14
14
  *
15
- * `CANONICAL_VK_HASH` and `CANONICAL_LICENSE_PROOF_VK_HASH` are the
16
- * verification-key hashes of the two published circuits — `LicensingApp`
17
- * (the on-chain zkApp) and `LicenseOwnershipProgram` (the ownership
18
- * challenge/response `ZkProgram`), respectively. Both are hand-maintained
19
- * constants — bump them whenever the corresponding circuit changes and
20
- * rerun the keeper's boot assertion (see zklicensing-app/src/keeperService.ts)
15
+ * `CANONICAL_VK_HASH` is the verification-key hash of the published
16
+ * `LicensingApp` circuit. Bump it whenever the on-chain zkApp changes
17
+ * and rerun the backend's boot assertion (see zklicensing-app/src/keeperService.ts)
21
18
  * / the verify service's `ensureCompiled()` check to catch drift.
22
19
  */
23
- import { declareState, fetchAccount, Field, PublicKey, SmartContract, Struct, UInt32, UInt64, MerkleMap } from 'o1js';
20
+ import { Bool, declareState, fetchAccount, Field, PublicKey, SmartContract, Struct, UInt32, UInt64, MerkleMap } from 'o1js';
24
21
  // ------------------------------------------------------------
25
22
  // EVENT STRUCTS
26
23
  // ------------------------------------------------------------
27
24
  // Struct() returns a class whose type references o1js internals that fall
28
25
  // outside this package's rootDir (npm hoists o1js to the workspace root).
29
26
  // Annotating each export as `any` keeps tsc from inferring (and therefore
30
- // emitting) those internal type references. Consumers get full typing through
31
- // the hand-written contractInterface.d.ts shim.
27
+ // emitting) those internal type references, so the generated declarations
28
+ // stay self-contained.
32
29
  //
33
30
  // The clean alternative — `export class X extends Struct({...}) {}` as the
34
31
  // mina-fungible-token repo does — only works when o1js sits inside rootDir,
35
32
  // which a workspace member can't guarantee.
33
+ // `cap` is carried so that a backend reconstructing the license from archive
34
+ // events (e.g. after losing its in-memory intent map to a restart) can
35
+ // rehydrate the exact LicenseLeaf that was committed on-chain. Without it,
36
+ // leafFromRecord() would default cap to UInt32.zero and every follow-up
37
+ // root-mutating proof (renew, refund, bind, unbind) would fail the
38
+ // in-circuit hash check.
39
+ //
40
+ // `deviceSlotsRoot` / `deviceSlotsFilled` are omitted deliberately: at issue
41
+ // time they are always EMPTY_DEVICE_SLOTS_ROOT / 0. The backend's rehydration
42
+ // uses those defaults, matching the leaf the circuit wrote.
43
+ //
44
+ // The leaf carries no separate ownerPubKeyHash — `licenseHash` IS the owner-
45
+ // pubkey commitment (buyLicense asserts them equal), so it doesn't need to
46
+ // ride in the event either.
36
47
  export const LicenseIssuedEvent = Struct({
37
48
  licenseHash: Field,
38
49
  buyer: PublicKey,
39
50
  amount: UInt64,
40
51
  slot: UInt32,
41
52
  expirySlot: UInt32,
53
+ cap: UInt32,
42
54
  });
43
55
  export const ExpiryUpdateEvent = Struct({
44
56
  licenseHash: Field,
@@ -48,32 +60,156 @@ export const PriceUpdatedEvent = Struct({
48
60
  priceMonthly: UInt64,
49
61
  priceYearly: UInt64,
50
62
  priceFiveYear: UInt64,
63
+ pricePerpetual: UInt64,
51
64
  });
52
65
  export const AppCreatedEvent = Struct({
53
66
  vendor: PublicKey,
67
+ /** The app this one continues (a redeploy: it starts with that app's licenses); PublicKey.empty() for a first generation. */
68
+ predecessor: PublicKey,
69
+ /** The licenses tree it starts with: empty, or its predecessor's frozen root. */
70
+ licensesRoot: Field,
71
+ });
72
+ // Emitted by `retire`: the app is frozen at `licensesRoot` for a redeploy;
73
+ // its successor starts with that tree (initializeSuccessor). `by` is the key
74
+ // that signed it (the vendor's or the platform's).
75
+ // `forced`: the platform retired it with purchases still in escrow (their
76
+ // funds stay on the retired contract, which settles nothing any more).
77
+ export const AppRetiredEvent = Struct({ licensesRoot: Field, by: PublicKey, successor: PublicKey, forced: Bool });
78
+ /**
79
+ * What the vendor or the platform signs to retire an app: bound to the app,
80
+ * its frozen root, the one successor that may start from it, and `force`
81
+ * (only the platform may: retire with purchases in escrow, whose funds then
82
+ * stay on the retired contract).
83
+ */
84
+ export const APP_RETIRE_TAG = Field(0x7a6b726574697265n); // "zkretire"
85
+ export function appRetireMessage(app, licensesRoot, successor, force) {
86
+ return [APP_RETIRE_TAG, ...app.toFields(), licensesRoot, ...successor.toFields(), force.toField()];
87
+ }
88
+ /**
89
+ * LicensingApp's on-chain state, in declaration order (appState index of
90
+ * each field; a PublicKey takes two). A successor's initializeSuccessor
91
+ * reads its predecessor's through account preconditions.
92
+ */
93
+ export const LICENSING_APP_STATE = {
94
+ licensesRoot: 0, vendorX: 1, vendorIsOdd: 2, escrowRoot: 3, pricesPacked: 4,
95
+ version: 5, ancestorsRoot: 6, forkActivationSlot: 7, deviceCap: 8, retired: 9,
96
+ successorX: 10, successorIsOdd: 11,
97
+ payoutX: 12, payoutIsOdd: 13, pendingPayoutX: 14, pendingPayoutIsOdd: 15, pendingPayoutSlot: 16,
98
+ platformX: 17, platformIsOdd: 18, treasuryX: 19, treasuryIsOdd: 20, platformEpoch: 21,
99
+ vendorNonce: 22, networkId: 23,
100
+ };
101
+ // ------------------------------------------------------------
102
+ // KEYS: the platform key, payout addresses, the vendor key, license owners
103
+ // ------------------------------------------------------------
104
+ /** Deterministic Field from a short ASCII label (≤ 31 bytes). */
105
+ function tagField(label) {
106
+ let v = 0n;
107
+ for (const ch of label)
108
+ v = (v << 8n) | BigInt(ch.charCodeAt(0));
109
+ return Field(v);
110
+ }
111
+ export const KEY_TAGS = {
112
+ PLATFORM_KEY: tagField('zkLicensing/v1/platformKey'),
113
+ PLATFORM_RECOVER: tagField('zkLicensing/v1/platformRecover'),
114
+ VENDOR_KEY: tagField('zkLicensing/v1/vendorKey'),
115
+ LICENSE_TRANSFER: tagField('zkLicensing/v1/licenseMove'),
116
+ };
117
+ /**
118
+ * The platform's key (signs platform retires and cancels), its treasury
119
+ * (receives the 2%) and how many times they changed, as every app and
120
+ * registry holds them. A new contract starts with the current ones (the
121
+ * keeper checks them before listing it); a successor carries its
122
+ * predecessor's over, checked on chain.
123
+ */
124
+ export const PlatformState = Struct({ key: PublicKey, treasury: PublicKey, epoch: UInt32 });
125
+ /**
126
+ * A change of the platform key and treasury: signed by the current platform
127
+ * key and the new one. Bound to the network and the next epoch, not to a
128
+ * contract, so one pair of signatures updates every app and registry on the
129
+ * network (anyone may send them; each contract takes it once).
130
+ */
131
+ export function platformKeyMessage(a) {
132
+ return [KEY_TAGS.PLATFORM_KEY, a.network, a.epoch.value, ...a.key.toFields(), ...a.treasury.toFields()];
133
+ }
134
+ /**
135
+ * The same, signed by the offline recovery key alone (compiled into the
136
+ * circuits): it can always set a new platform key and treasury, lost or
137
+ * stolen, at any epoch above a contract's current one.
138
+ */
139
+ export function platformRecoverMessage(a) {
140
+ return [KEY_TAGS.PLATFORM_RECOVER, a.network, a.epoch.value, ...a.key.toFields(), ...a.treasury.toFields()];
141
+ }
142
+ /** A new vendor key for an app: signed by the current vendor key and the new one; `nonce` is the app's vendorNonce. */
143
+ export function vendorKeyMessage(a) {
144
+ return [KEY_TAGS.VENDOR_KEY, a.network, ...a.app.toFields(), a.nonce.value, ...a.vendor.toFields()];
145
+ }
146
+ /**
147
+ * A license moving to a new owner key (`to` = ownerPubKeyHash of the new
148
+ * key): signed by the current owner key and the new one, over the license
149
+ * as it is now (its leaf hash) and a last slot it may land by.
150
+ */
151
+ export function licenseTransferMessage(a) {
152
+ return [KEY_TAGS.LICENSE_TRANSFER, a.network, ...a.app.toFields(), a.leafHash, a.to, a.validUntil.value];
153
+ }
154
+ /**
155
+ * How long a new payout address waits before it takes effect: 48 hours at
156
+ * 90 s per slot. Payments keep going to the current one until it is
157
+ * applied, and the owner can cancel it meanwhile.
158
+ */
159
+ export const PAYOUT_DELAY_SLOTS_N = 1_920;
160
+ /** A payout address was proposed; anyone may apply it from `effectiveSlot` on. */
161
+ export const PayoutProposedEvent = Struct({ payout: PublicKey, effectiveSlot: UInt32 });
162
+ /** The payout address now in use (applied), or the pending one cancelled (`applied` false). */
163
+ export const PayoutChangedEvent = Struct({ payout: PublicKey, applied: Bool });
164
+ export const PlatformChangedEvent = Struct({ platform: PlatformState, byRecovery: Bool });
165
+ export const VendorChangedEvent = Struct({ vendor: PublicKey, nonce: UInt32 });
166
+ /**
167
+ * A license moved to a new owner key: the same leaf under `to`. `wallet` is
168
+ * the transaction's sender, the new owner's wallet that paid for it (as
169
+ * LicenseIssuedEvent's `buyer`), so a replay lists it under that wallet.
170
+ */
171
+ export const LicenseTransferredEvent = Struct({ from: Field, to: Field, wallet: PublicKey });
172
+ // Emitted by `bind` when the buyer's device commitment lands in a slot on
173
+ // their license leaf. `deviceCommitment = Poseidon(devicePubKeyHash)` — the
174
+ // raw pubkey is never revealed. `slotIndex` is 0-based within the license's
175
+ // fixed-size slot array (see DEVICE_SLOT_CAP).
176
+ //
177
+ // `boundAtSlot` carries the circuit's proof-time `globalSlotSinceGenesis` —
178
+ // the exact value packed into the leaf's `freedAt` via `packSlotTimes(
179
+ // currentSlot, 0)`. Off-chain backends rebuilding `deviceSlotsRoot` MUST use
180
+ // this, not the block's globalSlot: the tx's precondition allows any block
181
+ // slot within TOLERANCE_WINDOW of proof time, so block-slot != proof-slot in
182
+ // the general case, and any mismatch flips the packed field, the leaf hash,
183
+ // and the aggregate `licensesRoot`. Follows the same pattern as
184
+ // `LicenseIssuedEvent.slot`.
185
+ export const DeviceBoundEvent = Struct({
186
+ licenseHash: Field,
187
+ slotIndex: UInt32,
188
+ deviceCommitment: Field,
189
+ boundAtSlot: UInt32,
54
190
  });
55
- // Emitted by `migrateLicense` when a license issued under an ancestor
56
- // deployment is re-minted into this deployment at zero payment. `licenseHash`
57
- // is stable across all deployments because the buyer's derived hash is what
58
- // identifies the license; `expirySlot` is copied verbatim from the ancestor's
59
- // licensesRoot entry; `ancestorGen` is the generation index the migration
60
- // resolved against (needed so archive replay and auditors can trace which
61
- // frozen root supplied the entry — skip-generation migrations are one-hop).
62
- export const LicenseMigratedEvent = Struct({
191
+ // Emitted by `unbind` when a slot is freed. `slotIndex` stays occupied in the
192
+ // array (`slotFreedAt` stamp stays set) so the cooldown timer starts; the
193
+ // slot's `occupied` field goes to Field(0). Any device holding the license's
194
+ // ownership key can trigger this — remote log-off is by design.
195
+ //
196
+ // `freedAtSlot` carries the circuit's proof-time `globalSlotSinceGenesis` —
197
+ // the value packed into the leaf's `freedAt` via `packSlotTimes(preservedBound,
198
+ // currentSlot)`. Same off-chain reconstruction reason as `DeviceBoundEvent.
199
+ // boundAtSlot`. The preserved `boundAtSlot` is not re-emitted; the backend
200
+ // reads it from its own record (which still has the earlier bind's stamp).
201
+ export const DeviceUnboundEvent = Struct({
63
202
  licenseHash: Field,
64
- expirySlot: UInt32,
65
- ancestorGen: UInt32,
203
+ slotIndex: UInt32,
204
+ freedAtSlot: UInt32,
66
205
  });
67
206
  // ------------------------------------------------------------
68
207
  // CONSTANTS (slot math — 90 s/slot after Mesa upgrade)
69
208
  // ------------------------------------------------------------
70
- export const MONTHLY_SLOTS_N = 28_800; // 30 days × 24 × 40
71
- export const ONE_YEAR_SLOTS_N = 350_640; // 365.25 days × 24 × 40 (Julian year)
72
- export const FIVE_YEAR_SLOTS_N = 1_753_200; // 5 × ONE_YEAR_SLOTS_N
73
- export const REFUND_WINDOW_N = 13_440;
74
- export const GRACE_PERIOD_N = 6_720;
75
- export const MS_PER_SLOT_N = 90_000; // Mesa slot duration in ms
76
- export const SLOTS_PER_DAY_N = 960; // 86_400_000 / MS_PER_SLOT_N
209
+ // Plain numbers, in an o1js-free module so the package root (verifyLicense)
210
+ // can use them without o1js installed; re-exported here unchanged.
211
+ import { MONTHLY_SLOTS_N, ONE_YEAR_SLOTS_N, FIVE_YEAR_SLOTS_N, PERPETUAL_SLOTS_N, REFUND_WINDOW_N, GRACE_PERIOD_N, MS_PER_SLOT_N, SLOTS_PER_DAY_N, } from './slotConstants.js';
212
+ export { MONTHLY_SLOTS_N, ONE_YEAR_SLOTS_N, FIVE_YEAR_SLOTS_N, PERPETUAL_SLOTS_N, REFUND_WINDOW_N, GRACE_PERIOD_N, MS_PER_SLOT_N, SLOTS_PER_DAY_N, };
77
213
  // Slot tolerance for the globalSlotSinceGenesis precondition. Applied uniformly to
78
214
  // every method that reads currentSlot. 40 slots × 90 s = 1 hour — sized to
79
215
  // clear the honest-user prove+wallet+mempool latency envelope. The refund vs
@@ -82,13 +218,43 @@ export const SLOTS_PER_DAY_N = 960; // 86_400_000 / MS_PER_SLOT_N
82
218
  // asserts against a threshold shifted by +TOLERANCE_WINDOW so neither can
83
219
  // land on the same real slot as the other. See AUDIT_BRIEF.md §7.
84
220
  export const TOLERANCE_WINDOW_N = 40;
221
+ // How far before a successor's fork activation slot a license's grace period
222
+ // may have ended and still qualify for the fork bump (effectiveExpirySlot).
223
+ // The bump exists for licenses that lapsed because the pre-fork sales freeze
224
+ // blocked renewal; the freeze starts at hardforkSlot - REFUND_WINDOW_N -
225
+ // margin (~15_500 slots). 20_160 slots = 21 days covers that with slack.
226
+ // Licenses whose grace ran out earlier lapsed normally and keep their expiry.
227
+ // The keeper warns at startup if FREEZE_AFTER_SLOT sits further back.
228
+ export const MIGRATION_BUMP_LOOKBACK_N = 20_160;
229
+ /**
230
+ * A license's expiry as the app's contract treats it: a successor deployed
231
+ * across a Mina hardfork (forkActivationSlot > 0) starts with its
232
+ * predecessor's licenses, and a license that lapsed during the pre-fork
233
+ * freeze (expiry before the fork slot, but within grace + lookback of it)
234
+ * counts as expiring at the fork slot, so the 7-day grace runs from there.
235
+ * renewLicense applies the same rule in-circuit; verification uses this.
236
+ */
237
+ export function effectiveExpirySlot(expirySlot, forkActivationSlot = 0) {
238
+ return forkBumpedExpiry(expirySlot, forkActivationSlot, GRACE_PERIOD_N);
239
+ }
240
+ /**
241
+ * The fork bump shared by licenses and permits: an expiry before the fork
242
+ * slot, but within `grace` + MIGRATION_BUMP_LOOKBACK_N of it (it lapsed
243
+ * during the pre-fork freeze, when it couldn't be renewed), counts as
244
+ * expiring at the fork slot. Licenses use their 7-day grace, permits their
245
+ * registry's grace period.
246
+ */
247
+ export function forkBumpedExpiry(expirySlot, forkActivationSlot, grace) {
248
+ return expirySlot < forkActivationSlot && expirySlot + grace + MIGRATION_BUMP_LOOKBACK_N >= forkActivationSlot
249
+ ? forkActivationSlot : expirySlot;
250
+ }
85
251
  export const EMPTY = Field(0);
86
252
  export const EMPTY_ROOT = new MerkleMap().getRoot();
87
253
  // ------------------------------------------------------------
88
254
  // DURATION HELPERS
89
255
  // ------------------------------------------------------------
90
- export const DURATION_LABELS = ['1 Month', '1 Year', '5 Years'];
91
- export const DURATION_INDEX = { '1 Month': 0, '1 Year': 1, '5 Years': 2 };
256
+ export const DURATION_LABELS = ['1 Month', '1 Year', '5 Years', 'Perpetual'];
257
+ export const DURATION_INDEX = { '1 Month': 0, '1 Year': 1, '5 Years': 2, 'Perpetual': 3 };
92
258
  export function durationSlotsFromLabel(label) {
93
259
  if (label === '1 Month')
94
260
  return MONTHLY_SLOTS_N;
@@ -96,6 +262,8 @@ export function durationSlotsFromLabel(label) {
96
262
  return ONE_YEAR_SLOTS_N;
97
263
  if (label === '5 Years')
98
264
  return FIVE_YEAR_SLOTS_N;
265
+ if (label === 'Perpetual')
266
+ return PERPETUAL_SLOTS_N;
99
267
  return null;
100
268
  }
101
269
  export function durationIndexFromLabel(label) {
@@ -105,6 +273,8 @@ export function durationIndexFromLabel(label) {
105
273
  return 1;
106
274
  if (label === '5 Years')
107
275
  return 2;
276
+ if (label === 'Perpetual')
277
+ return 3;
108
278
  return null;
109
279
  }
110
280
  export function durationLabelFromIndex(idx) {
@@ -123,16 +293,23 @@ export class LicensingAppEventsContract extends SmartContract {
123
293
  licenseIssued: LicenseIssuedEvent,
124
294
  licenseIssuedNoEscrow: LicenseIssuedEvent,
125
295
  licenseRenewed: ExpiryUpdateEvent,
126
- licenseMigrated: LicenseMigratedEvent,
296
+ appRetired: AppRetiredEvent,
127
297
  refundIssued: Field,
128
298
  fundsReleased: Field,
129
299
  priceUpdated: PriceUpdatedEvent,
300
+ deviceBound: DeviceBoundEvent,
301
+ deviceUnbound: DeviceUnboundEvent,
302
+ licenseTransferred: LicenseTransferredEvent,
303
+ vendorChanged: VendorChangedEvent,
304
+ payoutProposed: PayoutProposedEvent,
305
+ payoutChanged: PayoutChangedEvent,
306
+ platformChanged: PlatformChangedEvent,
130
307
  };
131
308
  }
132
309
  // State-slot layout mirrors LicensingApp's declareState(). Read-only from here
133
310
  // — no @method bodies exist. Consumers use `.version.get()`, `.licensesRoot.get()`
134
- // etc. after fetchAccount(). `pricesPacked` is a single Field with the three
135
- // UInt64 tier prices packed as [pM | pY<<64 | pF<<128]; unpack with
311
+ // etc. after fetchAccount(). `pricesPacked` is a single Field with the four
312
+ // 63-bit tier prices packed as [pM | pY<<63 | pF<<126 | pP<<189]; unpack with
136
313
  // `unpackPrices` if you need the individual tiers off-chain.
137
314
  declareState(LicensingAppEventsContract, {
138
315
  licensesRoot: Field,
@@ -141,17 +318,32 @@ declareState(LicensingAppEventsContract, {
141
318
  pricesPacked: Field,
142
319
  version: UInt32,
143
320
  ancestorsRoot: Field,
321
+ forkActivationSlot: UInt32,
322
+ deviceCap: UInt32,
323
+ retired: Field,
324
+ successor: PublicKey,
325
+ payout: PublicKey,
326
+ pendingPayout: PublicKey,
327
+ pendingPayoutSlot: UInt32,
328
+ platform: PublicKey,
329
+ treasury: PublicKey,
330
+ platformEpoch: UInt32,
331
+ vendorNonce: UInt32,
332
+ networkId: Field,
144
333
  });
145
334
  // Off-chain mirror of the in-circuit price packing (see LicensingApp.ts). Kept
146
335
  // here so the events service can decode `pricesPacked` slots without pulling
147
- // the private contract source.
336
+ // the private contract source. Layout: four 63-bit tiers = 252 bits, fits in
337
+ // the ~254-bit Field. Each tier's high bit is unused — a UInt64 written by
338
+ // packPrices is range-checked to 63 bits in circuit.
148
339
  export function unpackPrices(packed) {
149
340
  const raw = packed.toBigInt();
150
- const mask = (1n << 64n) - 1n;
341
+ const mask = (1n << 63n) - 1n;
151
342
  return {
152
343
  priceMonthly: UInt64.from(raw & mask),
153
- priceYearly: UInt64.from((raw >> 64n) & mask),
154
- priceFiveYear: UInt64.from((raw >> 128n) & mask),
344
+ priceYearly: UInt64.from((raw >> 63n) & mask),
345
+ priceFiveYear: UInt64.from((raw >> 126n) & mask),
346
+ pricePerpetual: UInt64.from((raw >> 189n) & mask),
155
347
  };
156
348
  }
157
349
  // ------------------------------------------------------------
@@ -159,7 +351,7 @@ export function unpackPrices(packed) {
159
351
  //
160
352
  // On-chain `version` slot is set at init() and can never change (setPermissions
161
353
  // is impossible; setVerificationKey is impossibleDuringCurrentVersion). A
162
- // keeper / verifier that only understands v1 state decodes must refuse to serve
354
+ // backend / verifier that only understands v1 state decodes must refuse to serve
163
355
  // a zkApp deployed from a different source revision — otherwise it could
164
356
  // mis-decode events or feed a stale state format to the verifier.
165
357
  //
@@ -186,7 +378,7 @@ export async function fetchLicensingAppVersion(zkAppAddress) {
186
378
  // ------------------------------------------------------------
187
379
  // CANONICAL VK HASHES
188
380
  //
189
- // Per-generation, append-only. The keeper boots with `LicensingApp.compile()`
381
+ // Per-generation, append-only. The backend boots with `LicensingApp.compile()`
190
382
  // and asserts the resulting VK hash matches `CANONICAL_VK_HASH` (the current
191
383
  // generation's row); the verify service resolves an address's generation via
192
384
  // AppRecord.deploymentHistory and asserts the on-chain VK hash matches
@@ -197,17 +389,16 @@ export async function fetchLicensingAppVersion(zkAppAddress) {
197
389
  // `deploymentHistory[]`, so the resolver returns null and verify rejects.
198
390
  //
199
391
  // Rules:
200
- // - Append the new generation's row at each hardfork migration; never
392
+ // - Append the new generation's row at each circuit release; never
201
393
  // delete historical rows.
202
394
  // - Bump `CURRENT_GENERATION` to the new key alongside the row.
203
- // - `CANONICAL_VK_HASH` is derived from the record — drift test and keeper
395
+ // - `CANONICAL_VK_HASH` is derived from the record — drift test and backend
204
396
  // boot-assert are unchanged.
205
397
  // ------------------------------------------------------------
206
398
  export const CANONICAL_VK_HASHES = {
207
- 1: '25510637873522061606403949338800808972643356911784243535869508122414992770753',
208
- // 2: '…' — append at each hardfork migration, never delete.
399
+ 1: '24356937757056509770089463595975375774248178850824042790271400407790662393035',
400
+ // 2: '…' — append at each circuit release, never delete.
209
401
  };
210
402
  export const CURRENT_GENERATION = 1;
211
403
  export const CANONICAL_VK_HASH = CANONICAL_VK_HASHES[CURRENT_GENERATION];
212
- export const CANONICAL_LICENSE_PROOF_VK_HASH = '6592142093294558010952934797827640785154417146015648013584661926355710165692';
213
404
  //# sourceMappingURL=contractInterface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contractInterface.js","sourceRoot":"","sources":["../src/contractInterface.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export type ContractType = 'licensing' | 'permits';
2
+ export declare const CONTRACT_TYPES: readonly ContractType[];
3
+ /** Canonical VK hashes by contract type, each keyed by generation. */
4
+ export declare const CANONICAL_VK_HASHES_BY_TYPE: Readonly<Record<ContractType, Readonly<Record<number, string>>>>;
5
+ /** Reads an optional `contractType` field; absent or unknown-but-empty → licensing. */
6
+ export declare function contractTypeOf(value: {
7
+ contractType?: unknown;
8
+ } | null | undefined): ContractType;
9
+ //# sourceMappingURL=contractTypes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contractTypes.d.ts","sourceRoot":"","sources":["../src/contractTypes.ts"],"names":[],"mappings":"AAeA,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG,SAAS,CAAC;AACnD,eAAO,MAAM,cAAc,EAAE,SAAS,YAAY,EAA6B,CAAC;AAEhF,sEAAsE;AACtE,eAAO,MAAM,2BAA2B,EAAE,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAGxG,CAAC;AAEF,uFAAuF;AACvF,wBAAgB,cAAc,CAAC,KAAK,EAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,GAAG,YAAY,CAKjG"}
@@ -0,0 +1,28 @@
1
+ // Copyright (c) 2025-2026 zkLicensing project developers
2
+ // SPDX-License-Identifier: BUSL-1.1
3
+ /**
4
+ * contractTypes.ts — `zklicensing/contract-types`
5
+ *
6
+ * The two contract types the platform runs and where they meet: the
7
+ * verification-key table by type. A missing type anywhere (manifest,
8
+ * well-known file, record) means `licensing`, so everything published
9
+ * before permits existed keeps its meaning.
10
+ */
11
+ import { CANONICAL_VK_HASHES } from './contractInterface.js';
12
+ import { CANONICAL_PERMIT_VK_HASHES } from './permitInterface.js';
13
+ export const CONTRACT_TYPES = ['licensing', 'permits'];
14
+ /** Canonical VK hashes by contract type, each keyed by generation. */
15
+ export const CANONICAL_VK_HASHES_BY_TYPE = {
16
+ licensing: CANONICAL_VK_HASHES,
17
+ permits: CANONICAL_PERMIT_VK_HASHES,
18
+ };
19
+ /** Reads an optional `contractType` field; absent or unknown-but-empty → licensing. */
20
+ export function contractTypeOf(value) {
21
+ const t = value?.contractType;
22
+ if (t === undefined || t === null || t === '')
23
+ return 'licensing';
24
+ if (t === 'licensing' || t === 'permits')
25
+ return t;
26
+ throw new Error(`unknown contractType: ${String(t)}`);
27
+ }
28
+ //# sourceMappingURL=contractTypes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contractTypes.js","sourceRoot":"","sources":["../src/contractTypes.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,oCAAoC;AAEpC;;;;;;;GAOG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAGlE,MAAM,CAAC,MAAM,cAAc,GAA4B,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;AAEhF,sEAAsE;AACtE,MAAM,CAAC,MAAM,2BAA2B,GAAqE;IAC3G,SAAS,EAAE,mBAAmB;IAC9B,OAAO,EAAE,0BAA0B;CACpC,CAAC;AAEF,uFAAuF;AACvF,MAAM,UAAU,cAAc,CAAC,KAAoD;IACjF,MAAM,CAAC,GAAG,KAAK,EAAE,YAAY,CAAC;IAC9B,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,EAAE;QAAE,OAAO,WAAW,CAAC;IAClE,IAAI,CAAC,KAAK,WAAW,IAAI,CAAC,KAAK,SAAS;QAAE,OAAO,CAAC,CAAC;IACnD,MAAM,IAAI,KAAK,CAAC,yBAAyB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AACxD,CAAC"}
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Buyer-country breakdown of a vendor's revenue, bucketed by UTC calendar year.
5
5
  * Structured for tax reporting: one row per (year, appId, countryCode) with
6
- * license count + the vendor's cut in MINA. Both the keeper (source of
6
+ * license count + the vendor's cut in MINA. Both the backend (source of
7
7
  * truth for /stats) and the dashboard UI import from here so the numbers can
8
8
  * never drift between them.
9
9
  *
@@ -17,10 +17,19 @@
17
17
  *
18
18
  * Browser-safe: pure computation, no fs, no fetch.
19
19
  */
20
- import type { LicenseRecord } from './licenseRecord.js';
20
+ import { type LicenseRecord } from './licenseRecord.js';
21
+ export { zipToState } from './zipToState.js';
21
22
  export type CountryBucket = {
22
23
  count: number;
23
24
  revenueMina: number;
25
+ grossMina: number;
26
+ estimatedVatMina?: number;
27
+ vatRates?: number[];
28
+ states?: Record<string, {
29
+ count: number;
30
+ revenueMina: number;
31
+ grossMina: number;
32
+ }>;
24
33
  };
25
34
  export type CountryYearBreakdown = {
26
35
  aggregate: Record<string, CountryBucket>;
@@ -33,5 +42,5 @@ export type CountryBreakdown = {
33
42
  export declare function computeCountryBreakdown(apps: {
34
43
  appId: string;
35
44
  zkAppAddress: string;
36
- }[], records: LicenseRecord[], currentSlot: number, nowMs: number): CountryBreakdown;
45
+ }[], records: LicenseRecord[], currentSlot: number, nowMs: number, tzOffsetMinutes?: number): CountryBreakdown;
37
46
  //# sourceMappingURL=countryStats.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"countryStats.d.ts","sourceRoot":"","sources":["../src/countryStats.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAmB,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAIzE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAS7C,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IAGpB,SAAS,EAAE,MAAM,CAAC;IAKlB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAG1B,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAOpB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpF,CAAC;AACF,MAAM,MAAM,oBAAoB,GAAG;IACjC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACzC,KAAK,EAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;CAC1D,CAAC;AACF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAG,MAAM,EAAE,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;CAC9C,CAAC;AAOF,wBAAgB,uBAAuB,CACrC,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,EAAE,EAC/C,OAAO,EAAE,aAAa,EAAE,EACxB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,eAAe,GAAE,MAAU,GAC1B,gBAAgB,CAyHlB"}