arc402-cli 0.9.19 → 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 (359) 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.d.ts.map +1 -1
  161. package/dist/endpoint-notify.js +49 -15
  162. package/dist/endpoint-notify.js.map +1 -1
  163. package/dist/index.js +50 -18
  164. package/dist/index.js.map +1 -1
  165. package/dist/openshell-runtime.d.ts.map +1 -1
  166. package/dist/openshell-runtime.js +82 -38
  167. package/dist/openshell-runtime.js.map +1 -1
  168. package/dist/program.d.ts.map +1 -1
  169. package/dist/program.js +85 -78
  170. package/dist/program.js.map +1 -1
  171. package/dist/repl.js +31 -25
  172. package/dist/repl.js.map +1 -1
  173. package/dist/signing.js +6 -3
  174. package/dist/signing.js.map +1 -1
  175. package/dist/telegram-notify.js +40 -3
  176. package/dist/telegram-notify.js.map +1 -1
  177. package/dist/tui/App.d.ts.map +1 -1
  178. package/dist/tui/App.js +56 -89
  179. package/dist/tui/App.js.map +1 -1
  180. package/dist/tui/Footer.js +7 -4
  181. package/dist/tui/Footer.js.map +1 -1
  182. package/dist/tui/Header.d.ts +1 -1
  183. package/dist/tui/Header.d.ts.map +1 -1
  184. package/dist/tui/Header.js +14 -9
  185. package/dist/tui/Header.js.map +1 -1
  186. package/dist/tui/InputLine.d.ts +2 -1
  187. package/dist/tui/InputLine.d.ts.map +1 -1
  188. package/dist/tui/InputLine.js +47 -97
  189. package/dist/tui/InputLine.js.map +1 -1
  190. package/dist/tui/Viewport.d.ts +1 -2
  191. package/dist/tui/Viewport.d.ts.map +1 -1
  192. package/dist/tui/Viewport.js +26 -6
  193. package/dist/tui/Viewport.js.map +1 -1
  194. package/dist/tui/WalletConnectPairing.js +19 -16
  195. package/dist/tui/WalletConnectPairing.js.map +1 -1
  196. package/dist/tui/components/Button.js +9 -6
  197. package/dist/tui/components/Button.js.map +1 -1
  198. package/dist/tui/components/CeremonyView.js +8 -5
  199. package/dist/tui/components/CeremonyView.js.map +1 -1
  200. package/dist/tui/components/CompletionDropdown.js +9 -6
  201. package/dist/tui/components/CompletionDropdown.js.map +1 -1
  202. package/dist/tui/components/ConfirmPrompt.js +8 -5
  203. package/dist/tui/components/ConfirmPrompt.js.map +1 -1
  204. package/dist/tui/components/CustomTextInput.js +14 -11
  205. package/dist/tui/components/CustomTextInput.js.map +1 -1
  206. package/dist/tui/components/InteractiveTable.js +12 -9
  207. package/dist/tui/components/InteractiveTable.js.map +1 -1
  208. package/dist/tui/components/StepSpinner.js +13 -10
  209. package/dist/tui/components/StepSpinner.js.map +1 -1
  210. package/dist/tui/components/Toast.js +12 -8
  211. package/dist/tui/components/Toast.js.map +1 -1
  212. package/dist/tui/index.d.ts.map +1 -1
  213. package/dist/tui/index.js +21 -28
  214. package/dist/tui/index.js.map +1 -1
  215. package/dist/tui/useChat.js +19 -13
  216. package/dist/tui/useChat.js.map +1 -1
  217. package/dist/tui/useCommand.d.ts +2 -3
  218. package/dist/tui/useCommand.d.ts.map +1 -1
  219. package/dist/tui/useCommand.js +24 -100
  220. package/dist/tui/useCommand.js.map +1 -1
  221. package/dist/tui/useNotifications.js +8 -5
  222. package/dist/tui/useNotifications.js.map +1 -1
  223. package/dist/tui/useScroll.d.ts.map +1 -1
  224. package/dist/tui/useScroll.js +12 -15
  225. package/dist/tui/useScroll.js.map +1 -1
  226. package/dist/ui/banner.d.ts +0 -12
  227. package/dist/ui/banner.d.ts.map +1 -1
  228. package/dist/ui/banner.js +19 -35
  229. package/dist/ui/banner.js.map +1 -1
  230. package/dist/ui/colors.js +19 -13
  231. package/dist/ui/colors.js.map +1 -1
  232. package/dist/ui/format.js +14 -6
  233. package/dist/ui/format.js.map +1 -1
  234. package/dist/ui/qr-render.js +11 -4
  235. package/dist/ui/qr-render.js.map +1 -1
  236. package/dist/ui/rpc-fallback.js +11 -6
  237. package/dist/ui/rpc-fallback.js.map +1 -1
  238. package/dist/ui/spinner.js +12 -6
  239. package/dist/ui/spinner.js.map +1 -1
  240. package/dist/ui/tree.js +6 -3
  241. package/dist/ui/tree.js.map +1 -1
  242. package/dist/utils/format.js +41 -27
  243. package/dist/utils/format.js.map +1 -1
  244. package/dist/utils/hash.js +42 -4
  245. package/dist/utils/hash.js.map +1 -1
  246. package/dist/utils/time.js +6 -2
  247. package/dist/utils/time.js.map +1 -1
  248. package/dist/wallet-router.d.ts +1 -1
  249. package/dist/wallet-router.d.ts.map +1 -1
  250. package/dist/wallet-router.js +19 -12
  251. package/dist/wallet-router.js.map +1 -1
  252. package/dist/walletconnect-session.d.ts +1 -1
  253. package/dist/walletconnect-session.d.ts.map +1 -1
  254. package/dist/walletconnect-session.js +11 -6
  255. package/dist/walletconnect-session.js.map +1 -1
  256. package/dist/walletconnect.d.ts +5 -6
  257. package/dist/walletconnect.d.ts.map +1 -1
  258. package/dist/walletconnect.js +35 -32
  259. package/dist/walletconnect.js.map +1 -1
  260. package/package.json +11 -10
  261. package/INK6-UX-SPEC.md +0 -446
  262. package/MIGRATION-SPEC.md +0 -108
  263. package/TUI-SPEC.md +0 -214
  264. package/scripts/authorize-machine-key.ts +0 -43
  265. package/scripts/drain-wallet.ts +0 -149
  266. package/scripts/execute-spend-only.ts +0 -81
  267. package/scripts/register-agent-userop.ts +0 -186
  268. package/src/abis.ts +0 -187
  269. package/src/bundler.ts +0 -235
  270. package/src/client.ts +0 -36
  271. package/src/coinbase-smart-wallet.ts +0 -51
  272. package/src/commands/accept.ts +0 -64
  273. package/src/commands/agent-handshake.ts +0 -72
  274. package/src/commands/agent.ts +0 -691
  275. package/src/commands/agreements.ts +0 -350
  276. package/src/commands/arbitrator.ts +0 -180
  277. package/src/commands/arena-handshake.ts +0 -274
  278. package/src/commands/arena.ts +0 -122
  279. package/src/commands/backup.ts +0 -117
  280. package/src/commands/cancel.ts +0 -35
  281. package/src/commands/channel.ts +0 -218
  282. package/src/commands/coldstart.ts +0 -165
  283. package/src/commands/config.ts +0 -68
  284. package/src/commands/contract-interaction.ts +0 -166
  285. package/src/commands/daemon.ts +0 -1054
  286. package/src/commands/deliver.ts +0 -148
  287. package/src/commands/discover.ts +0 -350
  288. package/src/commands/dispute.ts +0 -375
  289. package/src/commands/doctor.ts +0 -172
  290. package/src/commands/endpoint.ts +0 -620
  291. package/src/commands/feed.ts +0 -229
  292. package/src/commands/hire.ts +0 -245
  293. package/src/commands/migrate.ts +0 -177
  294. package/src/commands/negotiate.ts +0 -272
  295. package/src/commands/openshell.ts +0 -1055
  296. package/src/commands/owner.ts +0 -35
  297. package/src/commands/policy.ts +0 -263
  298. package/src/commands/relay.ts +0 -277
  299. package/src/commands/remediate.ts +0 -24
  300. package/src/commands/reputation.ts +0 -79
  301. package/src/commands/setup.ts +0 -343
  302. package/src/commands/trust.ts +0 -27
  303. package/src/commands/verify.ts +0 -91
  304. package/src/commands/wallet.ts +0 -3548
  305. package/src/commands/watch.ts +0 -220
  306. package/src/commands/watchtower.ts +0 -248
  307. package/src/commands/workroom.ts +0 -963
  308. package/src/config.ts +0 -220
  309. package/src/daemon/config.ts +0 -344
  310. package/src/daemon/hire-listener.ts +0 -226
  311. package/src/daemon/index.ts +0 -1089
  312. package/src/daemon/job-lifecycle.ts +0 -215
  313. package/src/daemon/notify.ts +0 -297
  314. package/src/daemon/token-metering.ts +0 -183
  315. package/src/daemon/userops.ts +0 -119
  316. package/src/daemon/wallet-monitor.ts +0 -90
  317. package/src/drain-v4.ts +0 -159
  318. package/src/endpoint-config.ts +0 -83
  319. package/src/endpoint-notify.ts +0 -134
  320. package/src/index.ts +0 -74
  321. package/src/openshell-runtime.ts +0 -281
  322. package/src/program.ts +0 -88
  323. package/src/repl.ts +0 -178
  324. package/src/signing.ts +0 -28
  325. package/src/telegram-notify.ts +0 -88
  326. package/src/tui/App.tsx +0 -263
  327. package/src/tui/Footer.tsx +0 -18
  328. package/src/tui/Header.tsx +0 -45
  329. package/src/tui/InputLine.tsx +0 -243
  330. package/src/tui/Viewport.tsx +0 -51
  331. package/src/tui/WalletConnectPairing.tsx +0 -114
  332. package/src/tui/components/Button.tsx +0 -38
  333. package/src/tui/components/CeremonyView.tsx +0 -39
  334. package/src/tui/components/CompletionDropdown.tsx +0 -56
  335. package/src/tui/components/ConfirmPrompt.tsx +0 -36
  336. package/src/tui/components/CustomTextInput.tsx +0 -132
  337. package/src/tui/components/InteractiveTable.tsx +0 -106
  338. package/src/tui/components/StepSpinner.tsx +0 -84
  339. package/src/tui/components/Toast.tsx +0 -59
  340. package/src/tui/index.tsx +0 -90
  341. package/src/tui/useChat.ts +0 -103
  342. package/src/tui/useCommand.ts +0 -238
  343. package/src/tui/useNotifications.ts +0 -28
  344. package/src/tui/useScroll.ts +0 -69
  345. package/src/ui/banner.ts +0 -78
  346. package/src/ui/colors.ts +0 -30
  347. package/src/ui/format.ts +0 -78
  348. package/src/ui/qr-render.ts +0 -92
  349. package/src/ui/rpc-fallback.ts +0 -59
  350. package/src/ui/spinner.ts +0 -56
  351. package/src/ui/tree.ts +0 -16
  352. package/src/utils/format.ts +0 -48
  353. package/src/utils/hash.ts +0 -5
  354. package/src/utils/time.ts +0 -15
  355. package/src/wallet-router.ts +0 -178
  356. package/src/walletconnect-session.ts +0 -27
  357. package/src/walletconnect.ts +0 -309
  358. package/test/time.test.js +0 -11
  359. 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
- }