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,235 @@
1
+ #!/usr/bin/env node
2
+ // Copyright (c) 2025-2026 zkLicensing project developers
3
+ // SPDX-License-Identifier: BUSL-1.1
4
+ /**
5
+ * trustAnchorVerifyCli.ts
6
+ *
7
+ * Command-line front-end for verifyTrustAnchor(). Ships as the `zklicensing-verify-trust`
8
+ * bin — the sibling of `zklicensing-verify` (which is the verifyService HTTP daemon).
9
+ *
10
+ * Usage:
11
+ * zklicensing-verify-trust \
12
+ * --origin https://store.example.com \
13
+ * --address B62q... \
14
+ * --pinned-key <base64-ed25519-pubkey> \
15
+ * [--mina-graphql https://api.minascan.io/node/mainnet/v1/graphql] \
16
+ * [--mina-network-id mainnet|testnet|devnet] \
17
+ * [--skip-chain-checks] \
18
+ * [--json]
19
+ *
20
+ * The manifest lives at `<origin>/.well-known/zklicensing/<address>.json` —
21
+ * one file per generation address, all signed by the same platform key. The
22
+ * appId is read out of the signed payload; callers never need to know it
23
+ * out-of-band, which lets buyers verify from just the address their wallet
24
+ * shows them (including addresses for retired generations).
25
+ *
26
+ * Permit registries:
27
+ * zklicensing-verify-trust --registry B62q... [--origin https://authority.example]
28
+ * [--mina-network-id mainnet|devnet] [--keeper-url https://zklicensing.com/api/keeper]
29
+ * [--no-well-known] [--mina-graphql <url>] [--json]
30
+ * checks the registry's verification key against the published PermitRegistry
31
+ * hashes, its locked permissions and network binding, the authority website
32
+ * written into it at deploy (on the --origin host, when given) and that the
33
+ * website's /.well-known/zkpermits/<address>.json claims it, and (with
34
+ * --keeper-url) that the keeper's authority keys, payout and website match.
35
+ *
36
+ * Exit codes:
37
+ * 0 — every finding passed
38
+ * 1 — one or more findings failed
39
+ * 2 — invalid arguments
40
+ *
41
+ * --pinned-key is required and may be repeated; the CLI ships NO baked-in
42
+ * pin. Source it from https://zklicensing.com/trustanchor.html (published
43
+ * next to each generation's VK hash). See the SDK README for details.
44
+ */
45
+ import { verifyTrustAnchor } from './trustAnchorVerify.js';
46
+ import { verifyRegistryTrust } from './registryTrustVerify.js';
47
+ const DEFAULT_GRAPHQL = {
48
+ mainnet: 'https://api.minascan.io/node/mainnet/v1/graphql',
49
+ // O1 Labs' devnet-plain node is the reliable public endpoint for freshly
50
+ // deployed accounts — public indexers like Minascan lag by several slots
51
+ // and often return null for a zkApp minutes after landing.
52
+ devnet: 'https://devnet-plain-1.gcp.o1test.net/graphql',
53
+ };
54
+ function usage() {
55
+ return [
56
+ 'zklicensing-verify-trust — verify a vendor page + on-chain zkApp mutually bind',
57
+ '',
58
+ 'Required:',
59
+ ' --origin <url> Vendor origin (https://...)',
60
+ ' --address <B62q...> zkApp address (the address your wallet shows you)',
61
+ ' --pinned-key <b64> Platform manifest pubkey (repeatable during rotation)',
62
+ '',
63
+ 'Or, for a permit registry:',
64
+ ' --registry <B62q...> Registry address; checks VK, permissions, network,',
65
+ ' the website bound at deploy and its .well-known claim',
66
+ ' --origin <url> The authority website you expect (compared by host)',
67
+ ' --keeper-url <url> Also compare the keeper\'s authority keys, payout, website',
68
+ ' --no-well-known Skip fetching <website>/.well-known/zkpermits/<registry>.json',
69
+ '',
70
+ 'Optional:',
71
+ ' --mina-graphql <url> Mina GraphQL endpoint (default depends on',
72
+ ' --mina-network-id: mainnet →',
73
+ ` ${DEFAULT_GRAPHQL.mainnet};`,
74
+ ` devnet → ${DEFAULT_GRAPHQL.devnet})`,
75
+ ' --mina-network-id <id> mainnet | devnet (default: devnet)',
76
+ ' --skip-chain-checks Manifest-only audit — no o1js chain reads',
77
+ ' --no-cross-check Skip the platform backend cross-check',
78
+ ' (default: on — verifies vendor manifest matches',
79
+ ' https://zklicensing.com/apps/by-address/<address>)',
80
+ ' --json Emit TrustAnchorReport as JSON on stdout',
81
+ '',
82
+ 'Exit: 0 all-ok · 1 any check failed · 2 bad args',
83
+ ].join('\n');
84
+ }
85
+ function parseArgs(argv) {
86
+ const args = {
87
+ pinnedKeys: [],
88
+ minaNetworkId: 'devnet',
89
+ skipChainChecks: false,
90
+ // Default on — the platform backend cross-check is cheap and catches
91
+ // vendors whose local manifest has drifted from the signed platform
92
+ // record. Opt out with --no-cross-check for a pure origin+chain audit.
93
+ crossCheck: true,
94
+ wellKnown: true,
95
+ json: false,
96
+ help: false,
97
+ };
98
+ for (let i = 0; i < argv.length; i++) {
99
+ const a = argv[i];
100
+ const next = () => {
101
+ const v = argv[++i];
102
+ if (v === undefined)
103
+ throw new Error(`missing value for ${a}`);
104
+ return v;
105
+ };
106
+ switch (a) {
107
+ case '--origin':
108
+ args.origin = next();
109
+ break;
110
+ case '--address':
111
+ args.address = next();
112
+ break;
113
+ case '--registry':
114
+ args.registry = next();
115
+ break;
116
+ case '--keeper-url':
117
+ args.keeperUrl = next();
118
+ break;
119
+ case '--pinned-key':
120
+ args.pinnedKeys.push(next());
121
+ break;
122
+ case '--mina-graphql':
123
+ args.minaGraphql = next();
124
+ break;
125
+ case '--mina-network-id': {
126
+ const v = next();
127
+ if (v !== 'mainnet' && v !== 'devnet') {
128
+ throw new Error(`--mina-network-id must be mainnet|devnet, got "${v}"`);
129
+ }
130
+ args.minaNetworkId = v;
131
+ break;
132
+ }
133
+ case '--skip-chain-checks':
134
+ args.skipChainChecks = true;
135
+ break;
136
+ case '--no-well-known':
137
+ args.wellKnown = false;
138
+ break;
139
+ // Kept as a no-op flag so any existing invocation that passed
140
+ // --cross-check keeps working. --no-cross-check opts out.
141
+ case '--cross-check':
142
+ args.crossCheck = true;
143
+ break;
144
+ case '--no-cross-check':
145
+ args.crossCheck = false;
146
+ break;
147
+ case '--json':
148
+ args.json = true;
149
+ break;
150
+ case '-h':
151
+ case '--help':
152
+ args.help = true;
153
+ break;
154
+ default: throw new Error(`unknown argument: ${a}`);
155
+ }
156
+ }
157
+ return args;
158
+ }
159
+ function formatHuman(report) {
160
+ const lines = [];
161
+ const banner = report.ok ? 'TRUST ANCHOR VERIFIED' : 'TRUST ANCHOR FAILED';
162
+ lines.push(banner);
163
+ lines.push(` origin: ${report.origin}`);
164
+ lines.push(` address: ${report.address}`);
165
+ if (report.appId)
166
+ lines.push(` appId: ${report.appId}`);
167
+ if (report.generation !== undefined)
168
+ lines.push(` generation: ${report.generation}`);
169
+ lines.push('');
170
+ for (const f of report.findings) {
171
+ const mark = f.ok ? '[ok] ' : '[FAIL]';
172
+ lines.push(` ${mark} ${f.name} — ${f.detail}`);
173
+ }
174
+ return lines.join('\n');
175
+ }
176
+ async function main() {
177
+ let args;
178
+ try {
179
+ args = parseArgs(process.argv.slice(2));
180
+ }
181
+ catch (err) {
182
+ process.stderr.write(`${err.message}\n\n${usage()}\n`);
183
+ return 2;
184
+ }
185
+ if (args.help) {
186
+ process.stdout.write(`${usage()}\n`);
187
+ return 0;
188
+ }
189
+ if (args.registry) {
190
+ const report = await verifyRegistryTrust({
191
+ address: args.registry, network: args.minaNetworkId, minaGraphqlUrl: args.minaGraphql, keeperUrl: args.keeperUrl,
192
+ website: args.origin, checkWellKnown: args.wellKnown,
193
+ });
194
+ if (args.json)
195
+ process.stdout.write(JSON.stringify(report, null, 2) + '\n');
196
+ else {
197
+ process.stdout.write([report.ok ? 'REGISTRY VERIFIED' : 'REGISTRY FAILED', ` registry: ${report.address}`, ` network: ${report.network}`, '',
198
+ ...(report.findings.some(f => f.name === 'website_claims_registry' && !f.ok) ? [` The authority publishes the claim at <website>/.well-known/zkpermits/${report.address}.json`, ''] : []),
199
+ ...report.findings.map(f => ` ${f.ok ? '[ok] ' : '[FAIL]'} ${f.name} — ${f.detail}`)].join('\n') + '\n');
200
+ }
201
+ return report.ok ? 0 : 1;
202
+ }
203
+ const missing = [];
204
+ if (!args.origin)
205
+ missing.push('--origin');
206
+ if (!args.address)
207
+ missing.push('--address');
208
+ if (args.pinnedKeys.length === 0)
209
+ missing.push('--pinned-key');
210
+ if (missing.length > 0) {
211
+ process.stderr.write(`missing required argument(s): ${missing.join(', ')}\n\n${usage()}\n`);
212
+ return 2;
213
+ }
214
+ const report = await verifyTrustAnchor({
215
+ origin: args.origin,
216
+ address: args.address,
217
+ pinnedPublicKeysBase64: args.pinnedKeys,
218
+ minaGraphqlUrl: args.minaGraphql ?? DEFAULT_GRAPHQL[args.minaNetworkId],
219
+ minaNetworkId: args.minaNetworkId,
220
+ skipChainChecks: args.skipChainChecks,
221
+ crossCheck: args.crossCheck,
222
+ });
223
+ if (args.json) {
224
+ process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
225
+ }
226
+ else {
227
+ process.stdout.write(`${formatHuman(report)}\n`);
228
+ }
229
+ return report.ok ? 0 : 1;
230
+ }
231
+ main().then((code) => process.exit(code), (err) => {
232
+ process.stderr.write(`unexpected error: ${err?.stack ?? err}\n`);
233
+ process.exit(1);
234
+ });
235
+ //# sourceMappingURL=trustAnchorVerifyCli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trustAnchorVerifyCli.js","sourceRoot":"","sources":["../src/trustAnchorVerifyCli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * txBroadcastClient.ts
3
+ *
4
+ * Small helper for POST /tx-broadcast. Called by the buy/renew/migrate
5
+ * flows immediately after the buyer's wallet returns a txHash — signals
6
+ * the backend to extend the app's in-flight slot from the short signing-TTL
7
+ * to the longer landing-TTL, so concurrent buyers on the same app don't
8
+ * think the slot has expired while an honest signed tx is still in the
9
+ * mempool.
10
+ *
11
+ * Fire-and-forget by design: this is a tightening signal, not a
12
+ * correctness dependency. Land-clear in the buy-watcher and the
13
+ * signing-TTL both remain live regardless of whether this call succeeds.
14
+ * Failures are swallowed with an optional log callback so a network blip
15
+ * doesn't surface as a confusing error mid-checkout.
16
+ */
17
+ export type NotifyBroadcastRequest = {
18
+ keeperUrl: string;
19
+ appId: string;
20
+ txHash: string;
21
+ fetcher?: typeof fetch;
22
+ signal?: AbortSignal;
23
+ onError?: (err: unknown) => void;
24
+ };
25
+ export declare function notifyBroadcast(req: NotifyBroadcastRequest): Promise<void>;
26
+ //# sourceMappingURL=txBroadcastClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"txBroadcastClient.d.ts","sourceRoot":"","sources":["../src/txBroadcastClient.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,MAAM,sBAAsB,GAAG;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAM,MAAM,CAAC;IAClB,MAAM,EAAK,MAAM,CAAC;IAClB,OAAO,CAAC,EAAG,OAAO,KAAK,CAAC;IACxB,MAAM,CAAC,EAAI,WAAW,CAAC;IAGvB,OAAO,CAAC,EAAG,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;CACnC,CAAC;AAMF,wBAAsB,eAAe,CAAC,GAAG,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAYhF"}
@@ -0,0 +1,20 @@
1
+ // Copyright (c) 2025-2026 zkLicensing project developers
2
+ // SPDX-License-Identifier: BUSL-1.1
3
+ function baseUrl(url) {
4
+ return url.replace(/\/+$/, '');
5
+ }
6
+ export async function notifyBroadcast(req) {
7
+ const fetcher = req.fetcher ?? fetch;
8
+ try {
9
+ await fetcher(`${baseUrl(req.keeperUrl)}/tx-broadcast`, {
10
+ method: 'POST',
11
+ headers: { 'Content-Type': 'application/json' },
12
+ signal: req.signal,
13
+ body: JSON.stringify({ appId: req.appId, txHash: req.txHash }),
14
+ });
15
+ }
16
+ catch (err) {
17
+ req.onError?.(err);
18
+ }
19
+ }
20
+ //# sourceMappingURL=txBroadcastClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"txBroadcastClient.js","sourceRoot":"","sources":["../src/txBroadcastClient.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,oCAAoC;AA8BpC,SAAS,OAAO,CAAC,GAAW;IAC1B,OAAO,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,GAA2B;IAC/D,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,KAAK,CAAC;IACrC,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,eAAe,EAAE;YACtD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;SAC/D,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;AACH,CAAC"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * unbindClient.ts
3
+ *
4
+ * Browser-safe client for the non-custodial device-unbinding flow.
5
+ * Mirrors `bindClient.ts` in shape: signs the unbind message with
6
+ * TAG_UNBINDING, POSTs to /prove/unbind, then /confirm/unbind after
7
+ * the wallet returns a txHash.
8
+ *
9
+ * Notable asymmetry with bind: the unbind message shape carries the
10
+ * deviceCommitment position too, but the backend and circuit both
11
+ * hard-code it to `Field(0)` (the "not about any specific new
12
+ * device" sentinel — the message is about freeing a slot, not
13
+ * introducing a new device). The SDK matches by omitting
14
+ * deviceCommitment from the request and using "0" when computing
15
+ * the signature preimage.
16
+ *
17
+ * Non-custodial invariant: the signature is re-verified in-circuit
18
+ * against the leaf's `licenseHash` (which IS the owner-pubkey
19
+ * commitment — the circuit asserts equality at buy time), so no
20
+ * backend / vendor can unilaterally kick a device — only the
21
+ * passphrase holder can.
22
+ * A user who lost the physical device but still has the passphrase
23
+ * can unbind the missing device's slot from any device that holds
24
+ * the ownership key (the "remote log-off" case).
25
+ */
26
+ import { PrivateKey } from 'o1js';
27
+ export type ProveUnbindRequest = {
28
+ keeperUrl: string;
29
+ network: 'devnet' | 'mainnet';
30
+ zkAppAddress: string;
31
+ licenseHash: string;
32
+ ownerPrivateKey: PrivateKey;
33
+ slotIndex: number;
34
+ buyerAddress: string;
35
+ nonce?: string;
36
+ slotState?: string;
37
+ expirySlot?: number;
38
+ fetcher?: typeof fetch;
39
+ signal?: AbortSignal;
40
+ };
41
+ export type ProveUnbindResponse = {
42
+ provenTxJson: string;
43
+ licenseHash: string;
44
+ slotIndex: number;
45
+ };
46
+ export type ConfirmUnbindRequest = {
47
+ keeperUrl: string;
48
+ zkAppAddress: string;
49
+ licenseHash: string;
50
+ txHash: string;
51
+ fetcher?: typeof fetch;
52
+ signal?: AbortSignal;
53
+ };
54
+ export declare function proveUnbind(req: ProveUnbindRequest): Promise<ProveUnbindResponse>;
55
+ export declare function confirmUnbind(req: ConfirmUnbindRequest): Promise<{
56
+ ok: true;
57
+ }>;
58
+ export type UnbindStatus = {
59
+ status: 'confirmed' | 'pending' | 'unknown';
60
+ slotIndex?: number;
61
+ deviceCommitment?: string;
62
+ elapsedMs?: number;
63
+ };
64
+ export type PollUnbindStatusOptions = {
65
+ keeperUrl: string;
66
+ network: 'devnet' | 'mainnet';
67
+ zkAppAddress: string;
68
+ licenseHash: string;
69
+ slotIndex: number;
70
+ fetcher?: typeof fetch;
71
+ intervalMs?: number;
72
+ timeoutMs?: number;
73
+ signal?: AbortSignal;
74
+ onTick?: (status: UnbindStatus) => void;
75
+ };
76
+ export declare function pollUnbindStatus(opts: PollUnbindStatusOptions): Promise<UnbindStatus>;
77
+ //# sourceMappingURL=unbindClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unbindClient.d.ts","sourceRoot":"","sources":["../src/unbindClient.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAS,UAAU,EAAwB,MAAM,MAAM,CAAC;AAK/D,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,EAAQ,MAAM,CAAC;IACxB,OAAO,EAAU,QAAQ,GAAG,SAAS,CAAC;IACtC,YAAY,EAAK,MAAM,CAAC;IACxB,WAAW,EAAM,MAAM,CAAC;IACxB,eAAe,EAAE,UAAU,CAAC;IAE5B,SAAS,EAAQ,MAAM,CAAC;IACxB,YAAY,EAAK,MAAM,CAAC;IAGxB,KAAK,CAAC,EAAW,MAAM,CAAC;IAGxB,SAAS,CAAC,EAAO,MAAM,CAAC;IACxB,UAAU,CAAC,EAAM,MAAM,CAAC;IACxB,OAAO,CAAC,EAAS,OAAO,KAAK,CAAC;IAC9B,MAAM,CAAC,EAAU,WAAW,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAG,MAAM,CAAC;IACrB,SAAS,EAAK,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,SAAS,EAAK,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAG,MAAM,CAAC;IACrB,MAAM,EAAQ,MAAM,CAAC;IACrB,OAAO,CAAC,EAAM,OAAO,KAAK,CAAC;IAC3B,MAAM,CAAC,EAAO,WAAW,CAAC;CAC3B,CAAC;AAgCF,wBAAsB,WAAW,CAAC,GAAG,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA2CvF;AAGD,wBAAsB,aAAa,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,CAAC,CAcpF;AAED,MAAM,MAAM,YAAY,GAAG;IAKzB,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,SAAS,CAAC;IAC5C,SAAS,CAAC,EAAS,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAS,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,SAAS,EAAK,MAAM,CAAC;IACrB,OAAO,EAAO,QAAQ,GAAG,SAAS,CAAC;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAG,MAAM,CAAC;IACrB,SAAS,EAAK,MAAM,CAAC;IACrB,OAAO,CAAC,EAAM,OAAO,KAAK,CAAC;IAC3B,UAAU,CAAC,EAAG,MAAM,CAAC;IACrB,SAAS,CAAC,EAAI,MAAM,CAAC;IACrB,MAAM,CAAC,EAAO,WAAW,CAAC;IAC1B,MAAM,CAAC,EAAO,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,CAAC;CAC9C,CAAC;AAKF,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,uBAAuB,GAAG,OAAO,CAAC,YAAY,CAAC,CA4C3F"}
@@ -0,0 +1,169 @@
1
+ // Copyright (c) 2025-2026 zkLicensing project developers
2
+ // SPDX-License-Identifier: BUSL-1.1
3
+ /**
4
+ * unbindClient.ts
5
+ *
6
+ * Browser-safe client for the non-custodial device-unbinding flow.
7
+ * Mirrors `bindClient.ts` in shape: signs the unbind message with
8
+ * TAG_UNBINDING, POSTs to /prove/unbind, then /confirm/unbind after
9
+ * the wallet returns a txHash.
10
+ *
11
+ * Notable asymmetry with bind: the unbind message shape carries the
12
+ * deviceCommitment position too, but the backend and circuit both
13
+ * hard-code it to `Field(0)` (the "not about any specific new
14
+ * device" sentinel — the message is about freeing a slot, not
15
+ * introducing a new device). The SDK matches by omitting
16
+ * deviceCommitment from the request and using "0" when computing
17
+ * the signature preimage.
18
+ *
19
+ * Non-custodial invariant: the signature is re-verified in-circuit
20
+ * against the leaf's `licenseHash` (which IS the owner-pubkey
21
+ * commitment — the circuit asserts equality at buy time), so no
22
+ * backend / vendor can unilaterally kick a device — only the
23
+ * passphrase holder can.
24
+ * A user who lost the physical device but still has the passphrase
25
+ * can unbind the missing device's slot from any device that holds
26
+ * the ownership key (the "remote log-off" case).
27
+ */
28
+ import { Field } from 'o1js';
29
+ import { readErrorBody, tryQueueBusyFromBody, keeperError } from './proveErrors.js';
30
+ import { encodePublicKey, encodeSignature, signUnbinding } from './ownershipSignature.js';
31
+ import { fetchBindingState } from './bindClient.js';
32
+ function baseUrl(url) {
33
+ return url.replace(/\/+$/, '');
34
+ }
35
+ async function readJsonError(resp) {
36
+ try {
37
+ const body = await resp.json();
38
+ if (typeof body.error === 'string')
39
+ return body.error;
40
+ }
41
+ catch { /* body wasn't JSON */ }
42
+ return `HTTP ${resp.status}`;
43
+ }
44
+ function freshNonce() {
45
+ const crypto = globalThis.crypto;
46
+ if (!crypto?.getRandomValues) {
47
+ throw new Error('crypto.getRandomValues unavailable — unbindClient requires Node ≥ 20 or a modern browser');
48
+ }
49
+ const bytes = new Uint8Array(16); // 128 bits
50
+ crypto.getRandomValues(bytes);
51
+ let n = 0n;
52
+ for (const b of bytes)
53
+ n = (n << 8n) | BigInt(b);
54
+ return Field(n).toString();
55
+ }
56
+ // POST /prove/unbind — same retry contract as /prove/bind. Returns
57
+ // 409 `ProveQueueBusyError` when another root-mutating tx for the
58
+ // same app is in flight; the caller retries with the server-supplied
59
+ // `retryAfterMs` cadence.
60
+ export async function proveUnbind(req) {
61
+ const fetcher = req.fetcher ?? fetch;
62
+ const nonce = req.nonce ?? freshNonce();
63
+ const { slotState, expirySlot } = (req.slotState !== undefined && req.expirySlot !== undefined)
64
+ ? { slotState: req.slotState, expirySlot: req.expirySlot }
65
+ : await fetchBindingState({ ...req, fetcher });
66
+ const ownerPubKey = req.ownerPrivateKey.toPublicKey();
67
+ // deviceCommitment=0 for the preimage — matches TAG_UNBINDING's
68
+ // circuit-side check (see verifyUnbinding / bindingLikeFields in
69
+ // ownershipSignature.ts).
70
+ const ownerSig = signUnbinding(req.ownerPrivateKey, {
71
+ licenseHash: req.licenseHash,
72
+ deviceCommitment: '0',
73
+ slotIndex: req.slotIndex,
74
+ nonce,
75
+ slotState,
76
+ expirySlot,
77
+ zkAppAddress: req.zkAppAddress,
78
+ });
79
+ const resp = await fetcher(`${baseUrl(req.keeperUrl)}/prove/unbind`, {
80
+ method: 'POST',
81
+ headers: { 'Content-Type': 'application/json' },
82
+ signal: req.signal,
83
+ body: JSON.stringify({
84
+ licenseHash: req.licenseHash,
85
+ buyerAddress: req.buyerAddress,
86
+ zkAppAddress: req.zkAppAddress,
87
+ network: req.network,
88
+ ownerPubKey: encodePublicKey(ownerPubKey),
89
+ ownerSig: encodeSignature(ownerSig),
90
+ slotIndex: req.slotIndex,
91
+ nonce,
92
+ }),
93
+ });
94
+ if (!resp.ok) {
95
+ const parsed = await readErrorBody(resp);
96
+ const queueBusy = tryQueueBusyFromBody(parsed);
97
+ if (queueBusy)
98
+ throw queueBusy;
99
+ throw keeperError(parsed);
100
+ }
101
+ return await resp.json();
102
+ }
103
+ // POST /confirm/unbind — pass-through no-op mirror of /confirm/bind.
104
+ export async function confirmUnbind(req) {
105
+ const fetcher = req.fetcher ?? fetch;
106
+ const resp = await fetcher(`${baseUrl(req.keeperUrl)}/confirm/unbind`, {
107
+ method: 'POST',
108
+ headers: { 'Content-Type': 'application/json' },
109
+ signal: req.signal,
110
+ body: JSON.stringify({
111
+ zkAppAddress: req.zkAppAddress,
112
+ licenseHash: req.licenseHash,
113
+ txHash: req.txHash,
114
+ }),
115
+ });
116
+ if (!resp.ok)
117
+ throw new Error(await readJsonError(resp));
118
+ return { ok: true };
119
+ }
120
+ // Polls GET /license/:zkAppAddress/:licenseHash until the unbind has
121
+ // landed on-chain (the target slot's commitment is '0') or the timeout
122
+ // fires. Mirrors pollBindStatus in shape.
123
+ export async function pollUnbindStatus(opts) {
124
+ const fetcher = opts.fetcher ?? fetch;
125
+ const interval = opts.intervalMs ?? 10_000;
126
+ const timeout = opts.timeoutMs ?? 20 * 60 * 1000;
127
+ const startedAt = Date.now();
128
+ const deadline = startedAt + timeout;
129
+ const url = `${baseUrl(opts.keeperUrl)}/license/${encodeURIComponent(opts.zkAppAddress)}/${encodeURIComponent(opts.licenseHash)}?network=${opts.network}`;
130
+ while (true) {
131
+ if (opts.signal?.aborted)
132
+ throw new Error('pollUnbindStatus aborted');
133
+ let status = { status: 'unknown', elapsedMs: Date.now() - startedAt };
134
+ try {
135
+ const resp = await fetcher(url, { signal: opts.signal });
136
+ if (resp.ok) {
137
+ const body = await resp.json();
138
+ if (body.found) {
139
+ const slot = (body.devices ?? []).find(d => d.slotIndex === opts.slotIndex);
140
+ const commitment = slot?.deviceCommitment ?? '0';
141
+ if (commitment === '0') {
142
+ status = {
143
+ status: 'confirmed',
144
+ slotIndex: opts.slotIndex,
145
+ deviceCommitment: commitment,
146
+ elapsedMs: Date.now() - startedAt,
147
+ };
148
+ }
149
+ else {
150
+ status = {
151
+ status: 'pending',
152
+ slotIndex: opts.slotIndex,
153
+ deviceCommitment: commitment,
154
+ elapsedMs: Date.now() - startedAt,
155
+ };
156
+ }
157
+ }
158
+ }
159
+ }
160
+ catch { /* transient network — try again on next tick */ }
161
+ opts.onTick?.(status);
162
+ if (status.status === 'confirmed')
163
+ return status;
164
+ if (Date.now() >= deadline)
165
+ return status;
166
+ await new Promise((r) => setTimeout(r, interval));
167
+ }
168
+ }
169
+ //# sourceMappingURL=unbindClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unbindClient.js","sourceRoot":"","sources":["../src/unbindClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ export type MinaUnit = 'MINA' | 'tMINA';
2
+ /** 'tMINA' on devnet (and any test network), 'MINA' on mainnet. */
3
+ export declare function minaUnit(network: string): MinaUnit;
4
+ /** "12.5 tMINA" / "12.5 MINA" for an amount in MINA (number or decimal string). */
5
+ export declare function formatMina(amountMina: number | string, network: string): string;
6
+ /** "12.5 tMINA" for an amount in nanomina. */
7
+ export declare function formatNanomina(nano: bigint | string | number, network: string): string;
8
+ /**
9
+ * The words that go with a fiat value. Mainnet: "≈ €2.10". Devnet: the same
10
+ * amount of real MINA, said as such ("as MINA ≈ €2.10"), plus a note that
11
+ * tMINA itself has no value.
12
+ */
13
+ export declare function fiatReference(network: string): {
14
+ prefix: string;
15
+ note: string | null;
16
+ };
17
+ export type FiatCurrency = 'eur' | 'usd' | 'gbp';
18
+ /**
19
+ * Which money a person sees amounts in, by their country: euros in the EU,
20
+ * pounds and euros in the UK, dollars in the US, euros and dollars elsewhere
21
+ * (or when the country is unknown).
22
+ */
23
+ export declare function fiatCurrencies(country?: string | null): FiatCurrency[];
24
+ /** "€2.10", "-€26.78" for an amount of money. */
25
+ export declare function formatFiat(amount: number | string, currency: FiatCurrency, digits?: number): string;
26
+ /** "€2.10 · $2.30" for the given currencies (a currency without a rate is left out). */
27
+ export declare function formatFiatList(values: Partial<Record<FiatCurrency, number | string>>, currencies: FiatCurrency[], digits?: number): string;
28
+ //# sourceMappingURL=units.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"units.d.ts","sourceRoot":"","sources":["../src/units.ts"],"names":[],"mappings":"AAeA,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;AAExC,mEAAmE;AACnE,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,CAElD;AAED,mFAAmF;AACnF,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAE/E;AAED,8CAA8C;AAC9C,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAMtF;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAItF;AAED,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAGjD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,YAAY,EAAE,CAMtE;AAED,iDAAiD;AACjD,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAI,GAAG,MAAM,CAG9F;AAED,wFAAwF;AACxF,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,EAAE,UAAU,EAAE,YAAY,EAAE,EAAE,MAAM,SAAI,GAAG,MAAM,CAGrI"}