arc402-cli 0.9.18 → 0.10.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 (358) hide show
  1. package/README.md +41 -2
  2. package/dist/abis.d.ts +1 -0
  3. package/dist/abis.d.ts.map +1 -1
  4. package/dist/abis.js +45 -14
  5. package/dist/abis.js.map +1 -1
  6. package/dist/bundler.d.ts +1 -1
  7. package/dist/bundler.d.ts.map +1 -1
  8. package/dist/bundler.js +61 -27
  9. package/dist/bundler.js.map +1 -1
  10. package/dist/client.d.ts +1 -1
  11. package/dist/client.d.ts.map +1 -1
  12. package/dist/client.js +9 -5
  13. package/dist/client.js.map +1 -1
  14. package/dist/coinbase-smart-wallet.js +4 -1
  15. package/dist/coinbase-smart-wallet.js.map +1 -1
  16. package/dist/commands/accept.js +28 -25
  17. package/dist/commands/accept.js.map +1 -1
  18. package/dist/commands/agent-handshake.js +18 -15
  19. package/dist/commands/agent-handshake.js.map +1 -1
  20. package/dist/commands/agent.js +104 -98
  21. package/dist/commands/agent.js.map +1 -1
  22. package/dist/commands/agreements.js +98 -62
  23. package/dist/commands/agreements.js.map +1 -1
  24. package/dist/commands/arbitrator.js +81 -45
  25. package/dist/commands/arbitrator.js.map +1 -1
  26. package/dist/commands/arena-handshake.d.ts.map +1 -1
  27. package/dist/commands/arena-handshake.js +35 -53
  28. package/dist/commands/arena-handshake.js.map +1 -1
  29. package/dist/commands/arena.js +18 -12
  30. package/dist/commands/arena.js.map +1 -1
  31. package/dist/commands/backup.js +36 -30
  32. package/dist/commands/backup.js.map +1 -1
  33. package/dist/commands/cancel.js +18 -15
  34. package/dist/commands/cancel.js.map +1 -1
  35. package/dist/commands/channel.js +81 -45
  36. package/dist/commands/channel.js.map +1 -1
  37. package/dist/commands/coldstart.js +34 -31
  38. package/dist/commands/coldstart.js.map +1 -1
  39. package/dist/commands/compute.d.ts +14 -0
  40. package/dist/commands/compute.d.ts.map +1 -0
  41. package/dist/commands/compute.js +466 -0
  42. package/dist/commands/compute.js.map +1 -0
  43. package/dist/commands/config.js +30 -24
  44. package/dist/commands/config.js.map +1 -1
  45. package/dist/commands/contract-interaction.js +15 -12
  46. package/dist/commands/contract-interaction.js.map +1 -1
  47. package/dist/commands/daemon.d.ts.map +1 -1
  48. package/dist/commands/daemon.js +135 -98
  49. package/dist/commands/daemon.js.map +1 -1
  50. package/dist/commands/deliver.js +76 -37
  51. package/dist/commands/deliver.js.map +1 -1
  52. package/dist/commands/discover.js +27 -24
  53. package/dist/commands/discover.js.map +1 -1
  54. package/dist/commands/dispute.js +110 -104
  55. package/dist/commands/dispute.js.map +1 -1
  56. package/dist/commands/doctor.js +55 -16
  57. package/dist/commands/doctor.js.map +1 -1
  58. package/dist/commands/endpoint.js +95 -56
  59. package/dist/commands/endpoint.js.map +1 -1
  60. package/dist/commands/feed.js +18 -11
  61. package/dist/commands/feed.js.map +1 -1
  62. package/dist/commands/hire.js +40 -37
  63. package/dist/commands/hire.js.map +1 -1
  64. package/dist/commands/migrate.js +33 -30
  65. package/dist/commands/migrate.js.map +1 -1
  66. package/dist/commands/negotiate.d.ts.map +1 -1
  67. package/dist/commands/negotiate.js +36 -34
  68. package/dist/commands/negotiate.js.map +1 -1
  69. package/dist/commands/openshell.js +104 -68
  70. package/dist/commands/openshell.js.map +1 -1
  71. package/dist/commands/owner.js +20 -17
  72. package/dist/commands/owner.js.map +1 -1
  73. package/dist/commands/policy.js +43 -41
  74. package/dist/commands/policy.js.map +1 -1
  75. package/dist/commands/relay.d.ts.map +1 -1
  76. package/dist/commands/relay.js +51 -18
  77. package/dist/commands/relay.js.map +1 -1
  78. package/dist/commands/remediate.js +23 -20
  79. package/dist/commands/remediate.js.map +1 -1
  80. package/dist/commands/reputation.js +27 -25
  81. package/dist/commands/reputation.js.map +1 -1
  82. package/dist/commands/setup.js +104 -65
  83. package/dist/commands/setup.js.map +1 -1
  84. package/dist/commands/trust.js +20 -17
  85. package/dist/commands/trust.js.map +1 -1
  86. package/dist/commands/verify.js +21 -18
  87. package/dist/commands/verify.js.map +1 -1
  88. package/dist/commands/wallet.d.ts.map +1 -1
  89. package/dist/commands/wallet.js +645 -679
  90. package/dist/commands/wallet.js.map +1 -1
  91. package/dist/commands/watch.js +36 -33
  92. package/dist/commands/watch.js.map +1 -1
  93. package/dist/commands/watchtower.js +73 -37
  94. package/dist/commands/watchtower.js.map +1 -1
  95. package/dist/commands/workroom.d.ts.map +1 -1
  96. package/dist/commands/workroom.js +282 -143
  97. package/dist/commands/workroom.js.map +1 -1
  98. package/dist/config.d.ts +3 -0
  99. package/dist/config.d.ts.map +1 -1
  100. package/dist/config.js +71 -22
  101. package/dist/config.js.map +1 -1
  102. package/dist/daemon/compute-metering.d.ts +61 -0
  103. package/dist/daemon/compute-metering.d.ts.map +1 -0
  104. package/dist/daemon/compute-metering.js +299 -0
  105. package/dist/daemon/compute-metering.js.map +1 -0
  106. package/dist/daemon/compute-session.d.ts +100 -0
  107. package/dist/daemon/compute-session.d.ts.map +1 -0
  108. package/dist/daemon/compute-session.js +231 -0
  109. package/dist/daemon/compute-session.js.map +1 -0
  110. package/dist/daemon/config.d.ts +19 -1
  111. package/dist/daemon/config.d.ts.map +1 -1
  112. package/dist/daemon/config.js +90 -16
  113. package/dist/daemon/config.js.map +1 -1
  114. package/dist/daemon/credentials.d.ts +24 -0
  115. package/dist/daemon/credentials.d.ts.map +1 -0
  116. package/dist/daemon/credentials.js +80 -0
  117. package/dist/daemon/credentials.js.map +1 -0
  118. package/dist/daemon/delivery-client.d.ts +35 -0
  119. package/dist/daemon/delivery-client.d.ts.map +1 -0
  120. package/dist/daemon/delivery-client.js +231 -0
  121. package/dist/daemon/delivery-client.js.map +1 -0
  122. package/dist/daemon/file-delivery.d.ts +98 -0
  123. package/dist/daemon/file-delivery.d.ts.map +1 -0
  124. package/dist/daemon/file-delivery.js +461 -0
  125. package/dist/daemon/file-delivery.js.map +1 -0
  126. package/dist/daemon/hire-listener.d.ts +3 -3
  127. package/dist/daemon/hire-listener.d.ts.map +1 -1
  128. package/dist/daemon/hire-listener.js +47 -13
  129. package/dist/daemon/hire-listener.js.map +1 -1
  130. package/dist/daemon/index.d.ts +2 -1
  131. package/dist/daemon/index.d.ts.map +1 -1
  132. package/dist/daemon/index.js +526 -53
  133. package/dist/daemon/index.js.map +1 -1
  134. package/dist/daemon/job-lifecycle.d.ts +1 -1
  135. package/dist/daemon/job-lifecycle.d.ts.map +1 -1
  136. package/dist/daemon/job-lifecycle.js +51 -11
  137. package/dist/daemon/job-lifecycle.js.map +1 -1
  138. package/dist/daemon/notify.d.ts +1 -1
  139. package/dist/daemon/notify.d.ts.map +1 -1
  140. package/dist/daemon/notify.js +53 -19
  141. package/dist/daemon/notify.js.map +1 -1
  142. package/dist/daemon/token-metering.js +47 -8
  143. package/dist/daemon/token-metering.js.map +1 -1
  144. package/dist/daemon/userops.d.ts +2 -2
  145. package/dist/daemon/userops.d.ts.map +1 -1
  146. package/dist/daemon/userops.js +27 -23
  147. package/dist/daemon/userops.js.map +1 -1
  148. package/dist/daemon/wallet-monitor.d.ts +1 -1
  149. package/dist/daemon/wallet-monitor.d.ts.map +1 -1
  150. package/dist/daemon/wallet-monitor.js +12 -8
  151. package/dist/daemon/wallet-monitor.js.map +1 -1
  152. package/dist/daemon/worker-executor.d.ts +71 -0
  153. package/dist/daemon/worker-executor.d.ts.map +1 -0
  154. package/dist/daemon/worker-executor.js +382 -0
  155. package/dist/daemon/worker-executor.js.map +1 -0
  156. package/dist/drain-v4.js +64 -26
  157. package/dist/drain-v4.js.map +1 -1
  158. package/dist/endpoint-config.js +63 -20
  159. package/dist/endpoint-config.js.map +1 -1
  160. package/dist/endpoint-notify.js +48 -9
  161. package/dist/endpoint-notify.js.map +1 -1
  162. package/dist/index.js +50 -18
  163. package/dist/index.js.map +1 -1
  164. package/dist/openshell-runtime.d.ts.map +1 -1
  165. package/dist/openshell-runtime.js +82 -38
  166. package/dist/openshell-runtime.js.map +1 -1
  167. package/dist/program.d.ts.map +1 -1
  168. package/dist/program.js +85 -78
  169. package/dist/program.js.map +1 -1
  170. package/dist/repl.js +31 -25
  171. package/dist/repl.js.map +1 -1
  172. package/dist/signing.js +6 -3
  173. package/dist/signing.js.map +1 -1
  174. package/dist/telegram-notify.js +40 -3
  175. package/dist/telegram-notify.js.map +1 -1
  176. package/dist/tui/App.d.ts.map +1 -1
  177. package/dist/tui/App.js +56 -89
  178. package/dist/tui/App.js.map +1 -1
  179. package/dist/tui/Footer.js +7 -4
  180. package/dist/tui/Footer.js.map +1 -1
  181. package/dist/tui/Header.d.ts +1 -1
  182. package/dist/tui/Header.d.ts.map +1 -1
  183. package/dist/tui/Header.js +14 -9
  184. package/dist/tui/Header.js.map +1 -1
  185. package/dist/tui/InputLine.d.ts +2 -1
  186. package/dist/tui/InputLine.d.ts.map +1 -1
  187. package/dist/tui/InputLine.js +47 -97
  188. package/dist/tui/InputLine.js.map +1 -1
  189. package/dist/tui/Viewport.d.ts +1 -2
  190. package/dist/tui/Viewport.d.ts.map +1 -1
  191. package/dist/tui/Viewport.js +26 -6
  192. package/dist/tui/Viewport.js.map +1 -1
  193. package/dist/tui/WalletConnectPairing.js +19 -16
  194. package/dist/tui/WalletConnectPairing.js.map +1 -1
  195. package/dist/tui/components/Button.js +9 -6
  196. package/dist/tui/components/Button.js.map +1 -1
  197. package/dist/tui/components/CeremonyView.js +8 -5
  198. package/dist/tui/components/CeremonyView.js.map +1 -1
  199. package/dist/tui/components/CompletionDropdown.js +9 -6
  200. package/dist/tui/components/CompletionDropdown.js.map +1 -1
  201. package/dist/tui/components/ConfirmPrompt.js +8 -5
  202. package/dist/tui/components/ConfirmPrompt.js.map +1 -1
  203. package/dist/tui/components/CustomTextInput.js +14 -11
  204. package/dist/tui/components/CustomTextInput.js.map +1 -1
  205. package/dist/tui/components/InteractiveTable.js +12 -9
  206. package/dist/tui/components/InteractiveTable.js.map +1 -1
  207. package/dist/tui/components/StepSpinner.js +13 -10
  208. package/dist/tui/components/StepSpinner.js.map +1 -1
  209. package/dist/tui/components/Toast.js +12 -8
  210. package/dist/tui/components/Toast.js.map +1 -1
  211. package/dist/tui/index.d.ts.map +1 -1
  212. package/dist/tui/index.js +21 -28
  213. package/dist/tui/index.js.map +1 -1
  214. package/dist/tui/useChat.js +19 -13
  215. package/dist/tui/useChat.js.map +1 -1
  216. package/dist/tui/useCommand.d.ts +2 -3
  217. package/dist/tui/useCommand.d.ts.map +1 -1
  218. package/dist/tui/useCommand.js +24 -100
  219. package/dist/tui/useCommand.js.map +1 -1
  220. package/dist/tui/useNotifications.js +8 -5
  221. package/dist/tui/useNotifications.js.map +1 -1
  222. package/dist/tui/useScroll.d.ts.map +1 -1
  223. package/dist/tui/useScroll.js +12 -15
  224. package/dist/tui/useScroll.js.map +1 -1
  225. package/dist/ui/banner.d.ts +0 -12
  226. package/dist/ui/banner.d.ts.map +1 -1
  227. package/dist/ui/banner.js +19 -35
  228. package/dist/ui/banner.js.map +1 -1
  229. package/dist/ui/colors.js +19 -13
  230. package/dist/ui/colors.js.map +1 -1
  231. package/dist/ui/format.js +14 -6
  232. package/dist/ui/format.js.map +1 -1
  233. package/dist/ui/qr-render.js +11 -4
  234. package/dist/ui/qr-render.js.map +1 -1
  235. package/dist/ui/rpc-fallback.js +11 -6
  236. package/dist/ui/rpc-fallback.js.map +1 -1
  237. package/dist/ui/spinner.js +12 -6
  238. package/dist/ui/spinner.js.map +1 -1
  239. package/dist/ui/tree.js +6 -3
  240. package/dist/ui/tree.js.map +1 -1
  241. package/dist/utils/format.js +41 -27
  242. package/dist/utils/format.js.map +1 -1
  243. package/dist/utils/hash.js +42 -4
  244. package/dist/utils/hash.js.map +1 -1
  245. package/dist/utils/time.js +6 -2
  246. package/dist/utils/time.js.map +1 -1
  247. package/dist/wallet-router.d.ts +1 -1
  248. package/dist/wallet-router.d.ts.map +1 -1
  249. package/dist/wallet-router.js +19 -12
  250. package/dist/wallet-router.js.map +1 -1
  251. package/dist/walletconnect-session.d.ts +1 -1
  252. package/dist/walletconnect-session.d.ts.map +1 -1
  253. package/dist/walletconnect-session.js +11 -6
  254. package/dist/walletconnect-session.js.map +1 -1
  255. package/dist/walletconnect.d.ts +5 -6
  256. package/dist/walletconnect.d.ts.map +1 -1
  257. package/dist/walletconnect.js +35 -32
  258. package/dist/walletconnect.js.map +1 -1
  259. package/package.json +11 -10
  260. package/INK6-UX-SPEC.md +0 -446
  261. package/MIGRATION-SPEC.md +0 -108
  262. package/TUI-SPEC.md +0 -214
  263. package/scripts/authorize-machine-key.ts +0 -43
  264. package/scripts/drain-wallet.ts +0 -149
  265. package/scripts/execute-spend-only.ts +0 -81
  266. package/scripts/register-agent-userop.ts +0 -186
  267. package/src/abis.ts +0 -187
  268. package/src/bundler.ts +0 -235
  269. package/src/client.ts +0 -36
  270. package/src/coinbase-smart-wallet.ts +0 -51
  271. package/src/commands/accept.ts +0 -64
  272. package/src/commands/agent-handshake.ts +0 -72
  273. package/src/commands/agent.ts +0 -691
  274. package/src/commands/agreements.ts +0 -350
  275. package/src/commands/arbitrator.ts +0 -180
  276. package/src/commands/arena-handshake.ts +0 -274
  277. package/src/commands/arena.ts +0 -122
  278. package/src/commands/backup.ts +0 -117
  279. package/src/commands/cancel.ts +0 -35
  280. package/src/commands/channel.ts +0 -218
  281. package/src/commands/coldstart.ts +0 -165
  282. package/src/commands/config.ts +0 -68
  283. package/src/commands/contract-interaction.ts +0 -166
  284. package/src/commands/daemon.ts +0 -1054
  285. package/src/commands/deliver.ts +0 -148
  286. package/src/commands/discover.ts +0 -350
  287. package/src/commands/dispute.ts +0 -375
  288. package/src/commands/doctor.ts +0 -172
  289. package/src/commands/endpoint.ts +0 -620
  290. package/src/commands/feed.ts +0 -229
  291. package/src/commands/hire.ts +0 -245
  292. package/src/commands/migrate.ts +0 -177
  293. package/src/commands/negotiate.ts +0 -272
  294. package/src/commands/openshell.ts +0 -1055
  295. package/src/commands/owner.ts +0 -35
  296. package/src/commands/policy.ts +0 -263
  297. package/src/commands/relay.ts +0 -277
  298. package/src/commands/remediate.ts +0 -24
  299. package/src/commands/reputation.ts +0 -79
  300. package/src/commands/setup.ts +0 -343
  301. package/src/commands/trust.ts +0 -27
  302. package/src/commands/verify.ts +0 -91
  303. package/src/commands/wallet.ts +0 -3548
  304. package/src/commands/watch.ts +0 -220
  305. package/src/commands/watchtower.ts +0 -248
  306. package/src/commands/workroom.ts +0 -963
  307. package/src/config.ts +0 -220
  308. package/src/daemon/config.ts +0 -344
  309. package/src/daemon/hire-listener.ts +0 -226
  310. package/src/daemon/index.ts +0 -1089
  311. package/src/daemon/job-lifecycle.ts +0 -215
  312. package/src/daemon/notify.ts +0 -297
  313. package/src/daemon/token-metering.ts +0 -183
  314. package/src/daemon/userops.ts +0 -119
  315. package/src/daemon/wallet-monitor.ts +0 -90
  316. package/src/drain-v4.ts +0 -159
  317. package/src/endpoint-config.ts +0 -83
  318. package/src/endpoint-notify.ts +0 -129
  319. package/src/index.ts +0 -74
  320. package/src/openshell-runtime.ts +0 -281
  321. package/src/program.ts +0 -88
  322. package/src/repl.ts +0 -178
  323. package/src/signing.ts +0 -28
  324. package/src/telegram-notify.ts +0 -88
  325. package/src/tui/App.tsx +0 -263
  326. package/src/tui/Footer.tsx +0 -18
  327. package/src/tui/Header.tsx +0 -45
  328. package/src/tui/InputLine.tsx +0 -243
  329. package/src/tui/Viewport.tsx +0 -51
  330. package/src/tui/WalletConnectPairing.tsx +0 -114
  331. package/src/tui/components/Button.tsx +0 -38
  332. package/src/tui/components/CeremonyView.tsx +0 -39
  333. package/src/tui/components/CompletionDropdown.tsx +0 -56
  334. package/src/tui/components/ConfirmPrompt.tsx +0 -36
  335. package/src/tui/components/CustomTextInput.tsx +0 -132
  336. package/src/tui/components/InteractiveTable.tsx +0 -106
  337. package/src/tui/components/StepSpinner.tsx +0 -84
  338. package/src/tui/components/Toast.tsx +0 -59
  339. package/src/tui/index.tsx +0 -90
  340. package/src/tui/useChat.ts +0 -103
  341. package/src/tui/useCommand.ts +0 -238
  342. package/src/tui/useNotifications.ts +0 -28
  343. package/src/tui/useScroll.ts +0 -69
  344. package/src/ui/banner.ts +0 -78
  345. package/src/ui/colors.ts +0 -30
  346. package/src/ui/format.ts +0 -78
  347. package/src/ui/qr-render.ts +0 -92
  348. package/src/ui/rpc-fallback.ts +0 -59
  349. package/src/ui/spinner.ts +0 -56
  350. package/src/ui/tree.ts +0 -16
  351. package/src/utils/format.ts +0 -48
  352. package/src/utils/hash.ts +0 -5
  353. package/src/utils/time.ts +0 -15
  354. package/src/wallet-router.ts +0 -178
  355. package/src/walletconnect-session.ts +0 -27
  356. package/src/walletconnect.ts +0 -309
  357. package/test/time.test.js +0 -11
  358. package/tsconfig.json +0 -33
package/src/ui/format.ts DELETED
@@ -1,78 +0,0 @@
1
- // ─── Address Formatting ───────────────────────────────────────────────────────
2
-
3
- /**
4
- * Truncate an address to 0x1234...abcd format (first 6 + last 4 chars).
5
- * Full address is preserved in --json output only.
6
- */
7
- export function formatAddress(address: string): string {
8
- if (address.length <= 12) return address;
9
- return `${address.slice(0, 6)}...${address.slice(-4)}`;
10
- }
11
-
12
- // ─── Value Formatting ─────────────────────────────────────────────────────────
13
-
14
- /**
15
- * Format a single token value: "0.024 ETH" or "150 USDC"
16
- */
17
- export function formatValue(amount: string | number, token: string): string {
18
- return `${amount} ${token}`;
19
- }
20
-
21
- /**
22
- * Format a combined ETH + token balance: "0.024 ETH · 150 USDC"
23
- */
24
- export function formatBalance(
25
- ethAmount: string | number,
26
- tokenAmount?: string | number,
27
- tokenSymbol?: string
28
- ): string {
29
- const eth = `${ethAmount} ETH`;
30
- if (tokenAmount !== undefined && tokenSymbol) {
31
- return `${eth} · ${tokenAmount} ${tokenSymbol}`;
32
- }
33
- return eth;
34
- }
35
-
36
- // ─── Timestamp Formatting ─────────────────────────────────────────────────────
37
-
38
- /**
39
- * Format a unix timestamp (seconds) as a relative "time ago" string.
40
- */
41
- export function formatTimeAgo(timestampSeconds: number): string {
42
- const now = Math.floor(Date.now() / 1000);
43
- const delta = now - timestampSeconds;
44
-
45
- if (delta < 0) return "in " + formatDuration(Math.abs(delta));
46
- if (delta < 60) return "just now";
47
- if (delta < 3600) {
48
- const m = Math.floor(delta / 60);
49
- return `${m}m ago`;
50
- }
51
- if (delta < 86400) {
52
- const h = Math.floor(delta / 3600);
53
- return `${h}h ago`;
54
- }
55
- const d = Math.floor(delta / 86400);
56
- return `${d}d ago`;
57
- }
58
-
59
- /**
60
- * Format seconds-until-expiry as "61h 14m" or "2d 3h".
61
- */
62
- export function formatDuration(seconds: number): string {
63
- if (seconds <= 0) return "expired";
64
- const d = Math.floor(seconds / 86400);
65
- const h = Math.floor((seconds % 86400) / 3600);
66
- const m = Math.floor((seconds % 3600) / 60);
67
-
68
- if (d > 0) return h > 0 ? `${d}d ${h}h` : `${d}d`;
69
- if (h > 0) return m > 0 ? `${h}h ${m}m` : `${h}h`;
70
- return `${m}m`;
71
- }
72
-
73
- /**
74
- * Format a unix timestamp (seconds) as a locale date/time string.
75
- */
76
- export function formatTimestamp(timestampSeconds: number): string {
77
- return new Date(timestampSeconds * 1000).toLocaleString();
78
- }
@@ -1,92 +0,0 @@
1
- import QRCode from "qrcode";
2
-
3
- export interface QRRenderOptions {
4
- /** Error correction level. L = smallest QR. Default: 'L' */
5
- errorCorrection?: "L" | "M" | "Q" | "H";
6
- /** Quiet zone size in modules. Default: 1 (standard is 4, but 1 suffices for terminal) */
7
- quiet?: number;
8
- /** Invert colors for dark terminal backgrounds. Default: true */
9
- invert?: boolean;
10
- }
11
-
12
- /**
13
- * Render a QR code as terminal-friendly half-block Unicode characters.
14
- * Returns an array of strings, one per terminal row.
15
- *
16
- * Uses qrcode library for matrix generation, custom renderer for compact output.
17
- * Key optimizations vs qrcode-terminal:
18
- * - Error correction L (not M) — ~20% fewer modules
19
- * - Quiet zone 1 (not 4) — saves ~6 rows
20
- * - Half-block chars: each terminal row = 2 QR module rows
21
- */
22
- export function renderQR(data: string, options?: QRRenderOptions): string[] {
23
- const ec = options?.errorCorrection ?? "L";
24
- const quiet = options?.quiet ?? 1;
25
- const invert = options?.invert ?? true;
26
-
27
- // Generate QR matrix
28
- const qr = QRCode.create(data, {
29
- errorCorrectionLevel: ec,
30
- });
31
-
32
- const size = qr.modules.size;
33
- const modules = qr.modules.data;
34
-
35
- // Helper: is module at (row, col) dark? (with quiet zone)
36
- const totalSize = size + quiet * 2;
37
- const isDark = (row: number, col: number): boolean => {
38
- const r = row - quiet;
39
- const c = col - quiet;
40
- if (r < 0 || r >= size || c < 0 || c >= size) return false;
41
- return modules[r * size + c] === 1;
42
- };
43
-
44
- const lines: string[] = [];
45
-
46
- // Process 2 rows at a time using half-block characters
47
- for (let row = 0; row < totalSize; row += 2) {
48
- let line = "";
49
- for (let col = 0; col < totalSize; col++) {
50
- const top = isDark(row, col);
51
- const bottom = row + 1 < totalSize ? isDark(row + 1, col) : false;
52
-
53
- if (invert) {
54
- // Dark terminal: dark modules = space (background), light = filled
55
- if (top && bottom) {
56
- line += " "; // both dark → background
57
- } else if (top && !bottom) {
58
- line += "▄"; // top dark, bottom light → bottom half filled
59
- } else if (!top && bottom) {
60
- line += "▀"; // top light, bottom dark → top half filled
61
- } else {
62
- line += "█"; // both light → full block
63
- }
64
- } else {
65
- // Light terminal: dark modules = filled
66
- if (top && bottom) {
67
- line += "█";
68
- } else if (top && !bottom) {
69
- line += "▀";
70
- } else if (!top && bottom) {
71
- line += "▄";
72
- } else {
73
- line += " ";
74
- }
75
- }
76
- }
77
- lines.push(line);
78
- }
79
-
80
- return lines;
81
- }
82
-
83
- /**
84
- * Render QR code to stdout (for non-TUI / child process context).
85
- * Drop-in replacement for qrcode-terminal.generate().
86
- */
87
- export function printQR(data: string, options?: QRRenderOptions): void {
88
- const lines = renderQR(data, options);
89
- for (const line of lines) {
90
- console.log(" " + line);
91
- }
92
- }
@@ -1,59 +0,0 @@
1
- import { ethers } from "ethers";
2
-
3
- /**
4
- * Public RPC endpoints for Base mainnet, ordered by reliability.
5
- * Used as fallbacks when the configured RPC fails on read-only calls.
6
- */
7
- const BASE_FALLBACK_RPCS = [
8
- "https://base.llamarpc.com",
9
- "https://base-rpc.publicnode.com",
10
- "https://1rpc.io/base",
11
- ];
12
-
13
- /** Check if verbose mode is enabled via --verbose flag or ARC402_DEBUG env */
14
- export function isVerbose(): boolean {
15
- return process.argv.includes("--verbose") || process.env.ARC402_DEBUG === "1";
16
- }
17
-
18
- /** Log only when verbose mode is on */
19
- export function verbose(...args: unknown[]): void {
20
- if (isVerbose()) {
21
- console.log("\x1b[2m [verbose]", ...args, "\x1b[22m");
22
- }
23
- }
24
-
25
- /**
26
- * Try a read-only call on the configured RPC first, then fall back
27
- * to public RPCs. Write operations always use the configured RPC.
28
- */
29
- export async function callWithFallback<T>(
30
- configuredRpcUrl: string,
31
- fn: (provider: ethers.JsonRpcProvider) => Promise<T>,
32
- ): Promise<T> {
33
- // Try configured RPC first
34
- try {
35
- verbose(`RPC call via ${configuredRpcUrl}`);
36
- const provider = new ethers.JsonRpcProvider(configuredRpcUrl);
37
- const result = await fn(provider);
38
- verbose(`RPC call succeeded`);
39
- return result;
40
- } catch (e) {
41
- verbose(`RPC failed on ${configuredRpcUrl}: ${e instanceof Error ? e.message.slice(0, 80) : String(e)}`);
42
- }
43
-
44
- // Try each fallback
45
- for (const rpc of BASE_FALLBACK_RPCS) {
46
- try {
47
- verbose(`Falling back to ${rpc}`);
48
- const provider = new ethers.JsonRpcProvider(rpc);
49
- const result = await fn(provider);
50
- verbose(`Fallback succeeded on ${rpc}`);
51
- return result;
52
- } catch (e) {
53
- verbose(`Fallback failed on ${rpc}: ${e instanceof Error ? e.message.slice(0, 80) : String(e)}`);
54
- continue;
55
- }
56
- }
57
-
58
- throw new Error("All RPC endpoints failed for read-only call");
59
- }
package/src/ui/spinner.ts DELETED
@@ -1,56 +0,0 @@
1
- import ora, { Ora } from "ora";
2
- import chalk from "chalk";
3
-
4
- const SPINNER_FRAMES = {
5
- interval: 120,
6
- frames: ["◈ ", "◉ ", "◎ ", "◉ "],
7
- };
8
-
9
- export interface ArcSpinner {
10
- succeed(text?: string): void;
11
- fail(text?: string): void;
12
- update(text: string): void;
13
- stop(): void;
14
- }
15
-
16
- export function startSpinner(text: string): ArcSpinner {
17
- if (process.env.ARC402_PRINT) {
18
- process.stdout.write(text + "\n");
19
- return {
20
- succeed(msg?: string) { if (msg) process.stdout.write("✓ " + msg + "\n"); },
21
- fail(msg?: string) { if (msg) process.stderr.write("✗ " + msg + "\n"); },
22
- update(t: string) { process.stdout.write(t + "\n"); },
23
- stop() {},
24
- };
25
- }
26
-
27
- const instance: Ora = ora({
28
- text,
29
- spinner: SPINNER_FRAMES,
30
- color: "cyan",
31
- prefixText: " ",
32
- }).start();
33
-
34
- return {
35
- succeed(msg?: string) {
36
- instance.stopAndPersist({
37
- symbol: chalk.green("✓"),
38
- text: msg ?? instance.text,
39
- prefixText: " ",
40
- });
41
- },
42
- fail(msg?: string) {
43
- instance.stopAndPersist({
44
- symbol: chalk.red("✗"),
45
- text: msg ?? instance.text,
46
- prefixText: " ",
47
- });
48
- },
49
- update(text: string) {
50
- instance.text = text;
51
- },
52
- stop() {
53
- instance.stop();
54
- },
55
- };
56
- }
package/src/ui/tree.ts DELETED
@@ -1,16 +0,0 @@
1
- import { c } from "./colors.js";
2
-
3
- export interface TreeItem {
4
- label: string;
5
- value: string;
6
- last?: boolean;
7
- }
8
-
9
- export function renderTree(items: TreeItem[]): void {
10
- items.forEach((item, i) => {
11
- const isLast = item.last ?? (i === items.length - 1);
12
- const branch = isLast ? "└" : "├";
13
- const paddedLabel = item.label.padEnd(10);
14
- console.log(` ${c.dim(branch)} ${c.dim(paddedLabel)} ${c.white(item.value)}`);
15
- });
16
- }
@@ -1,48 +0,0 @@
1
- import chalk from "chalk";
2
- import Table from "cli-table3";
3
- import { AgreementStatus, IdentityTier, ReputationSignalType } from "@arc402/sdk";
4
-
5
- export const truncateAddress = (address: string) => address.length <= 12 ? address : `${address.slice(0, 6)}...${address.slice(-4)}`;
6
- export const formatDate = (timestamp: number) => new Date(timestamp * 1000).toLocaleString();
7
-
8
- export function getTrustTier(score: number): string {
9
- if (score >= 800) return "Autonomous";
10
- if (score >= 600) return "Elevated";
11
- if (score >= 300) return "Standard";
12
- if (score >= 100) return "Restricted";
13
- return "Probationary";
14
- }
15
-
16
- export function agreementStatusLabel(status: AgreementStatus): string {
17
- return AgreementStatus[status] ?? "UNKNOWN";
18
- }
19
-
20
- export function colourStatus(status: AgreementStatus): string {
21
- const label = agreementStatusLabel(status);
22
- switch (status) {
23
- case AgreementStatus.PROPOSED:
24
- case AgreementStatus.REVISION_REQUESTED:
25
- return chalk.yellow(label);
26
- case AgreementStatus.ACCEPTED:
27
- case AgreementStatus.REVISED:
28
- case AgreementStatus.PENDING_VERIFICATION:
29
- return chalk.blue(label);
30
- case AgreementStatus.FULFILLED:
31
- return chalk.green(label);
32
- case AgreementStatus.DISPUTED:
33
- case AgreementStatus.ESCALATED_TO_HUMAN:
34
- case AgreementStatus.ESCALATED_TO_ARBITRATION:
35
- return chalk.red(label);
36
- default:
37
- return chalk.gray(label);
38
- }
39
- }
40
-
41
- export const identityTierLabel = (tier: IdentityTier) => IdentityTier[tier] ?? "NONE";
42
- export const reputationSignalLabel = (signal: ReputationSignalType) => ReputationSignalType[signal] ?? "UNKNOWN";
43
-
44
- export function printTable(head: string[], rows: (string | number)[][]) {
45
- const table = new Table({ head: head.map((value) => chalk.cyan(value)), style: { head: [], border: [] } });
46
- rows.forEach((row) => table.push(row));
47
- console.log(table.toString());
48
- }
package/src/utils/hash.ts DELETED
@@ -1,5 +0,0 @@
1
- import * as fs from "fs";
2
- import { ethers } from "ethers";
3
-
4
- export const hashFile = (filePath: string) => ethers.keccak256(fs.readFileSync(filePath));
5
- export const hashString = (value: string) => ethers.keccak256(ethers.toUtf8Bytes(value));
package/src/utils/time.ts DELETED
@@ -1,15 +0,0 @@
1
- export function parseDuration(duration: string): number {
2
- const now = Math.floor(Date.now() / 1000);
3
- const match = duration.match(/^(\d+)([hd])$/i);
4
- if (!match) throw new Error(`Invalid duration format: \"${duration}\". Use e.g. 2h, 24h, 7d`);
5
- const value = Number(match[1]);
6
- return now + (match[2].toLowerCase() === "d" ? value * 86400 : value * 3600);
7
- }
8
-
9
- export function formatDeadline(deadline: number): string {
10
- const diff = deadline - Math.floor(Date.now() / 1000);
11
- if (diff < 0) return "EXPIRED";
12
- const hours = Math.floor(diff / 3600);
13
- const days = Math.floor(hours / 24);
14
- return days > 0 ? `${days}d ${hours % 24}h remaining` : `${hours}h remaining`;
15
- }
@@ -1,178 +0,0 @@
1
- import { ethers } from "ethers";
2
- import { Arc402Config } from "./config.js";
3
- import { ARC402_WALLET_EXECUTE_ABI } from "./abis.js";
4
-
5
- // ─── ARC402Wallet custom error decoder ─────────────────────────────────────
6
-
7
- const WALLET_CUSTOM_ERROR_IFACE = new ethers.Interface([
8
- "error WVel()",
9
- "error WCtx()",
10
- "error WAtt()",
11
- "error WAuth()",
12
- "error WCall()",
13
- "error WZero()",
14
- "error WFrozen()",
15
- "error WPending()",
16
- "error WLock()",
17
- ]);
18
-
19
- const WALLET_ERROR_HELP: Record<string, string> = {
20
- WVel:
21
- "Velocity limit breached. Your wallet has been automatically frozen as a security measure.\n" +
22
- " To unfreeze: arc402 wallet unfreeze\n" +
23
- " To prevent this: check your spending velocity limits with arc402 wallet policy status",
24
- WCtx:
25
- "Context error: either a context is already open, or no context is open when one is required.\n" +
26
- " Note: each context allows exactly one spend — a new context must be opened per payment.\n" +
27
- " Check context state: arc402 wallet check-context\n" +
28
- " Close stale context: arc402 wallet close-context",
29
- WAtt:
30
- "Attestation invalid: not found, already consumed, expired, or parameters do not match.\n" +
31
- " Each attestation can only be used once. Create a new attestation for each spend.",
32
- WAuth:
33
- "Machine key not authorized on this wallet.\n" +
34
- " Fix: arc402 wallet authorize-machine-key <your-machine-key-address>",
35
- WCall:
36
- "External contract call failed. The target contract reverted. Check the target address and calldata.",
37
- WZero:
38
- "Zero address not allowed for a required address parameter.",
39
- WFrozen:
40
- "Wallet is frozen and cannot process transactions.\n" +
41
- " To unfreeze: arc402 wallet unfreeze (owner WalletConnect required)",
42
- WPending:
43
- "A registry upgrade is already pending. Cancel it first: arc402 wallet cancel-registry-upgrade",
44
- WLock:
45
- "Registry upgrade timelock has not elapsed yet. Check: arc402 wallet execute-registry-upgrade",
46
- };
47
-
48
- /**
49
- * Attempts to decode a known ARC402Wallet custom error from a thrown error.
50
- * If a recognized error is found, prints a human-readable message and exits.
51
- * Otherwise, rethrows the original error.
52
- */
53
- export function handleWalletError(e: unknown): never {
54
- // Extract revert data from various ethers v6 error shapes
55
- let errorData: string | undefined;
56
- if (e && typeof e === "object") {
57
- const err = e as Record<string, unknown>;
58
- if (typeof err.data === "string") {
59
- errorData = err.data;
60
- } else if (err.error && typeof err.error === "object") {
61
- const inner = err.error as Record<string, unknown>;
62
- if (typeof inner.data === "string") errorData = inner.data;
63
- }
64
- // ethers v6 sometimes nests it in info.error.data
65
- if (!errorData && err.info && typeof err.info === "object") {
66
- const info = err.info as Record<string, unknown>;
67
- if (info.error && typeof info.error === "object") {
68
- const ie = info.error as Record<string, unknown>;
69
- if (typeof ie.data === "string") errorData = ie.data;
70
- }
71
- }
72
- // Fallback: parse from error message string
73
- if (!errorData && typeof err.message === "string") {
74
- const m = err.message.match(/"data"\s*:\s*"(0x[0-9a-fA-F]+)"/);
75
- if (m) errorData = m[1];
76
- }
77
- }
78
-
79
- if (errorData && errorData.length >= 10) {
80
- try {
81
- const decoded = WALLET_CUSTOM_ERROR_IFACE.parseError(errorData);
82
- if (decoded) {
83
- const help = WALLET_ERROR_HELP[decoded.name];
84
- if (help) {
85
- console.error(`\nError: ${decoded.name}()`);
86
- console.error(` ${help.split("\n").join("\n ")}`);
87
- process.exit(1);
88
- }
89
- }
90
- } catch { /* decoding failed — fall through to rethrow */ }
91
- }
92
-
93
- throw e;
94
- }
95
-
96
- // ─── Selector-based error decoder (J1-06) ────────────────────────────────────
97
- //
98
- // Maps known 4-byte selectors to human-readable messages for use in external error handling.
99
-
100
- const WALLET_ERROR_SELECTOR_MAP: Record<string, string> = {
101
- "0x13af807f": "Context error: either a context is already open, or no context is open. Check with `arc402 wallet check-context`",
102
- "0x88529d53": "Attestation error: attestation not found, already used, expired, or wrong parameters",
103
- "0xd6636aaa": "Velocity limit breached — wallet is now frozen. Run `arc402 wallet unfreeze` to recover",
104
- "0xbc34a075": "Unauthorized: this operation requires owner or machine key authorization",
105
- "0xf5138cb6": "Contract call failed: the target contract reverted. Check that the target contract is working correctly",
106
- "0xd92e233d": "Zero address error: a required address parameter was address(0)",
107
- "0xb808d662": "Wallet is frozen. Run `arc402 wallet unfreeze` to recover (requires owner)",
108
- };
109
-
110
- /**
111
- * Decode a 4-byte ARC402Wallet custom error selector into a human-readable message.
112
- * Returns null if the selector is not a known wallet error.
113
- */
114
- export function decodeWalletError(errorData: string): string | null {
115
- if (!errorData || errorData.length < 10) return null;
116
- const selector = errorData.slice(0, 10).toLowerCase();
117
- return WALLET_ERROR_SELECTOR_MAP[selector] ?? null;
118
- }
119
-
120
- export interface SenderInfo {
121
- address: string;
122
- useContract: boolean;
123
- }
124
-
125
- export function getEffectiveSender(config: Arc402Config): SenderInfo {
126
- if (config.walletContractAddress) {
127
- return { address: config.walletContractAddress, useContract: true };
128
- }
129
- const wallet = new ethers.Wallet(config.privateKey!);
130
- return { address: wallet.address, useContract: false };
131
- }
132
-
133
- export function printSenderInfo(config: Arc402Config): void {
134
- if (config.walletContractAddress) {
135
- console.log(`Using ARC402Wallet: ${config.walletContractAddress}`);
136
- console.log(`Policy enforcement active — transaction subject to configured limits`);
137
- } else {
138
- const wallet = new ethers.Wallet(config.privateKey!);
139
- console.log(`Using EOA wallet: ${wallet.address}`);
140
- console.log(`Tip: run \`arc402 wallet deploy\` to enable spending limits and policy enforcement`);
141
- }
142
- }
143
-
144
- /**
145
- * Route a write transaction through the ARC402Wallet's executeContractCall when deployed,
146
- * otherwise encode calldata directly against the target contract using the provided ABI.
147
- */
148
- export async function executeContractWriteViaWallet(
149
- walletContractAddress: string,
150
- signer: ethers.Wallet,
151
- targetAddress: string,
152
- contractAbi: readonly string[],
153
- functionName: string,
154
- args: unknown[],
155
- value: bigint = 0n,
156
- approvalToken: string = ethers.ZeroAddress,
157
- maxApprovalAmount: bigint = 0n,
158
- ): Promise<ethers.ContractTransactionResponse> {
159
- const iface = new ethers.Interface(contractAbi);
160
- const data = iface.encodeFunctionData(functionName, args);
161
- const walletContract = new ethers.Contract(
162
- walletContractAddress,
163
- ARC402_WALLET_EXECUTE_ABI,
164
- signer,
165
- );
166
- try {
167
- return await walletContract.executeContractCall({
168
- target: targetAddress,
169
- data,
170
- value,
171
- minReturnValue: 0n,
172
- maxApprovalAmount,
173
- approvalToken,
174
- });
175
- } catch (e) {
176
- handleWalletError(e);
177
- }
178
- }
@@ -1,27 +0,0 @@
1
- import { Arc402Config, saveConfig } from "./config.js";
2
-
3
- export interface WCSessionData {
4
- topic: string;
5
- expiry: number; // Unix timestamp
6
- account: string; // Phone wallet address
7
- chainId: number;
8
- }
9
-
10
- /** Returns null if no session, expired, or wrong chainId. */
11
- export function loadWCSession(config: Arc402Config, requiredChainId: number): WCSessionData | null {
12
- if (!config.wcSession) return null;
13
- const now = Math.floor(Date.now() / 1000);
14
- if (config.wcSession.expiry <= now) return null;
15
- if (config.wcSession.chainId !== requiredChainId) return null;
16
- return config.wcSession as WCSessionData;
17
- }
18
-
19
- export function saveWCSession(config: Arc402Config, session: WCSessionData): void {
20
- config.wcSession = session;
21
- saveConfig(config);
22
- }
23
-
24
- export function clearWCSession(config: Arc402Config): void {
25
- delete config.wcSession;
26
- saveConfig(config);
27
- }