arc402-cli 1.0.0-rc.1 → 1.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 (257) hide show
  1. package/README.md +43 -2
  2. package/dist/abis.d.ts +1 -0
  3. package/dist/abis.d.ts.map +1 -1
  4. package/dist/abis.js +29 -1
  5. package/dist/abis.js.map +1 -1
  6. package/dist/commands/backup.d.ts +3 -0
  7. package/dist/commands/backup.d.ts.map +1 -0
  8. package/dist/commands/backup.js +106 -0
  9. package/dist/commands/backup.js.map +1 -0
  10. package/dist/commands/compute.d.ts +14 -0
  11. package/dist/commands/compute.d.ts.map +1 -0
  12. package/dist/commands/compute.js +466 -0
  13. package/dist/commands/compute.js.map +1 -0
  14. package/dist/commands/config.d.ts.map +1 -1
  15. package/dist/commands/config.js +11 -1
  16. package/dist/commands/config.js.map +1 -1
  17. package/dist/commands/daemon.d.ts.map +1 -1
  18. package/dist/commands/daemon.js +67 -0
  19. package/dist/commands/daemon.js.map +1 -1
  20. package/dist/commands/discover.d.ts.map +1 -1
  21. package/dist/commands/discover.js +60 -15
  22. package/dist/commands/discover.js.map +1 -1
  23. package/dist/commands/doctor.d.ts +3 -0
  24. package/dist/commands/doctor.d.ts.map +1 -0
  25. package/dist/commands/doctor.js +205 -0
  26. package/dist/commands/doctor.js.map +1 -0
  27. package/dist/commands/tunnel.d.ts +3 -0
  28. package/dist/commands/tunnel.d.ts.map +1 -0
  29. package/dist/commands/tunnel.js +281 -0
  30. package/dist/commands/tunnel.js.map +1 -0
  31. package/dist/commands/wallet.d.ts.map +1 -1
  32. package/dist/commands/wallet.js +299 -65
  33. package/dist/commands/wallet.js.map +1 -1
  34. package/dist/commands/watch.d.ts.map +1 -1
  35. package/dist/commands/watch.js +146 -9
  36. package/dist/commands/watch.js.map +1 -1
  37. package/dist/commands/workroom.d.ts.map +1 -1
  38. package/dist/commands/workroom.js +112 -6
  39. package/dist/commands/workroom.js.map +1 -1
  40. package/dist/config.d.ts +13 -0
  41. package/dist/config.d.ts.map +1 -1
  42. package/dist/config.js +41 -4
  43. package/dist/config.js.map +1 -1
  44. package/dist/daemon/compute-metering.d.ts +61 -0
  45. package/dist/daemon/compute-metering.d.ts.map +1 -0
  46. package/dist/daemon/compute-metering.js +299 -0
  47. package/dist/daemon/compute-metering.js.map +1 -0
  48. package/dist/daemon/compute-session.d.ts +100 -0
  49. package/dist/daemon/compute-session.d.ts.map +1 -0
  50. package/dist/daemon/compute-session.js +231 -0
  51. package/dist/daemon/compute-session.js.map +1 -0
  52. package/dist/daemon/config.d.ts +33 -1
  53. package/dist/daemon/config.d.ts.map +1 -1
  54. package/dist/daemon/config.js +69 -0
  55. package/dist/daemon/config.js.map +1 -1
  56. package/dist/daemon/credentials.d.ts +24 -0
  57. package/dist/daemon/credentials.d.ts.map +1 -0
  58. package/dist/daemon/credentials.js +80 -0
  59. package/dist/daemon/credentials.js.map +1 -0
  60. package/dist/daemon/delivery-client.d.ts +35 -0
  61. package/dist/daemon/delivery-client.d.ts.map +1 -0
  62. package/dist/daemon/delivery-client.js +231 -0
  63. package/dist/daemon/delivery-client.js.map +1 -0
  64. package/dist/daemon/file-delivery.d.ts +98 -0
  65. package/dist/daemon/file-delivery.d.ts.map +1 -0
  66. package/dist/daemon/file-delivery.js +461 -0
  67. package/dist/daemon/file-delivery.js.map +1 -0
  68. package/dist/daemon/index.d.ts +1 -0
  69. package/dist/daemon/index.d.ts.map +1 -1
  70. package/dist/daemon/index.js +793 -227
  71. package/dist/daemon/index.js.map +1 -1
  72. package/dist/daemon/notify.d.ts +35 -6
  73. package/dist/daemon/notify.d.ts.map +1 -1
  74. package/dist/daemon/notify.js +176 -48
  75. package/dist/daemon/notify.js.map +1 -1
  76. package/dist/daemon/worker-executor.d.ts +71 -0
  77. package/dist/daemon/worker-executor.d.ts.map +1 -0
  78. package/dist/daemon/worker-executor.js +382 -0
  79. package/dist/daemon/worker-executor.js.map +1 -0
  80. package/dist/drain-v4.js +2 -2
  81. package/dist/drain-v4.js.map +1 -1
  82. package/dist/endpoint-notify.d.ts +9 -1
  83. package/dist/endpoint-notify.d.ts.map +1 -1
  84. package/dist/endpoint-notify.js +116 -3
  85. package/dist/endpoint-notify.js.map +1 -1
  86. package/dist/index.js +81 -1
  87. package/dist/index.js.map +1 -1
  88. package/dist/program.d.ts.map +1 -1
  89. package/dist/program.js +8 -0
  90. package/dist/program.js.map +1 -1
  91. package/dist/repl.d.ts.map +1 -1
  92. package/dist/repl.js +69 -486
  93. package/dist/repl.js.map +1 -1
  94. package/dist/tui/App.d.ts +12 -0
  95. package/dist/tui/App.d.ts.map +1 -0
  96. package/dist/tui/App.js +154 -0
  97. package/dist/tui/App.js.map +1 -0
  98. package/dist/tui/Footer.d.ts +11 -0
  99. package/dist/tui/Footer.d.ts.map +1 -0
  100. package/dist/tui/Footer.js +13 -0
  101. package/dist/tui/Footer.js.map +1 -0
  102. package/dist/tui/Header.d.ts +14 -0
  103. package/dist/tui/Header.d.ts.map +1 -0
  104. package/dist/tui/Header.js +19 -0
  105. package/dist/tui/Header.js.map +1 -0
  106. package/dist/tui/InputLine.d.ts +11 -0
  107. package/dist/tui/InputLine.d.ts.map +1 -0
  108. package/dist/tui/InputLine.js +145 -0
  109. package/dist/tui/InputLine.js.map +1 -0
  110. package/dist/tui/Viewport.d.ts +14 -0
  111. package/dist/tui/Viewport.d.ts.map +1 -0
  112. package/dist/tui/Viewport.js +48 -0
  113. package/dist/tui/Viewport.js.map +1 -0
  114. package/dist/tui/WalletConnectPairing.d.ts +23 -0
  115. package/dist/tui/WalletConnectPairing.d.ts.map +1 -0
  116. package/dist/tui/WalletConnectPairing.js +61 -0
  117. package/dist/tui/WalletConnectPairing.js.map +1 -0
  118. package/dist/tui/components/Button.d.ts +7 -0
  119. package/dist/tui/components/Button.d.ts.map +1 -0
  120. package/dist/tui/components/Button.js +21 -0
  121. package/dist/tui/components/Button.js.map +1 -0
  122. package/dist/tui/components/CeremonyView.d.ts +13 -0
  123. package/dist/tui/components/CeremonyView.d.ts.map +1 -0
  124. package/dist/tui/components/CeremonyView.js +10 -0
  125. package/dist/tui/components/CeremonyView.js.map +1 -0
  126. package/dist/tui/components/CompletionDropdown.d.ts +7 -0
  127. package/dist/tui/components/CompletionDropdown.d.ts.map +1 -0
  128. package/dist/tui/components/CompletionDropdown.js +23 -0
  129. package/dist/tui/components/CompletionDropdown.js.map +1 -0
  130. package/dist/tui/components/ConfirmPrompt.d.ts +9 -0
  131. package/dist/tui/components/ConfirmPrompt.d.ts.map +1 -0
  132. package/dist/tui/components/ConfirmPrompt.js +10 -0
  133. package/dist/tui/components/ConfirmPrompt.js.map +1 -0
  134. package/dist/tui/components/CustomTextInput.d.ts +15 -0
  135. package/dist/tui/components/CustomTextInput.d.ts.map +1 -0
  136. package/dist/tui/components/CustomTextInput.js +99 -0
  137. package/dist/tui/components/CustomTextInput.js.map +1 -0
  138. package/dist/tui/components/InteractiveTable.d.ts +14 -0
  139. package/dist/tui/components/InteractiveTable.d.ts.map +1 -0
  140. package/dist/tui/components/InteractiveTable.js +61 -0
  141. package/dist/tui/components/InteractiveTable.js.map +1 -0
  142. package/dist/tui/components/StepSpinner.d.ts +11 -0
  143. package/dist/tui/components/StepSpinner.d.ts.map +1 -0
  144. package/dist/tui/components/StepSpinner.js +32 -0
  145. package/dist/tui/components/StepSpinner.js.map +1 -0
  146. package/dist/tui/components/Toast.d.ts +18 -0
  147. package/dist/tui/components/Toast.d.ts.map +1 -0
  148. package/dist/tui/components/Toast.js +29 -0
  149. package/dist/tui/components/Toast.js.map +1 -0
  150. package/dist/tui/index.d.ts +2 -0
  151. package/dist/tui/index.d.ts.map +1 -0
  152. package/dist/tui/index.js +55 -0
  153. package/dist/tui/index.js.map +1 -0
  154. package/dist/tui/useChat.d.ts +11 -0
  155. package/dist/tui/useChat.d.ts.map +1 -0
  156. package/dist/tui/useChat.js +91 -0
  157. package/dist/tui/useChat.js.map +1 -0
  158. package/dist/tui/useCommand.d.ts +12 -0
  159. package/dist/tui/useCommand.d.ts.map +1 -0
  160. package/dist/tui/useCommand.js +137 -0
  161. package/dist/tui/useCommand.js.map +1 -0
  162. package/dist/tui/useNotifications.d.ts +9 -0
  163. package/dist/tui/useNotifications.d.ts.map +1 -0
  164. package/dist/tui/useNotifications.js +17 -0
  165. package/dist/tui/useNotifications.js.map +1 -0
  166. package/dist/tui/useScroll.d.ts +17 -0
  167. package/dist/tui/useScroll.d.ts.map +1 -0
  168. package/dist/tui/useScroll.js +46 -0
  169. package/dist/tui/useScroll.js.map +1 -0
  170. package/dist/ui/format.d.ts.map +1 -1
  171. package/dist/ui/format.js +2 -0
  172. package/dist/ui/format.js.map +1 -1
  173. package/dist/ui/qr-render.d.ts +25 -0
  174. package/dist/ui/qr-render.d.ts.map +1 -0
  175. package/dist/ui/qr-render.js +90 -0
  176. package/dist/ui/qr-render.js.map +1 -0
  177. package/dist/ui/rpc-fallback.d.ts +11 -0
  178. package/dist/ui/rpc-fallback.d.ts.map +1 -0
  179. package/dist/ui/rpc-fallback.js +58 -0
  180. package/dist/ui/rpc-fallback.js.map +1 -0
  181. package/dist/walletconnect.d.ts +4 -0
  182. package/dist/walletconnect.d.ts.map +1 -1
  183. package/dist/walletconnect.js.map +1 -1
  184. package/package.json +11 -3
  185. package/scripts/authorize-machine-key.ts +0 -43
  186. package/scripts/drain-wallet.ts +0 -149
  187. package/scripts/execute-spend-only.ts +0 -81
  188. package/scripts/register-agent-userop.ts +0 -186
  189. package/src/abis.ts +0 -187
  190. package/src/bundler.ts +0 -235
  191. package/src/client.ts +0 -36
  192. package/src/coinbase-smart-wallet.ts +0 -51
  193. package/src/commands/accept.ts +0 -64
  194. package/src/commands/agent-handshake.ts +0 -72
  195. package/src/commands/agent.ts +0 -691
  196. package/src/commands/agreements.ts +0 -350
  197. package/src/commands/arbitrator.ts +0 -180
  198. package/src/commands/arena-handshake.ts +0 -257
  199. package/src/commands/arena.ts +0 -122
  200. package/src/commands/cancel.ts +0 -35
  201. package/src/commands/channel.ts +0 -218
  202. package/src/commands/coldstart.ts +0 -165
  203. package/src/commands/config.ts +0 -58
  204. package/src/commands/contract-interaction.ts +0 -166
  205. package/src/commands/daemon.ts +0 -978
  206. package/src/commands/deliver.ts +0 -148
  207. package/src/commands/discover.ts +0 -297
  208. package/src/commands/dispute.ts +0 -375
  209. package/src/commands/endpoint.ts +0 -620
  210. package/src/commands/feed.ts +0 -229
  211. package/src/commands/hire.ts +0 -245
  212. package/src/commands/migrate.ts +0 -177
  213. package/src/commands/negotiate.ts +0 -271
  214. package/src/commands/openshell.ts +0 -1055
  215. package/src/commands/owner.ts +0 -35
  216. package/src/commands/policy.ts +0 -263
  217. package/src/commands/relay.ts +0 -273
  218. package/src/commands/remediate.ts +0 -24
  219. package/src/commands/reputation.ts +0 -79
  220. package/src/commands/setup.ts +0 -343
  221. package/src/commands/trust.ts +0 -27
  222. package/src/commands/verify.ts +0 -91
  223. package/src/commands/wallet.ts +0 -3280
  224. package/src/commands/watch.ts +0 -23
  225. package/src/commands/watchtower.ts +0 -248
  226. package/src/commands/workroom.ts +0 -959
  227. package/src/config.ts +0 -174
  228. package/src/daemon/config.ts +0 -308
  229. package/src/daemon/hire-listener.ts +0 -226
  230. package/src/daemon/index.ts +0 -955
  231. package/src/daemon/job-lifecycle.ts +0 -215
  232. package/src/daemon/notify.ts +0 -157
  233. package/src/daemon/token-metering.ts +0 -183
  234. package/src/daemon/userops.ts +0 -119
  235. package/src/daemon/wallet-monitor.ts +0 -90
  236. package/src/drain-v4.ts +0 -159
  237. package/src/endpoint-config.ts +0 -83
  238. package/src/endpoint-notify.ts +0 -46
  239. package/src/index.ts +0 -26
  240. package/src/openshell-runtime.ts +0 -277
  241. package/src/program.ts +0 -83
  242. package/src/repl.ts +0 -680
  243. package/src/signing.ts +0 -28
  244. package/src/telegram-notify.ts +0 -88
  245. package/src/ui/banner.ts +0 -51
  246. package/src/ui/colors.ts +0 -30
  247. package/src/ui/format.ts +0 -77
  248. package/src/ui/spinner.ts +0 -56
  249. package/src/ui/tree.ts +0 -16
  250. package/src/utils/format.ts +0 -48
  251. package/src/utils/hash.ts +0 -5
  252. package/src/utils/time.ts +0 -15
  253. package/src/wallet-router.ts +0 -178
  254. package/src/walletconnect-session.ts +0 -27
  255. package/src/walletconnect.ts +0 -294
  256. package/test/time.test.js +0 -11
  257. package/tsconfig.json +0 -19
@@ -1,88 +0,0 @@
1
- import * as https from "https";
2
-
3
- /** Generic Telegram message sender. Fire-and-forget — swallows errors. */
4
- export async function sendTelegramMessage(opts: {
5
- botToken: string;
6
- chatId: string;
7
- threadId?: number;
8
- text: string;
9
- buttons?: { text: string; url?: string; callback_data?: string }[][];
10
- }): Promise<void> {
11
- const body: Record<string, unknown> = {
12
- chat_id: opts.chatId,
13
- text: opts.text,
14
- };
15
- if (opts.threadId !== undefined) body.message_thread_id = opts.threadId;
16
- if (opts.buttons && opts.buttons.length > 0) {
17
- body.reply_markup = { inline_keyboard: opts.buttons };
18
- }
19
-
20
- const payload = JSON.stringify(body);
21
- await new Promise<void>((resolve) => {
22
- try {
23
- const req = https.request(
24
- {
25
- hostname: "api.telegram.org",
26
- path: `/bot${opts.botToken}/sendMessage`,
27
- method: "POST",
28
- headers: {
29
- "Content-Type": "application/json",
30
- "Content-Length": Buffer.byteLength(payload),
31
- },
32
- },
33
- (res) => { res.resume(); resolve(); }
34
- );
35
- req.on("error", () => resolve());
36
- req.write(payload);
37
- req.end();
38
- } catch {
39
- resolve();
40
- }
41
- });
42
- }
43
-
44
- export async function sendWalletConnectApprovalButton(opts: {
45
- botToken: string;
46
- chatId: string;
47
- threadId?: number;
48
- prompt: string;
49
- walletLinks: { label: string; url: string }[];
50
- }): Promise<void> {
51
- const body: Record<string, unknown> = {
52
- chat_id: opts.chatId,
53
- text: opts.prompt,
54
- reply_markup: {
55
- inline_keyboard: [opts.walletLinks.map((link) => ({ text: link.label, url: link.url }))],
56
- },
57
- };
58
- if (opts.threadId !== undefined) {
59
- body.message_thread_id = opts.threadId;
60
- }
61
-
62
- const payload = JSON.stringify(body);
63
-
64
- await new Promise<void>((resolve) => {
65
- try {
66
- const req = https.request(
67
- {
68
- hostname: "api.telegram.org",
69
- path: `/bot${opts.botToken}/sendMessage`,
70
- method: "POST",
71
- headers: {
72
- "Content-Type": "application/json",
73
- "Content-Length": Buffer.byteLength(payload),
74
- },
75
- },
76
- (res) => {
77
- res.resume(); // drain response body
78
- resolve();
79
- }
80
- );
81
- req.on("error", () => resolve());
82
- req.write(payload);
83
- req.end();
84
- } catch {
85
- resolve();
86
- }
87
- });
88
- }
package/src/ui/banner.ts DELETED
@@ -1,51 +0,0 @@
1
- import chalk from "chalk";
2
-
3
- // eslint-disable-next-line @typescript-eslint/no-var-requires
4
- const _pkg = require("../../package.json") as { version: string };
5
-
6
- const ART = `
7
- ██████╗ ██████╗ ██████╗ ██╗ ██╗ ██████╗ ██████╗
8
- ██╔══██╗██╔══██╗██╔════╝ ██║ ██║██╔═══██╗╚════██╗
9
- ███████║██████╔╝██║ █████╗███████║██║ ██║ █████╔╝
10
- ██╔══██║██╔══██╗██║ ╚════╝╚════██║██║ ██║██╔═══╝
11
- ██║ ██║██║ ██║╚██████╗ ██║╚██████╔╝███████╗
12
- ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═════╝ ╚══════╝`;
13
-
14
- const SEPARATOR = chalk.cyanBright("◈") + " " + chalk.dim("─".repeat(45));
15
-
16
- export interface BannerConfig {
17
- network?: string;
18
- wallet?: string;
19
- balance?: string;
20
- }
21
-
22
- /** Returns banner as an array of plain lines (no trailing newlines). */
23
- export function getBannerLines(config?: BannerConfig): string[] {
24
- const lines: string[] = [];
25
- // ART has a leading newline — skip it
26
- for (const l of ART.split("\n").slice(1)) {
27
- lines.push(chalk.cyan(l));
28
- }
29
- lines.push("");
30
- lines.push(" " + chalk.dim(`agent-to-agent arcing · v${_pkg.version}`));
31
- lines.push(" " + SEPARATOR);
32
- if (config) {
33
- lines.push("");
34
- if (config.network)
35
- lines.push(` ${chalk.dim("Network")} ${chalk.white(config.network)}`);
36
- if (config.wallet)
37
- lines.push(` ${chalk.dim("Wallet")} ${chalk.white(config.wallet)}`);
38
- if (config.balance)
39
- lines.push(` ${chalk.dim("Balance")} ${chalk.white(config.balance)}`);
40
- }
41
- lines.push("");
42
- lines.push(` ${chalk.dim("Type 'help' to get started")}`);
43
- lines.push("");
44
- return lines;
45
- }
46
-
47
- export function renderBanner(config?: BannerConfig): void {
48
- for (const line of getBannerLines(config)) {
49
- console.log(line);
50
- }
51
- }
package/src/ui/colors.ts DELETED
@@ -1,30 +0,0 @@
1
- import chalk from "chalk";
2
-
3
- // ─── ARC-402 Color System ─────────────────────────────────────────────────────
4
-
5
- export const c = {
6
- // Protocol mark + section headings
7
- cyan: chalk.cyan,
8
- brightCyan: chalk.cyanBright,
9
-
10
- // Primary content, values
11
- white: chalk.white,
12
-
13
- // Secondary info — addresses, timestamps, labels
14
- dim: chalk.dim,
15
-
16
- // Success states, fulfilled agreements
17
- green: chalk.green,
18
-
19
- // Errors, disputes, failures
20
- red: chalk.red,
21
-
22
- // Warnings, pending states, unconfirmed
23
- yellow: chalk.yellow,
24
-
25
- // Symbols
26
- mark: chalk.cyanBright("◈"),
27
- success: chalk.green("✓"),
28
- failure: chalk.red("✗"),
29
- warning: chalk.yellow("⚠"),
30
- };
package/src/ui/format.ts DELETED
@@ -1,77 +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 < 60) return "just now";
46
- if (delta < 3600) {
47
- const m = Math.floor(delta / 60);
48
- return `${m}m ago`;
49
- }
50
- if (delta < 86400) {
51
- const h = Math.floor(delta / 3600);
52
- return `${h}h ago`;
53
- }
54
- const d = Math.floor(delta / 86400);
55
- return `${d}d ago`;
56
- }
57
-
58
- /**
59
- * Format seconds-until-expiry as "61h 14m" or "2d 3h".
60
- */
61
- export function formatDuration(seconds: number): string {
62
- if (seconds <= 0) return "expired";
63
- const d = Math.floor(seconds / 86400);
64
- const h = Math.floor((seconds % 86400) / 3600);
65
- const m = Math.floor((seconds % 3600) / 60);
66
-
67
- if (d > 0) return h > 0 ? `${d}d ${h}h` : `${d}d`;
68
- if (h > 0) return m > 0 ? `${h}h ${m}m` : `${h}h`;
69
- return `${m}m`;
70
- }
71
-
72
- /**
73
- * Format a unix timestamp (seconds) as a locale date/time string.
74
- */
75
- export function formatTimestamp(timestampSeconds: number): string {
76
- return new Date(timestampSeconds * 1000).toLocaleString();
77
- }
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";
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";
3
- import { ARC402_WALLET_EXECUTE_ABI } from "./abis";
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";
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
- }