@attocash/cli 0.1.0

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 (400) hide show
  1. package/LICENSE +28 -0
  2. package/README.md +707 -0
  3. package/dist/application/app.d.ts +138 -0
  4. package/dist/application/app.js +654 -0
  5. package/dist/application/operations.d.ts +9 -0
  6. package/dist/application/operations.js +96 -0
  7. package/dist/cli/cli.d.ts +1 -0
  8. package/dist/cli/cli.js +460 -0
  9. package/dist/cli/help.d.ts +4 -0
  10. package/dist/cli/help.js +49 -0
  11. package/dist/cli/main.d.ts +2 -0
  12. package/dist/cli/main.js +13 -0
  13. package/dist/cli/onboarding.d.ts +14 -0
  14. package/dist/cli/onboarding.js +144 -0
  15. package/dist/cli/output.d.ts +2 -0
  16. package/dist/cli/output.js +231 -0
  17. package/dist/cli/terminal.d.ts +6 -0
  18. package/dist/cli/terminal.js +92 -0
  19. package/dist/cli/update-check.d.ts +1 -0
  20. package/dist/cli/update-check.js +12 -0
  21. package/dist/cli/updates.d.ts +2 -0
  22. package/dist/cli/updates.js +98 -0
  23. package/dist/core.d.ts +14 -0
  24. package/dist/core.js +14 -0
  25. package/dist/doctor/credential-probe.d.ts +7 -0
  26. package/dist/doctor/credential-probe.js +49 -0
  27. package/dist/doctor/doctor.d.ts +4 -0
  28. package/dist/doctor/doctor.js +213 -0
  29. package/dist/doctor/keyring.d.ts +7 -0
  30. package/dist/doctor/keyring.js +150 -0
  31. package/dist/doctor/profile.d.ts +19 -0
  32. package/dist/doctor/profile.js +73 -0
  33. package/dist/doctor/types.d.ts +40 -0
  34. package/dist/doctor/types.js +1 -0
  35. package/dist/domain/amount.d.ts +6 -0
  36. package/dist/domain/amount.js +27 -0
  37. package/dist/domain/errors.d.ts +10 -0
  38. package/dist/domain/errors.js +16 -0
  39. package/dist/labels/directory.d.ts +87 -0
  40. package/dist/labels/directory.js +140 -0
  41. package/dist/labels/personal.d.ts +17 -0
  42. package/dist/labels/personal.js +56 -0
  43. package/dist/labels/presentation.d.ts +154 -0
  44. package/dist/labels/presentation.js +90 -0
  45. package/dist/network/reader.d.ts +31 -0
  46. package/dist/network/reader.js +370 -0
  47. package/dist/network/retry.d.ts +7 -0
  48. package/dist/network/retry.js +53 -0
  49. package/dist/network/work.d.ts +3 -0
  50. package/dist/network/work.js +66 -0
  51. package/dist/pricing/market.d.ts +29 -0
  52. package/dist/pricing/market.js +150 -0
  53. package/dist/pricing/terms.d.ts +6 -0
  54. package/dist/pricing/terms.js +12 -0
  55. package/dist/spending/destination.d.ts +16 -0
  56. package/dist/spending/destination.js +42 -0
  57. package/dist/spending/journal.d.ts +28 -0
  58. package/dist/spending/journal.js +69 -0
  59. package/dist/spending/ledger.d.ts +118 -0
  60. package/dist/spending/ledger.js +444 -0
  61. package/dist/spending/payments.d.ts +67 -0
  62. package/dist/spending/payments.js +424 -0
  63. package/dist/spending/pool.d.ts +13 -0
  64. package/dist/spending/pool.js +38 -0
  65. package/dist/spending/reconcile.d.ts +18 -0
  66. package/dist/spending/reconcile.js +64 -0
  67. package/dist/storage/profiles.d.ts +13 -0
  68. package/dist/storage/profiles.js +86 -0
  69. package/dist/storage/secrets.d.ts +16 -0
  70. package/dist/storage/secrets.js +104 -0
  71. package/dist/storage/state.d.ts +32 -0
  72. package/dist/storage/state.js +255 -0
  73. package/dist/wallet/auto-receive.d.ts +57 -0
  74. package/dist/wallet/auto-receive.js +140 -0
  75. package/dist/wallet/defaults.d.ts +3 -0
  76. package/dist/wallet/defaults.js +26 -0
  77. package/dist/wallet/signing.d.ts +17 -0
  78. package/dist/wallet/signing.js +128 -0
  79. package/dist/wallet/types.d.ts +65 -0
  80. package/dist/wallet/types.js +1 -0
  81. package/dist/wallet/work.d.ts +29 -0
  82. package/dist/wallet/work.js +154 -0
  83. package/dist/watches/manager.d.ts +75 -0
  84. package/dist/watches/manager.js +197 -0
  85. package/node_modules/@attocash/commons-core/Kotlin-DateTime-library-kotlinx-datetime.mjs +6678 -0
  86. package/node_modules/@attocash/commons-core/Kotlin-DateTime-library-kotlinx-datetime.mjs.map +1 -0
  87. package/node_modules/@attocash/commons-core/LICENSE +28 -0
  88. package/node_modules/@attocash/commons-core/README.md +118 -0
  89. package/node_modules/@attocash/commons-core/commons-commons-core.d.mts +1036 -0
  90. package/node_modules/@attocash/commons-core/commons-commons-core.mjs +7701 -0
  91. package/node_modules/@attocash/commons-core/commons-commons-core.mjs.map +1 -0
  92. package/node_modules/@attocash/commons-core/kotlin-kotlin-stdlib.mjs +17681 -0
  93. package/node_modules/@attocash/commons-core/kotlin-kotlin-stdlib.mjs.map +1 -0
  94. package/node_modules/@attocash/commons-core/kotlin_org_jetbrains_kotlin_kotlin_dom_api_compat.mjs +4 -0
  95. package/node_modules/@attocash/commons-core/kotlin_org_jetbrains_kotlin_kotlin_dom_api_compat.mjs.map +1 -0
  96. package/node_modules/@attocash/commons-core/kotlinx-io-kotlinx-io-bytestring.mjs +209 -0
  97. package/node_modules/@attocash/commons-core/kotlinx-io-kotlinx-io-bytestring.mjs.map +1 -0
  98. package/node_modules/@attocash/commons-core/kotlinx-io-kotlinx-io-core.mjs +2284 -0
  99. package/node_modules/@attocash/commons-core/kotlinx-io-kotlinx-io-core.mjs.map +1 -0
  100. package/node_modules/@attocash/commons-core/kotlinx-serialization-kotlinx-serialization-core.mjs +6042 -0
  101. package/node_modules/@attocash/commons-core/kotlinx-serialization-kotlinx-serialization-core.mjs.map +1 -0
  102. package/node_modules/@attocash/commons-core/kotlinx-serialization-kotlinx-serialization-json.mjs +5294 -0
  103. package/node_modules/@attocash/commons-core/kotlinx-serialization-kotlinx-serialization-json.mjs.map +1 -0
  104. package/node_modules/@attocash/commons-core/package.json +27 -0
  105. package/node_modules/@attocash/commons-node/LICENSE +28 -0
  106. package/node_modules/@attocash/commons-node/README.md +92 -0
  107. package/node_modules/@attocash/commons-node/commons-commons-node.d.mts +255 -0
  108. package/node_modules/@attocash/commons-node/commons-commons-node.mjs +2977 -0
  109. package/node_modules/@attocash/commons-node/commons-commons-node.mjs.map +1 -0
  110. package/node_modules/@attocash/commons-node/kotlin-logging.mjs +432 -0
  111. package/node_modules/@attocash/commons-node/kotlin-logging.mjs.map +1 -0
  112. package/node_modules/@attocash/commons-node/kotlinx-serialization-kotlinx-serialization-json.mjs +5294 -0
  113. package/node_modules/@attocash/commons-node/kotlinx-serialization-kotlinx-serialization-json.mjs.map +1 -0
  114. package/node_modules/@attocash/commons-node/package.json +29 -0
  115. package/node_modules/@attocash/commons-node-remote/LICENSE +28 -0
  116. package/node_modules/@attocash/commons-node-remote/README.md +61 -0
  117. package/node_modules/@attocash/commons-node-remote/commons-commons-node-remote.d.mts +122 -0
  118. package/node_modules/@attocash/commons-node-remote/commons-commons-node-remote.mjs +1810 -0
  119. package/node_modules/@attocash/commons-node-remote/commons-commons-node-remote.mjs.map +1 -0
  120. package/node_modules/@attocash/commons-node-remote/kotlin-logging.mjs +432 -0
  121. package/node_modules/@attocash/commons-node-remote/kotlin-logging.mjs.map +1 -0
  122. package/node_modules/@attocash/commons-node-remote/kotlinx-browser.mjs +8 -0
  123. package/node_modules/@attocash/commons-node-remote/kotlinx-browser.mjs.map +1 -0
  124. package/node_modules/@attocash/commons-node-remote/kotlinx-serialization-kotlinx-serialization-json-io.mjs +4 -0
  125. package/node_modules/@attocash/commons-node-remote/kotlinx-serialization-kotlinx-serialization-json-io.mjs.map +1 -0
  126. package/node_modules/@attocash/commons-node-remote/kotlinx-serialization-kotlinx-serialization-json.mjs +5294 -0
  127. package/node_modules/@attocash/commons-node-remote/kotlinx-serialization-kotlinx-serialization-json.mjs.map +1 -0
  128. package/node_modules/@attocash/commons-node-remote/package.json +31 -0
  129. package/node_modules/@attocash/commons-transport/LICENSE +28 -0
  130. package/node_modules/@attocash/commons-transport/README.md +5 -0
  131. package/node_modules/@attocash/commons-transport/commons-commons-transport.d.mts +64 -0
  132. package/node_modules/@attocash/commons-transport/commons-commons-transport.mjs +249 -0
  133. package/node_modules/@attocash/commons-transport/commons-commons-transport.mjs.map +1 -0
  134. package/node_modules/@attocash/commons-transport/kotlinx-atomicfu.mjs +263 -0
  135. package/node_modules/@attocash/commons-transport/kotlinx-atomicfu.mjs.map +1 -0
  136. package/node_modules/@attocash/commons-transport/kotlinx-browser.mjs +8 -0
  137. package/node_modules/@attocash/commons-transport/kotlinx-browser.mjs.map +1 -0
  138. package/node_modules/@attocash/commons-transport/kotlinx-coroutines-core.mjs +11604 -0
  139. package/node_modules/@attocash/commons-transport/kotlinx-coroutines-core.mjs.map +1 -0
  140. package/node_modules/@attocash/commons-transport/kotlinx-serialization-kotlinx-serialization-json-io.mjs +4 -0
  141. package/node_modules/@attocash/commons-transport/kotlinx-serialization-kotlinx-serialization-json-io.mjs.map +1 -0
  142. package/node_modules/@attocash/commons-transport/kotlinx-serialization-kotlinx-serialization-json.mjs +5294 -0
  143. package/node_modules/@attocash/commons-transport/kotlinx-serialization-kotlinx-serialization-json.mjs.map +1 -0
  144. package/node_modules/@attocash/commons-transport/ktor-ktor-client-content-negotiation.mjs +499 -0
  145. package/node_modules/@attocash/commons-transport/ktor-ktor-client-content-negotiation.mjs.map +1 -0
  146. package/node_modules/@attocash/commons-transport/ktor-ktor-client-core.mjs +6456 -0
  147. package/node_modules/@attocash/commons-transport/ktor-ktor-client-core.mjs.map +1 -0
  148. package/node_modules/@attocash/commons-transport/ktor-ktor-events.mjs +83 -0
  149. package/node_modules/@attocash/commons-transport/ktor-ktor-events.mjs.map +1 -0
  150. package/node_modules/@attocash/commons-transport/ktor-ktor-http-cio.mjs +1714 -0
  151. package/node_modules/@attocash/commons-transport/ktor-ktor-http-cio.mjs.map +1 -0
  152. package/node_modules/@attocash/commons-transport/ktor-ktor-http.mjs +3197 -0
  153. package/node_modules/@attocash/commons-transport/ktor-ktor-http.mjs.map +1 -0
  154. package/node_modules/@attocash/commons-transport/ktor-ktor-io.mjs +2290 -0
  155. package/node_modules/@attocash/commons-transport/ktor-ktor-io.mjs.map +1 -0
  156. package/node_modules/@attocash/commons-transport/ktor-ktor-serialization-kotlinx-json.mjs +46 -0
  157. package/node_modules/@attocash/commons-transport/ktor-ktor-serialization-kotlinx-json.mjs.map +1 -0
  158. package/node_modules/@attocash/commons-transport/ktor-ktor-serialization-kotlinx.mjs +482 -0
  159. package/node_modules/@attocash/commons-transport/ktor-ktor-serialization-kotlinx.mjs.map +1 -0
  160. package/node_modules/@attocash/commons-transport/ktor-ktor-serialization.mjs +165 -0
  161. package/node_modules/@attocash/commons-transport/ktor-ktor-serialization.mjs.map +1 -0
  162. package/node_modules/@attocash/commons-transport/ktor-ktor-sse.mjs +4 -0
  163. package/node_modules/@attocash/commons-transport/ktor-ktor-sse.mjs.map +1 -0
  164. package/node_modules/@attocash/commons-transport/ktor-ktor-utils.mjs +3222 -0
  165. package/node_modules/@attocash/commons-transport/ktor-ktor-utils.mjs.map +1 -0
  166. package/node_modules/@attocash/commons-transport/ktor-ktor-websocket-serialization.mjs +4 -0
  167. package/node_modules/@attocash/commons-transport/ktor-ktor-websocket-serialization.mjs.map +1 -0
  168. package/node_modules/@attocash/commons-transport/ktor-ktor-websockets.mjs +1485 -0
  169. package/node_modules/@attocash/commons-transport/ktor-ktor-websockets.mjs.map +1 -0
  170. package/node_modules/@attocash/commons-transport/package.json +29 -0
  171. package/node_modules/@attocash/commons-worker/LICENSE +28 -0
  172. package/node_modules/@attocash/commons-worker/README.md +48 -0
  173. package/node_modules/@attocash/commons-worker/commons-commons-worker.d.mts +73 -0
  174. package/node_modules/@attocash/commons-worker/commons-commons-worker.mjs +702 -0
  175. package/node_modules/@attocash/commons-worker/commons-commons-worker.mjs.map +1 -0
  176. package/node_modules/@attocash/commons-worker/kotlin-logging.mjs +432 -0
  177. package/node_modules/@attocash/commons-worker/kotlin-logging.mjs.map +1 -0
  178. package/node_modules/@attocash/commons-worker/kotlinx-serialization-kotlinx-serialization-json.mjs +5294 -0
  179. package/node_modules/@attocash/commons-worker/kotlinx-serialization-kotlinx-serialization-json.mjs.map +1 -0
  180. package/node_modules/@attocash/commons-worker/package.json +29 -0
  181. package/node_modules/@attocash/commons-worker-remote/LICENSE +28 -0
  182. package/node_modules/@attocash/commons-worker-remote/README.md +60 -0
  183. package/node_modules/@attocash/commons-worker-remote/commons-commons-worker-remote.d.mts +93 -0
  184. package/node_modules/@attocash/commons-worker-remote/commons-commons-worker-remote.mjs +289 -0
  185. package/node_modules/@attocash/commons-worker-remote/commons-commons-worker-remote.mjs.map +1 -0
  186. package/node_modules/@attocash/commons-worker-remote/kotlin-logging.mjs +432 -0
  187. package/node_modules/@attocash/commons-worker-remote/kotlin-logging.mjs.map +1 -0
  188. package/node_modules/@attocash/commons-worker-remote/kotlinx-browser.mjs +8 -0
  189. package/node_modules/@attocash/commons-worker-remote/kotlinx-browser.mjs.map +1 -0
  190. package/node_modules/@attocash/commons-worker-remote/kotlinx-serialization-kotlinx-serialization-json-io.mjs +4 -0
  191. package/node_modules/@attocash/commons-worker-remote/kotlinx-serialization-kotlinx-serialization-json-io.mjs.map +1 -0
  192. package/node_modules/@attocash/commons-worker-remote/kotlinx-serialization-kotlinx-serialization-json.mjs +5294 -0
  193. package/node_modules/@attocash/commons-worker-remote/kotlinx-serialization-kotlinx-serialization-json.mjs.map +1 -0
  194. package/node_modules/@attocash/commons-worker-remote/package.json +31 -0
  195. package/node_modules/@js-joda/core/CHANGELOG.md +363 -0
  196. package/node_modules/@js-joda/core/CheatSheet.md +947 -0
  197. package/node_modules/@js-joda/core/LICENSE +34 -0
  198. package/node_modules/@js-joda/core/README.md +155 -0
  199. package/node_modules/@js-joda/core/bower.json +21 -0
  200. package/node_modules/@js-joda/core/dist/js-joda.d.ts +2452 -0
  201. package/node_modules/@js-joda/core/dist/js-joda.esm.js +13564 -0
  202. package/node_modules/@js-joda/core/dist/js-joda.flow.js +949 -0
  203. package/node_modules/@js-joda/core/dist/js-joda.js +13630 -0
  204. package/node_modules/@js-joda/core/dist/js-joda.js.map +1 -0
  205. package/node_modules/@js-joda/core/dist/js-joda.min.js +5 -0
  206. package/node_modules/@js-joda/core/package.json +76 -0
  207. package/node_modules/@js-joda/core/src/Clock.js +330 -0
  208. package/node_modules/@js-joda/core/src/DayOfWeek.js +451 -0
  209. package/node_modules/@js-joda/core/src/Duration.js +1205 -0
  210. package/node_modules/@js-joda/core/src/Enum.js +30 -0
  211. package/node_modules/@js-joda/core/src/Instant.js +1012 -0
  212. package/node_modules/@js-joda/core/src/LocalDate.js +1703 -0
  213. package/node_modules/@js-joda/core/src/LocalDateTime.js +1686 -0
  214. package/node_modules/@js-joda/core/src/LocalTime.js +1415 -0
  215. package/node_modules/@js-joda/core/src/MathUtil.js +236 -0
  216. package/node_modules/@js-joda/core/src/Month.js +600 -0
  217. package/node_modules/@js-joda/core/src/MonthDay.js +730 -0
  218. package/node_modules/@js-joda/core/src/OffsetDateTime.js +757 -0
  219. package/node_modules/@js-joda/core/src/OffsetTime.js +621 -0
  220. package/node_modules/@js-joda/core/src/Period.js +933 -0
  221. package/node_modules/@js-joda/core/src/StringUtil.js +43 -0
  222. package/node_modules/@js-joda/core/src/Year.js +1015 -0
  223. package/node_modules/@js-joda/core/src/YearConstants.js +21 -0
  224. package/node_modules/@js-joda/core/src/YearMonth.js +1096 -0
  225. package/node_modules/@js-joda/core/src/ZoneId.js +236 -0
  226. package/node_modules/@js-joda/core/src/ZoneIdFactory.js +201 -0
  227. package/node_modules/@js-joda/core/src/ZoneOffset.js +486 -0
  228. package/node_modules/@js-joda/core/src/ZoneRegion.js +72 -0
  229. package/node_modules/@js-joda/core/src/ZonedDateTime.js +2007 -0
  230. package/node_modules/@js-joda/core/src/_init.js +68 -0
  231. package/node_modules/@js-joda/core/src/assert.js +33 -0
  232. package/node_modules/@js-joda/core/src/chrono/ChronoLocalDate.js +230 -0
  233. package/node_modules/@js-joda/core/src/chrono/ChronoLocalDateTime.js +130 -0
  234. package/node_modules/@js-joda/core/src/chrono/ChronoZonedDateTime.js +194 -0
  235. package/node_modules/@js-joda/core/src/chrono/IsoChronology.js +235 -0
  236. package/node_modules/@js-joda/core/src/convert.js +83 -0
  237. package/node_modules/@js-joda/core/src/errors.js +54 -0
  238. package/node_modules/@js-joda/core/src/format/DateTimeBuilder.js +535 -0
  239. package/node_modules/@js-joda/core/src/format/DateTimeFormatter.js +728 -0
  240. package/node_modules/@js-joda/core/src/format/DateTimeFormatterBuilder.js +1545 -0
  241. package/node_modules/@js-joda/core/src/format/DateTimeParseContext.js +297 -0
  242. package/node_modules/@js-joda/core/src/format/DateTimePrintContext.js +138 -0
  243. package/node_modules/@js-joda/core/src/format/DecimalStyle.js +113 -0
  244. package/node_modules/@js-joda/core/src/format/EnumMap.js +70 -0
  245. package/node_modules/@js-joda/core/src/format/ParsePosition.js +31 -0
  246. package/node_modules/@js-joda/core/src/format/ResolverStyle.js +93 -0
  247. package/node_modules/@js-joda/core/src/format/SignStyle.js +38 -0
  248. package/node_modules/@js-joda/core/src/format/StringBuilder.js +47 -0
  249. package/node_modules/@js-joda/core/src/format/TextStyle.js +114 -0
  250. package/node_modules/@js-joda/core/src/format/parser/CharLiteralPrinterParser.js +46 -0
  251. package/node_modules/@js-joda/core/src/format/parser/CompositePrinterParser.js +89 -0
  252. package/node_modules/@js-joda/core/src/format/parser/FractionPrinterParser.js +162 -0
  253. package/node_modules/@js-joda/core/src/format/parser/NumberPrinterParser.js +367 -0
  254. package/node_modules/@js-joda/core/src/format/parser/OffsetIdPrinterParser.js +177 -0
  255. package/node_modules/@js-joda/core/src/format/parser/PadPrinterParserDecorator.js +81 -0
  256. package/node_modules/@js-joda/core/src/format/parser/SettingsParser.js +44 -0
  257. package/node_modules/@js-joda/core/src/format/parser/StringLiteralPrinterParser.js +39 -0
  258. package/node_modules/@js-joda/core/src/format/parser/ZoneIdPrinterParser.js +218 -0
  259. package/node_modules/@js-joda/core/src/js-joda.js +210 -0
  260. package/node_modules/@js-joda/core/src/license-preamble.js +3 -0
  261. package/node_modules/@js-joda/core/src/temporal/ChronoField.js +470 -0
  262. package/node_modules/@js-joda/core/src/temporal/ChronoUnit.js +310 -0
  263. package/node_modules/@js-joda/core/src/temporal/DefaultInterfaceTemporal.js +118 -0
  264. package/node_modules/@js-joda/core/src/temporal/IsoFields.js +859 -0
  265. package/node_modules/@js-joda/core/src/temporal/NativeJsTemporal.js +105 -0
  266. package/node_modules/@js-joda/core/src/temporal/Temporal.js +346 -0
  267. package/node_modules/@js-joda/core/src/temporal/TemporalAccessor.js +125 -0
  268. package/node_modules/@js-joda/core/src/temporal/TemporalAdjuster.js +92 -0
  269. package/node_modules/@js-joda/core/src/temporal/TemporalAdjusters.js +464 -0
  270. package/node_modules/@js-joda/core/src/temporal/TemporalAmount.js +166 -0
  271. package/node_modules/@js-joda/core/src/temporal/TemporalField.js +248 -0
  272. package/node_modules/@js-joda/core/src/temporal/TemporalQueries.js +223 -0
  273. package/node_modules/@js-joda/core/src/temporal/TemporalQueriesFactory.js +77 -0
  274. package/node_modules/@js-joda/core/src/temporal/TemporalQuery.js +107 -0
  275. package/node_modules/@js-joda/core/src/temporal/TemporalUnit.js +179 -0
  276. package/node_modules/@js-joda/core/src/temporal/ValueRange.js +257 -0
  277. package/node_modules/@js-joda/core/src/use.js +20 -0
  278. package/node_modules/@js-joda/core/src/zone/SystemDefaultZoneId.js +31 -0
  279. package/node_modules/@js-joda/core/src/zone/SystemDefaultZoneRules.js +162 -0
  280. package/node_modules/@js-joda/core/src/zone/ZoneOffsetTransition.js +289 -0
  281. package/node_modules/@js-joda/core/src/zone/ZoneRules.js +464 -0
  282. package/node_modules/@js-joda/core/src/zone/ZoneRulesProvider.js +36 -0
  283. package/node_modules/@noble/hashes/LICENSE +21 -0
  284. package/node_modules/@noble/hashes/README.md +563 -0
  285. package/node_modules/@noble/hashes/_blake.d.ts +21 -0
  286. package/node_modules/@noble/hashes/_blake.d.ts.map +1 -0
  287. package/node_modules/@noble/hashes/_blake.js +52 -0
  288. package/node_modules/@noble/hashes/_blake.js.map +1 -0
  289. package/node_modules/@noble/hashes/_md.d.ts +99 -0
  290. package/node_modules/@noble/hashes/_md.d.ts.map +1 -0
  291. package/node_modules/@noble/hashes/_md.js +202 -0
  292. package/node_modules/@noble/hashes/_md.js.map +1 -0
  293. package/node_modules/@noble/hashes/_u64.d.ts +63 -0
  294. package/node_modules/@noble/hashes/_u64.d.ts.map +1 -0
  295. package/node_modules/@noble/hashes/_u64.js +84 -0
  296. package/node_modules/@noble/hashes/_u64.js.map +1 -0
  297. package/node_modules/@noble/hashes/argon2.d.ts +112 -0
  298. package/node_modules/@noble/hashes/argon2.d.ts.map +1 -0
  299. package/node_modules/@noble/hashes/argon2.js +517 -0
  300. package/node_modules/@noble/hashes/argon2.js.map +1 -0
  301. package/node_modules/@noble/hashes/blake1.d.ts +156 -0
  302. package/node_modules/@noble/hashes/blake1.d.ts.map +1 -0
  303. package/node_modules/@noble/hashes/blake1.js +560 -0
  304. package/node_modules/@noble/hashes/blake1.js.map +1 -0
  305. package/node_modules/@noble/hashes/blake2.d.ts +184 -0
  306. package/node_modules/@noble/hashes/blake2.d.ts.map +1 -0
  307. package/node_modules/@noble/hashes/blake2.js +501 -0
  308. package/node_modules/@noble/hashes/blake2.js.map +1 -0
  309. package/node_modules/@noble/hashes/blake3.d.ts +68 -0
  310. package/node_modules/@noble/hashes/blake3.d.ts.map +1 -0
  311. package/node_modules/@noble/hashes/blake3.js +284 -0
  312. package/node_modules/@noble/hashes/blake3.js.map +1 -0
  313. package/node_modules/@noble/hashes/eskdf.d.ts +92 -0
  314. package/node_modules/@noble/hashes/eskdf.d.ts.map +1 -0
  315. package/node_modules/@noble/hashes/eskdf.js +218 -0
  316. package/node_modules/@noble/hashes/eskdf.js.map +1 -0
  317. package/node_modules/@noble/hashes/hkdf.d.ts +64 -0
  318. package/node_modules/@noble/hashes/hkdf.d.ts.map +1 -0
  319. package/node_modules/@noble/hashes/hkdf.js +120 -0
  320. package/node_modules/@noble/hashes/hkdf.js.map +1 -0
  321. package/node_modules/@noble/hashes/hmac.d.ts +47 -0
  322. package/node_modules/@noble/hashes/hmac.d.ts.map +1 -0
  323. package/node_modules/@noble/hashes/hmac.js +93 -0
  324. package/node_modules/@noble/hashes/hmac.js.map +1 -0
  325. package/node_modules/@noble/hashes/index.d.ts +2 -0
  326. package/node_modules/@noble/hashes/index.d.ts.map +1 -0
  327. package/node_modules/@noble/hashes/index.js +35 -0
  328. package/node_modules/@noble/hashes/index.js.map +1 -0
  329. package/node_modules/@noble/hashes/legacy.d.ts +102 -0
  330. package/node_modules/@noble/hashes/legacy.d.ts.map +1 -0
  331. package/node_modules/@noble/hashes/legacy.js +327 -0
  332. package/node_modules/@noble/hashes/legacy.js.map +1 -0
  333. package/node_modules/@noble/hashes/package.json +97 -0
  334. package/node_modules/@noble/hashes/pbkdf2.d.ts +56 -0
  335. package/node_modules/@noble/hashes/pbkdf2.d.ts.map +1 -0
  336. package/node_modules/@noble/hashes/pbkdf2.js +135 -0
  337. package/node_modules/@noble/hashes/pbkdf2.js.map +1 -0
  338. package/node_modules/@noble/hashes/scrypt.d.ts +65 -0
  339. package/node_modules/@noble/hashes/scrypt.d.ts.map +1 -0
  340. package/node_modules/@noble/hashes/scrypt.js +257 -0
  341. package/node_modules/@noble/hashes/scrypt.js.map +1 -0
  342. package/node_modules/@noble/hashes/sha2.d.ts +249 -0
  343. package/node_modules/@noble/hashes/sha2.d.ts.map +1 -0
  344. package/node_modules/@noble/hashes/sha2.js +458 -0
  345. package/node_modules/@noble/hashes/sha2.js.map +1 -0
  346. package/node_modules/@noble/hashes/sha3-addons.d.ts +461 -0
  347. package/node_modules/@noble/hashes/sha3-addons.d.ts.map +1 -0
  348. package/node_modules/@noble/hashes/sha3-addons.js +783 -0
  349. package/node_modules/@noble/hashes/sha3-addons.js.map +1 -0
  350. package/node_modules/@noble/hashes/sha3.d.ts +199 -0
  351. package/node_modules/@noble/hashes/sha3.d.ts.map +1 -0
  352. package/node_modules/@noble/hashes/sha3.js +431 -0
  353. package/node_modules/@noble/hashes/sha3.js.map +1 -0
  354. package/node_modules/@noble/hashes/src/_blake.ts +57 -0
  355. package/node_modules/@noble/hashes/src/_md.ts +222 -0
  356. package/node_modules/@noble/hashes/src/_u64.ts +117 -0
  357. package/node_modules/@noble/hashes/src/argon2.ts +667 -0
  358. package/node_modules/@noble/hashes/src/blake1.ts +614 -0
  359. package/node_modules/@noble/hashes/src/blake2.ts +582 -0
  360. package/node_modules/@noble/hashes/src/blake3.ts +317 -0
  361. package/node_modules/@noble/hashes/src/eskdf.ts +259 -0
  362. package/node_modules/@noble/hashes/src/hkdf.ts +133 -0
  363. package/node_modules/@noble/hashes/src/hmac.ts +126 -0
  364. package/node_modules/@noble/hashes/src/index.ts +33 -0
  365. package/node_modules/@noble/hashes/src/legacy.ts +339 -0
  366. package/node_modules/@noble/hashes/src/pbkdf2.ts +175 -0
  367. package/node_modules/@noble/hashes/src/scrypt.ts +315 -0
  368. package/node_modules/@noble/hashes/src/sha2.ts +530 -0
  369. package/node_modules/@noble/hashes/src/sha3-addons.ts +983 -0
  370. package/node_modules/@noble/hashes/src/sha3.ts +485 -0
  371. package/node_modules/@noble/hashes/src/utils.ts +848 -0
  372. package/node_modules/@noble/hashes/src/webcrypto.ts +239 -0
  373. package/node_modules/@noble/hashes/utils.d.ts +519 -0
  374. package/node_modules/@noble/hashes/utils.d.ts.map +1 -0
  375. package/node_modules/@noble/hashes/utils.js +578 -0
  376. package/node_modules/@noble/hashes/utils.js.map +1 -0
  377. package/node_modules/@noble/hashes/webcrypto.d.ts +120 -0
  378. package/node_modules/@noble/hashes/webcrypto.d.ts.map +1 -0
  379. package/node_modules/@noble/hashes/webcrypto.js +165 -0
  380. package/node_modules/@noble/hashes/webcrypto.js.map +1 -0
  381. package/node_modules/ws/LICENSE +20 -0
  382. package/node_modules/ws/README.md +548 -0
  383. package/node_modules/ws/browser.js +8 -0
  384. package/node_modules/ws/index.js +22 -0
  385. package/node_modules/ws/lib/buffer-util.js +131 -0
  386. package/node_modules/ws/lib/constants.js +19 -0
  387. package/node_modules/ws/lib/event-target.js +292 -0
  388. package/node_modules/ws/lib/extension.js +203 -0
  389. package/node_modules/ws/lib/limiter.js +55 -0
  390. package/node_modules/ws/lib/permessage-deflate.js +530 -0
  391. package/node_modules/ws/lib/receiver.js +743 -0
  392. package/node_modules/ws/lib/sender.js +607 -0
  393. package/node_modules/ws/lib/stream.js +161 -0
  394. package/node_modules/ws/lib/subprotocol.js +62 -0
  395. package/node_modules/ws/lib/validation.js +152 -0
  396. package/node_modules/ws/lib/websocket-server.js +562 -0
  397. package/node_modules/ws/lib/websocket.js +1407 -0
  398. package/node_modules/ws/package.json +74 -0
  399. package/node_modules/ws/wrapper.mjs +21 -0
  400. package/package.json +53 -0
@@ -0,0 +1,73 @@
1
+ import { accessSync, constants, existsSync, statSync } from 'node:fs';
2
+ import { dirname, join } from 'node:path';
3
+ import { DatabaseSync } from 'node:sqlite';
4
+ import { z } from 'zod';
5
+ import { parseOperation } from '../application/operations.js';
6
+ import { amountRaw } from '../domain/amount.js';
7
+ import { AttoError } from '../domain/errors.js';
8
+ import { parseAddress } from '../network/reader.js';
9
+ import { marketTerms } from '../pricing/terms.js';
10
+ import { defaultSettings } from '../wallet/defaults.js';
11
+ const identitySchema = z.strictObject({ address: z.string().max(128), fingerprint: z.string().regex(/^[a-f\d]{64}$/i) });
12
+ const addressesSchema = z.array(z.strictObject({ index: z.number().int().min(0).max(2147483647),
13
+ address: z.string().max(128), publicKey: z.string().regex(/^[a-f\d]{64}$/i), active: z.boolean() }));
14
+ /** Read a consistent snapshot without StateStore's initialization, migration, or chmod. */
15
+ export function readDoctorProfile(directory) {
16
+ let parent = directory;
17
+ while (!existsSync(parent) && dirname(parent) !== parent)
18
+ parent = dirname(parent);
19
+ accessSync(parent, constants.R_OK | constants.W_OK | constants.X_OK);
20
+ const file = join(directory, 'state.sqlite');
21
+ const directoryInfo = existsSync(directory) ? statSync(directory) : undefined;
22
+ const databaseInfo = existsSync(file) ? statSync(file) : undefined;
23
+ const permissions = process.platform !== 'win32' && directoryInfo ? {
24
+ private: (directoryInfo.mode & 0o077) === 0 && (!databaseInfo || (databaseInfo.mode & 0o077) === 0),
25
+ directoryMode: (directoryInfo.mode & 0o777).toString(8),
26
+ ...(databaseInfo ? { databaseMode: (databaseInfo.mode & 0o777).toString(8) } : {}),
27
+ } : undefined;
28
+ if (!databaseInfo)
29
+ return { settings: defaultSettings(), settingsSource: 'defaults', addresses: [], access: 'read-only', poolIndexes: [0], pendingPayments: 0, resetPending: false, termsAccepted: false, permissions };
30
+ accessSync(file, constants.R_OK | constants.W_OK);
31
+ const state = new DatabaseSync(file, { readOnly: true });
32
+ try {
33
+ state.exec('PRAGMA busy_timeout = 1000; BEGIN;');
34
+ if (state.prepare('PRAGMA user_version').get()?.user_version !== 1)
35
+ throw new AttoError('STATE_VERSION', 'This wallet state requires a supported Atto CLI version.');
36
+ const get = (key) => {
37
+ const row = state.prepare('SELECT value FROM settings WHERE key = ?').get(key);
38
+ if (!row)
39
+ return undefined;
40
+ if (typeof row.value !== 'string' || row.value.length > 1_048_576)
41
+ throw new Error('Invalid state value');
42
+ return JSON.parse(row.value);
43
+ };
44
+ const settings = parseOperation('wallet_configure', get('settings'));
45
+ if (['network', 'nodeUrl', 'workerUrl', 'representative', 'autoReceive', 'minReceiveRaw'].some(key => !Object.hasOwn(settings, key)))
46
+ throw new Error('Incomplete settings');
47
+ parseAddress(settings.representative);
48
+ amountRaw(settings.minReceiveRaw, 'RAW');
49
+ const savedIdentity = get('identity');
50
+ const identity = savedIdentity === undefined ? undefined : identitySchema.parse(savedIdentity);
51
+ if (identity)
52
+ parseAddress(identity.address);
53
+ const addresses = addressesSchema.parse(get('addresses') ?? []);
54
+ if (new Set(addresses.map(address => address.index)).size !== addresses.length)
55
+ throw new Error('Duplicate account indexes');
56
+ for (const address of addresses) {
57
+ if (parseAddress(address.address).publicKey.toString().toUpperCase() !== address.publicKey.toUpperCase())
58
+ throw new Error('Account identity mismatch');
59
+ }
60
+ if (identity && addresses.find(address => address.index === 0)?.address !== identity.address)
61
+ throw new Error('Wallet identity mismatch');
62
+ const access = z.enum(['read-only', 'spend']).parse(get('spending.mcpAccess') ?? 'read-only');
63
+ const proposed = parseOperation('limits_propose', { policy: get('spending.policy') ?? { perRequest: null, rolling: [] }, access, pool: get('spending.pool') ?? { indexes: [0], consolidate: false } });
64
+ const pending = state.prepare("SELECT COUNT(*) AS count FROM settings, json_each(settings.value) WHERE settings.key = 'spending.records' AND json_extract(json_each.value, '$.status') IN ('reserved', 'signed', 'unknown')").get();
65
+ const terms = get('market.terms');
66
+ return { settings, settingsSource: 'profile', identity, addresses, access, permissions,
67
+ poolIndexes: proposed.pool.indexes, pendingPayments: Number(pending?.count ?? 0),
68
+ resetPending: Boolean(get('wallet.reset')), termsAccepted: terms?.version === marketTerms.version };
69
+ }
70
+ finally {
71
+ state.close();
72
+ }
73
+ }
@@ -0,0 +1,40 @@
1
+ export type DoctorStatus = 'pass' | 'warn' | 'fail' | 'skipped';
2
+ export interface DoctorCheck {
3
+ id: string;
4
+ status: DoctorStatus;
5
+ code: string;
6
+ message: string;
7
+ evidence?: Record<string, unknown>;
8
+ remediation?: {
9
+ steps: string[];
10
+ command?: string[];
11
+ suggestedEnv?: Record<string, string>;
12
+ restartRequired?: boolean;
13
+ };
14
+ }
15
+ export interface DoctorOptions {
16
+ directory?: string;
17
+ access?: 'mcp';
18
+ signal?: AbortSignal;
19
+ globalDirectory?: boolean;
20
+ }
21
+ export interface DoctorReport {
22
+ status: 'pass' | 'warn' | 'fail';
23
+ context: {
24
+ interface: 'cli' | 'mcp';
25
+ executable: string;
26
+ nodeVersion: string;
27
+ cliVersion: string;
28
+ mcpVersion?: string;
29
+ platform: string;
30
+ directory?: string;
31
+ credentialService?: string;
32
+ credentialAccount?: string;
33
+ network?: string;
34
+ nodeUrl?: string;
35
+ workerUrl?: string;
36
+ settingsSource?: 'profile' | 'defaults';
37
+ };
38
+ checks: DoctorCheck[];
39
+ durationMs: number;
40
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ import type { AmountUnit } from '../wallet/types.js';
2
+ export declare function amountRaw(value: string, unit?: AmountUnit, allowZero?: boolean): string;
3
+ export declare function amountOutput(raw: string): {
4
+ raw: string;
5
+ atto: string;
6
+ };
@@ -0,0 +1,27 @@
1
+ import { AttoAmount, AttoUnit } from '@attocash/commons-core';
2
+ import { AttoError } from './errors.js';
3
+ export function amountRaw(value, unit = 'ATTO', allowZero = false) {
4
+ if (typeof value !== 'string' || !/^\d+(?:\.\d+)?$/.test(value) || !['ATTO', 'RAW'].includes(unit)) {
5
+ throw new AttoError('INVALID_AMOUNT', 'Use a nonnegative decimal string with an ATTO or RAW unit.');
6
+ }
7
+ const fraction = (value.split('.')[1] ?? '').replace(/0+$/, '');
8
+ if (fraction.length > (unit === 'ATTO' ? 9 : 0)) {
9
+ throw new AttoError('INVALID_AMOUNT', 'ATTO supports nine decimal places; RAW must be a whole number.');
10
+ }
11
+ try {
12
+ const normalized = `${value.split('.')[0]}${fraction ? `.${fraction}` : ''}`;
13
+ const amount = AttoAmount.from(unit === 'RAW' ? AttoUnit.RAW : AttoUnit.ATTO, normalized);
14
+ const raw = amount.toString();
15
+ if (!allowZero && BigInt(raw) === 0n)
16
+ throw new Error();
17
+ return raw;
18
+ }
19
+ catch {
20
+ throw new AttoError('INVALID_AMOUNT', 'Amount is outside the Atto range or precision.');
21
+ }
22
+ }
23
+ export function amountOutput(raw) {
24
+ const value = BigInt(raw);
25
+ const fraction = (value % 1000000000n).toString().padStart(9, '0').replace(/0+$/, '');
26
+ return { raw, atto: `${value / 1000000000n}${fraction ? `.${fraction}` : ''}` };
27
+ }
@@ -0,0 +1,10 @@
1
+ export declare class AttoError extends Error {
2
+ readonly code: string;
3
+ readonly details?: unknown | undefined;
4
+ constructor(code: string, message: string, details?: unknown | undefined);
5
+ }
6
+ export declare function errorResult(error: unknown): {
7
+ code: string;
8
+ message: string;
9
+ details?: unknown;
10
+ };
@@ -0,0 +1,16 @@
1
+ export class AttoError extends Error {
2
+ code;
3
+ details;
4
+ constructor(code, message, details) {
5
+ super(message);
6
+ this.code = code;
7
+ this.details = details;
8
+ this.name = 'AttoError';
9
+ }
10
+ }
11
+ export function errorResult(error) {
12
+ if (error instanceof AttoError)
13
+ return { code: error.code, message: error.message, details: error.details };
14
+ // Dependency errors can include request headers or key material. Never return their raw messages.
15
+ return { code: 'OPERATION_FAILED', message: 'The operation failed. Check wallet status and endpoint availability.' };
16
+ }
@@ -0,0 +1,87 @@
1
+ import { z } from 'zod';
2
+ export declare const DIRECTORY_URL = "https://gatekeeper.live.application.atto.cash/projections/addresses";
3
+ export declare const directorySchema: z.ZodObject<{
4
+ entities: z.ZodArray<z.ZodObject<{
5
+ entity: z.ZodString;
6
+ organization: z.ZodString;
7
+ label: z.ZodString;
8
+ website: z.ZodString;
9
+ tags: z.ZodArray<z.ZodString>;
10
+ addedAt: z.ZodString;
11
+ description: z.ZodString;
12
+ }, z.core.$strip>>;
13
+ addresses: z.ZodArray<z.ZodObject<{
14
+ address: z.ZodString;
15
+ label: z.ZodString;
16
+ entity: z.ZodString;
17
+ addedAt: z.ZodString;
18
+ description: z.ZodString;
19
+ }, z.core.$strip>>;
20
+ voters: z.ZodArray<z.ZodObject<{
21
+ address: z.ZodString;
22
+ label: z.ZodString;
23
+ entity: z.ZodString;
24
+ addedAt: z.ZodString;
25
+ description: z.ZodString;
26
+ payToAddress: z.ZodNullable<z.ZodString>;
27
+ sharePercentage: z.ZodNumber;
28
+ voteWeight: z.ZodString;
29
+ lastVotedAt: z.ZodString;
30
+ }, z.core.$strip>>;
31
+ }, z.core.$strip>;
32
+ export type DirectorySnapshot = z.infer<typeof directorySchema>;
33
+ /** Fetches only the public URL, with no wallet addresses or personal labels. */
34
+ export declare function fetchDirectory(fetcher?: typeof fetch, signal?: AbortSignal): Promise<DirectorySnapshot>;
35
+ /** Disposable public cache, kept outside the profile's durable SQLite state. */
36
+ export declare class GlobalDirectory {
37
+ private readonly directory;
38
+ private readonly fetcher;
39
+ private readonly now;
40
+ private pending?;
41
+ private memory;
42
+ private readonly path;
43
+ constructor(directory: string, fetcher?: typeof fetch, now?: () => number);
44
+ private read;
45
+ private save;
46
+ cached(): {
47
+ snapshot: {
48
+ entities: {
49
+ entity: string;
50
+ organization: string;
51
+ label: string;
52
+ website: string;
53
+ tags: string[];
54
+ addedAt: string;
55
+ description: string;
56
+ }[];
57
+ addresses: {
58
+ address: string;
59
+ label: string;
60
+ entity: string;
61
+ addedAt: string;
62
+ description: string;
63
+ }[];
64
+ voters: {
65
+ address: string;
66
+ label: string;
67
+ entity: string;
68
+ addedAt: string;
69
+ description: string;
70
+ payToAddress: string | null;
71
+ sharePercentage: number;
72
+ voteWeight: string;
73
+ lastVotedAt: string;
74
+ }[];
75
+ } | undefined;
76
+ status: {
77
+ lastError?: string | undefined;
78
+ retryAt?: string | undefined;
79
+ fetchedAt?: string | undefined;
80
+ source: string;
81
+ network: string;
82
+ available: boolean;
83
+ stale: boolean;
84
+ };
85
+ };
86
+ refresh(force?: boolean): Promise<void>;
87
+ }
@@ -0,0 +1,140 @@
1
+ import { mkdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { randomUUID } from 'node:crypto';
4
+ import { z } from 'zod';
5
+ import { parseAddress } from '../network/reader.js';
6
+ export const DIRECTORY_URL = 'https://gatekeeper.live.application.atto.cash/projections/addresses';
7
+ const FRESH_MS = 3_600_000;
8
+ const RETRY_MS = 300_000;
9
+ const MAX_BYTES = 2 * 1024 * 1024;
10
+ const string = z.string().max(4096);
11
+ const address = z.string().max(128).refine(value => { try {
12
+ return parseAddress(value).value === value;
13
+ }
14
+ catch {
15
+ return false;
16
+ } });
17
+ const entity = z.object({ entity: string, organization: string, label: string, website: string, tags: z.array(string).max(100), addedAt: string, description: string });
18
+ const entry = z.object({ address, label: string, entity: string, addedAt: string, description: string });
19
+ const voter = entry.extend({ payToAddress: address.nullable(), sharePercentage: z.number().min(0).max(100), voteWeight: z.string().regex(/^\d+$/).max(40), lastVotedAt: string });
20
+ export const directorySchema = z.object({ entities: z.array(entity).max(10_000), addresses: z.array(entry).max(10_000), voters: z.array(voter).max(10_000) })
21
+ .superRefine((snapshot, context) => {
22
+ const entities = new Set(snapshot.entities.map(value => value.entity));
23
+ if (entities.size !== snapshot.entities.length || [...snapshot.addresses, ...snapshot.voters].some(value => !entities.has(value.entity))) {
24
+ context.addIssue({ code: 'custom', message: 'Invalid directory entity references.' });
25
+ }
26
+ });
27
+ /** Fetches only the public URL, with no wallet addresses or personal labels. */
28
+ export async function fetchDirectory(fetcher = fetch, signal) {
29
+ const response = await fetcher(DIRECTORY_URL, { signal: AbortSignal.any([AbortSignal.timeout(3000), ...(signal ? [signal] : [])]), redirect: 'error', headers: { accept: 'application/json' } });
30
+ try {
31
+ if (!response.ok || !response.body || !/^application\/json\b/i.test(response.headers.get('content-type') ?? '')
32
+ || Number(response.headers.get('content-length') ?? 0) > MAX_BYTES)
33
+ throw new Error('Invalid directory response.');
34
+ const reader = response.body.getReader();
35
+ const chunks = [];
36
+ let size = 0;
37
+ try {
38
+ for (;;) {
39
+ const { done, value } = await reader.read();
40
+ if (done)
41
+ break;
42
+ size += value.length;
43
+ if (size > MAX_BYTES)
44
+ throw new Error('Directory response too large.');
45
+ chunks.push(value);
46
+ }
47
+ }
48
+ finally {
49
+ await reader.cancel();
50
+ reader.releaseLock();
51
+ }
52
+ return directorySchema.parse(JSON.parse(Buffer.concat(chunks).toString('utf8')));
53
+ }
54
+ finally {
55
+ if (!response.body?.locked)
56
+ await response.body?.cancel();
57
+ }
58
+ }
59
+ /** Disposable public cache, kept outside the profile's durable SQLite state. */
60
+ export class GlobalDirectory {
61
+ directory;
62
+ fetcher;
63
+ now;
64
+ pending;
65
+ memory = {};
66
+ path;
67
+ constructor(directory, fetcher = fetch, now = Date.now) {
68
+ this.directory = directory;
69
+ this.fetcher = fetcher;
70
+ this.now = now;
71
+ this.path = join(directory, 'cache', 'global-addresses.json');
72
+ }
73
+ read() {
74
+ try {
75
+ if (statSync(this.path).size > MAX_BYTES + 1024)
76
+ throw new Error();
77
+ const bytes = readFileSync(this.path);
78
+ if (bytes.length > MAX_BYTES + 1024)
79
+ throw new Error();
80
+ const cache = JSON.parse(bytes.toString('utf8'));
81
+ for (const time of [cache.fetchedAt, cache.failedAt])
82
+ if (time !== undefined && (!Number.isSafeInteger(time) || time < 0 || time > 8_640_000_000_000_000 - RETRY_MS))
83
+ throw new Error();
84
+ if (cache.snapshot) {
85
+ cache.snapshot = directorySchema.parse(cache.snapshot);
86
+ if (cache.fetchedAt === undefined)
87
+ throw new Error();
88
+ }
89
+ return this.memory = cache;
90
+ }
91
+ catch {
92
+ return this.memory;
93
+ }
94
+ }
95
+ save(cache) {
96
+ this.memory = cache;
97
+ const temporary = `${this.path}.${randomUUID()}.tmp`;
98
+ try {
99
+ mkdirSync(join(this.directory, 'cache'), { recursive: true, mode: 0o700 });
100
+ writeFileSync(temporary, JSON.stringify(cache), { mode: 0o600 });
101
+ renameSync(temporary, this.path);
102
+ }
103
+ catch { /* Public-cache storage failures must not break wallet operations. */ }
104
+ finally {
105
+ try {
106
+ rmSync(temporary, { force: true });
107
+ }
108
+ catch { /* Best effort. */ }
109
+ }
110
+ }
111
+ cached() {
112
+ const cache = this.read();
113
+ return { snapshot: cache.snapshot, status: { source: DIRECTORY_URL, network: 'LIVE',
114
+ available: Boolean(cache.snapshot), stale: !cache.snapshot || this.now() - cache.fetchedAt >= FRESH_MS,
115
+ ...(cache.fetchedAt !== undefined ? { fetchedAt: new Date(cache.fetchedAt).toISOString() } : {}),
116
+ ...(cache.failedAt !== undefined ? { lastError: 'DIRECTORY_UNAVAILABLE', retryAt: new Date(cache.failedAt + RETRY_MS).toISOString() } : {}) } };
117
+ }
118
+ async refresh(force = false) {
119
+ if (this.pending)
120
+ return this.pending;
121
+ const cache = this.read();
122
+ if (!force && ((cache.fetchedAt !== undefined && this.now() - cache.fetchedAt < FRESH_MS)
123
+ || (cache.failedAt !== undefined && this.now() - cache.failedAt < RETRY_MS)))
124
+ return;
125
+ this.pending = (async () => {
126
+ try {
127
+ this.save({ snapshot: await fetchDirectory(this.fetcher), fetchedAt: this.now() });
128
+ }
129
+ catch {
130
+ this.save({ ...cache, failedAt: this.now() });
131
+ }
132
+ })();
133
+ try {
134
+ await this.pending;
135
+ }
136
+ finally {
137
+ this.pending = undefined;
138
+ }
139
+ }
140
+ }
@@ -0,0 +1,17 @@
1
+ import { z } from 'zod';
2
+ import type { StateStore } from '../storage/state.js';
3
+ import type { NetworkName } from '../wallet/types.js';
4
+ export declare const personalNameSchema: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
5
+ export declare const nameKey: (name: string) => string;
6
+ export interface PersonalLabel {
7
+ address: string;
8
+ label: string;
9
+ }
10
+ export declare class PersonalLabels {
11
+ private readonly store;
12
+ constructor(store: StateStore);
13
+ list(network: NetworkName): PersonalLabel[];
14
+ set(network: NetworkName, address: string, input: string): PersonalLabel;
15
+ remove(network: NetworkName, address: string): void;
16
+ resolve(network: NetworkName, label: string): PersonalLabel;
17
+ }
@@ -0,0 +1,56 @@
1
+ import { z } from 'zod';
2
+ import { AttoError } from '../domain/errors.js';
3
+ import { parseAddress } from '../network/reader.js';
4
+ // Count Unicode code points, not UTF-16 units. Formatting controls are rejected
5
+ // too, so invisible direction changes cannot disguise a payment destination.
6
+ export const personalNameSchema = z.string().refine(value => !/[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/u.test(value), 'Labels cannot contain control characters.')
7
+ .transform(value => value.trim()).refine(value => [...value].length >= 1 && [...value].length <= 128, 'Labels must contain 1–128 characters after trimming.');
8
+ export const nameKey = (name) => name.trim().toLowerCase();
9
+ export class PersonalLabels {
10
+ store;
11
+ constructor(store) {
12
+ this.store = store;
13
+ }
14
+ list(network) {
15
+ const rows = this.store.get(`labels.personal.${network}`) ?? [];
16
+ try {
17
+ if (!Array.isArray(rows))
18
+ throw new Error();
19
+ const names = new Set();
20
+ const addresses = new Set();
21
+ for (const row of rows) {
22
+ if (parseAddress(row.address).value !== row.address || personalNameSchema.parse(row.label) !== row.label
23
+ || names.has(nameKey(row.label)) || addresses.has(row.address))
24
+ throw new Error();
25
+ names.add(nameKey(row.label));
26
+ addresses.add(row.address);
27
+ }
28
+ return rows;
29
+ }
30
+ catch {
31
+ throw new AttoError('INVALID_STATE', 'The saved personal labels are invalid. Restore verified profile state.');
32
+ }
33
+ }
34
+ set(network, address, input) {
35
+ const label = personalNameSchema.parse(input);
36
+ address = parseAddress(address).value;
37
+ return this.store.transaction(() => {
38
+ const rows = this.list(network);
39
+ if (rows.some(row => nameKey(row.label) === nameKey(label) && row.address !== address)) {
40
+ throw new AttoError('LABEL_EXISTS', 'This personal name already belongs to another address on this network.');
41
+ }
42
+ const row = { address, label };
43
+ this.store.set(`labels.personal.${network}`, [...rows.filter(row => row.address !== address), row]);
44
+ return row;
45
+ });
46
+ }
47
+ remove(network, address) {
48
+ this.store.transaction(() => this.store.set(`labels.personal.${network}`, this.list(network).filter(row => row.address !== address)));
49
+ }
50
+ resolve(network, label) {
51
+ const row = this.list(network).find(row => nameKey(row.label) === nameKey(label));
52
+ if (!row)
53
+ throw new AttoError('LABEL_NOT_FOUND', 'No personal label matches this name on this network. Global names cannot be used for payments.');
54
+ return row;
55
+ }
56
+ }
@@ -0,0 +1,154 @@
1
+ import type { NetworkName } from '../wallet/types.js';
2
+ import { GlobalDirectory } from './directory.js';
3
+ import { PersonalLabels } from './personal.js';
4
+ export declare function modelAddress(value: Record<string, unknown>, prefix?: string): string | undefined;
5
+ /** Read protocol keys without rewriting network objects or interpreting metadata. */
6
+ export declare function resultAddresses(value: unknown): string[];
7
+ export declare class AddressLabels {
8
+ private readonly personal;
9
+ readonly global: GlobalDirectory;
10
+ constructor(personal: PersonalLabels, global: GlobalDirectory);
11
+ dictionary(network: NetworkName, addresses: string[]): {
12
+ [k: string]: {
13
+ global: ({
14
+ source: string;
15
+ entityInfo: {
16
+ entity: string;
17
+ organization: string;
18
+ label: string;
19
+ website: string;
20
+ tags: string[];
21
+ addedAt: string;
22
+ description: string;
23
+ } | undefined;
24
+ stale: boolean;
25
+ kind: "address";
26
+ address: string;
27
+ label: string;
28
+ entity: string;
29
+ addedAt: string;
30
+ description: string;
31
+ } | {
32
+ source: string;
33
+ entityInfo: {
34
+ entity: string;
35
+ organization: string;
36
+ label: string;
37
+ website: string;
38
+ tags: string[];
39
+ addedAt: string;
40
+ description: string;
41
+ } | undefined;
42
+ stale: boolean;
43
+ kind: "voter";
44
+ address: string;
45
+ label: string;
46
+ entity: string;
47
+ addedAt: string;
48
+ description: string;
49
+ payToAddress: string | null;
50
+ sharePercentage: number;
51
+ voteWeight: string;
52
+ lastVotedAt: string;
53
+ })[];
54
+ payoutFor: {
55
+ voterAddress: string;
56
+ label: string;
57
+ entity: string;
58
+ source: string;
59
+ stale: boolean;
60
+ }[];
61
+ personal?: {
62
+ source: string;
63
+ label: string;
64
+ } | undefined;
65
+ };
66
+ };
67
+ status(network: NetworkName): {
68
+ lastError?: string | undefined;
69
+ retryAt?: string | undefined;
70
+ fetchedAt?: string | undefined;
71
+ source: string;
72
+ network: string;
73
+ available: boolean;
74
+ stale: boolean;
75
+ } | {
76
+ network: string;
77
+ applicable: boolean;
78
+ };
79
+ list(network: NetworkName, all?: boolean, search?: string): {
80
+ network: NetworkName;
81
+ items: {
82
+ address: string;
83
+ }[];
84
+ addressLabels: {
85
+ [k: string]: {
86
+ global: ({
87
+ source: string;
88
+ entityInfo: {
89
+ entity: string;
90
+ organization: string;
91
+ label: string;
92
+ website: string;
93
+ tags: string[];
94
+ addedAt: string;
95
+ description: string;
96
+ } | undefined;
97
+ stale: boolean;
98
+ kind: "address";
99
+ address: string;
100
+ label: string;
101
+ entity: string;
102
+ addedAt: string;
103
+ description: string;
104
+ } | {
105
+ source: string;
106
+ entityInfo: {
107
+ entity: string;
108
+ organization: string;
109
+ label: string;
110
+ website: string;
111
+ tags: string[];
112
+ addedAt: string;
113
+ description: string;
114
+ } | undefined;
115
+ stale: boolean;
116
+ kind: "voter";
117
+ address: string;
118
+ label: string;
119
+ entity: string;
120
+ addedAt: string;
121
+ description: string;
122
+ payToAddress: string | null;
123
+ sharePercentage: number;
124
+ voteWeight: string;
125
+ lastVotedAt: string;
126
+ })[];
127
+ payoutFor: {
128
+ voterAddress: string;
129
+ label: string;
130
+ entity: string;
131
+ source: string;
132
+ stale: boolean;
133
+ }[];
134
+ personal?: {
135
+ source: string;
136
+ label: string;
137
+ } | undefined;
138
+ } | undefined;
139
+ };
140
+ globalDirectory: {
141
+ lastError?: string | undefined;
142
+ retryAt?: string | undefined;
143
+ fetchedAt?: string | undefined;
144
+ source: string;
145
+ network: string;
146
+ available: boolean;
147
+ stale: boolean;
148
+ } | {
149
+ network: string;
150
+ applicable: boolean;
151
+ };
152
+ };
153
+ decorate(result: unknown, network: NetworkName): unknown;
154
+ }