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
@@ -1,274 +0,0 @@
1
- import { Command } from "commander";
2
- import { ethers } from "ethers";
3
- import { loadConfig, getUsdcAddress } from "../config.js";
4
- import { requireSigner } from "../client.js";
5
- import { AGENT_REGISTRY_ABI } from "../abis.js";
6
- import { startSpinner } from "../ui/spinner.js";
7
- import { renderTree } from "../ui/tree.js";
8
- import { c } from "../ui/colors.js";
9
-
10
- const DEFAULT_REGISTRY_ADDRESS = "0xD5c2851B00090c92Ba7F4723FB548bb30C9B6865";
11
-
12
- async function pingHandshakeEndpoint(
13
- agentAddress: string,
14
- payload: Record<string, unknown>,
15
- registryAddress: string,
16
- provider: ethers.Provider
17
- ): Promise<void> {
18
- const registry = new ethers.Contract(registryAddress, AGENT_REGISTRY_ABI, provider);
19
- const agentData = await registry.getAgent(agentAddress);
20
- const endpoint = agentData.endpoint as string;
21
- if (!endpoint) return;
22
- await fetch(`${endpoint}/handshake`, {
23
- method: "POST",
24
- headers: { "Content-Type": "application/json" },
25
- body: JSON.stringify(payload),
26
- });
27
- }
28
-
29
- // ─── Handshake Contract ABI (from Handshake.sol) ─────────────────────────────
30
-
31
- const HANDSHAKE_ABI = [
32
- "function sendHandshake(address to, uint8 hsType, string note) payable",
33
- "function sendHandshakeWithToken(address to, uint8 hsType, string note, address token, uint256 tokenAmount)",
34
- "function sendBatch(address[] recipients, uint8[] hsTypes, string[] notes)",
35
- "function hasConnection(address from, address to) view returns (bool)",
36
- "function isMutual(address a, address b) view returns (bool)",
37
- "function getStats(address agent) view returns (uint256 sent, uint256 received, uint256 uniqueInbound)",
38
- "function sentCount(address) view returns (uint256)",
39
- "function receivedCount(address) view returns (uint256)",
40
- "function uniqueSenders(address) view returns (uint256)",
41
- "function totalHandshakes() view returns (uint256)",
42
- "function allowedTokens(address) view returns (bool)",
43
- "event HandshakeSent(uint256 indexed handshakeId, address indexed from, address indexed to, uint8 hsType, address token, uint256 amount, string note, uint256 timestamp)",
44
- "event NewConnection(address indexed from, address indexed to, uint256 handshakeId)",
45
- ];
46
-
47
- const POLICY_ENGINE_ABI = [
48
- "function isContractWhitelisted(address wallet, address target) view returns (bool)",
49
- "function whitelistContract(address wallet, address target)",
50
- ];
51
-
52
- const HANDSHAKE_TYPES: Record<string, number> = {
53
- respect: 0,
54
- curiosity: 1,
55
- endorsement: 2,
56
- thanks: 3,
57
- collaboration: 4,
58
- challenge: 5,
59
- referral: 6,
60
- hello: 7,
61
- };
62
-
63
- // ─── Auto-Whitelist ──────────────────────────────────────────────────────────
64
-
65
- async function ensureWhitelisted(
66
- signer: ethers.Signer,
67
- provider: ethers.Provider,
68
- walletAddress: string,
69
- policyEngineAddress: string,
70
- handshakeAddress: string
71
- ): Promise<void> {
72
- // Check whitelist with RPC fallback (public RPCs often fail on eth_call)
73
- const { callWithFallback } = await import("../ui/rpc-fallback.js");
74
- const rpcUrl = (provider as ethers.JsonRpcProvider)._getConnection?.()?.url ?? "https://mainnet.base.org";
75
- const isWhitelisted = await callWithFallback(rpcUrl, async (p) => {
76
- const pe = new ethers.Contract(policyEngineAddress, POLICY_ENGINE_ABI, p);
77
- return await pe.isContractWhitelisted(walletAddress, handshakeAddress) as boolean;
78
- }).catch(() => true); // If all RPCs fail, assume whitelisted and let the tx itself fail if not
79
-
80
- if (!isWhitelisted) {
81
- console.log("Handshake contract not yet whitelisted on your wallet.");
82
- console.log("Whitelisting now (one-time setup)...");
83
- try {
84
- const peSigner = new ethers.Contract(policyEngineAddress, POLICY_ENGINE_ABI, signer);
85
- const tx = await peSigner.whitelistContract(walletAddress, handshakeAddress);
86
- console.log(` tx: ${tx.hash}`);
87
- await tx.wait();
88
- console.log(" ✓ Handshake contract whitelisted\n");
89
- } catch (e) {
90
- const msg = e instanceof Error ? e.message : String(e);
91
- if (msg.includes("already whitelisted")) {
92
- console.log(" ✓ Handshake contract already whitelisted\n");
93
- } else if (msg.includes("insufficient funds")) {
94
- console.log(" ⚠ Machine key has no ETH for whitelisting. Use WalletConnect:");
95
- console.log(` arc402 wallet whitelist-contract ${handshakeAddress}\n`);
96
- return;
97
- } else {
98
- throw e;
99
- }
100
- }
101
- }
102
- }
103
-
104
- // ─── Commands ────────────────────────────────────────────────────────────────
105
-
106
- export function registerArenaHandshakeCommands(program: Command): void {
107
- const hs = program
108
- .command("shake")
109
- .description("ARC Arena social handshake — send a typed trust signal to another agent.");
110
-
111
- // ── send ──────────────────────────────────────────────────────────────────
112
- hs.command("send <agentAddress>")
113
- .description("Send a handshake to another agent.")
114
- .option("--type <type>", "Handshake type: respect, curiosity, endorsement, thanks, collaboration, challenge, referral, hello", "hello")
115
- .option("--note <note>", "Short message (max 280 chars)", "")
116
- .option("--tip <amount>", "ETH tip to attach (e.g. 0.01)")
117
- .option("--usdc <amount>", "USDC tip to attach (e.g. 5.00)")
118
- .option("--json", "Output as JSON")
119
- .action(async (agentAddress: string, opts) => {
120
- const config = loadConfig();
121
- const { signer, provider } = await requireSigner(config);
122
- const myAddress = await signer.getAddress();
123
-
124
- if (!config.handshakeAddress) {
125
- console.error("handshakeAddress not configured. Run: arc402 config set handshakeAddress <address>");
126
- process.exit(1);
127
- }
128
- if (!config.policyEngineAddress) {
129
- console.error("policyEngineAddress not configured.");
130
- process.exit(1);
131
- }
132
-
133
- // Auto-whitelist check
134
- await ensureWhitelisted(signer, provider, myAddress, config.policyEngineAddress, config.handshakeAddress);
135
-
136
- const hsType = HANDSHAKE_TYPES[opts.type.toLowerCase()];
137
- if (hsType === undefined) {
138
- console.error(`Unknown handshake type: ${opts.type}`);
139
- console.error(`Valid types: ${Object.keys(HANDSHAKE_TYPES).join(", ")}`);
140
- process.exit(1);
141
- }
142
-
143
- const handshake = new ethers.Contract(config.handshakeAddress, HANDSHAKE_ABI, signer);
144
-
145
- const hsSpinner = startSpinner(`Sending ${opts.type} handshake...`);
146
- let tx;
147
- if (opts.usdc) {
148
- // USDC handshake
149
- const usdcAddress = getUsdcAddress(config);
150
- const amount = ethers.parseUnits(opts.usdc, 6);
151
- tx = await handshake.sendHandshakeWithToken(agentAddress, hsType, opts.note, usdcAddress, amount);
152
- } else {
153
- // ETH handshake (with optional tip)
154
- const value = opts.tip ? ethers.parseEther(opts.tip) : 0n;
155
- tx = await handshake.sendHandshake(agentAddress, hsType, opts.note, { value });
156
- }
157
- hsSpinner.succeed("Handshake sent");
158
-
159
- // Notify recipient's HTTP endpoint (non-blocking)
160
- const registryAddress = config.agentRegistryV2Address ?? config.agentRegistryAddress ?? DEFAULT_REGISTRY_ADDRESS;
161
- try {
162
- await pingHandshakeEndpoint(
163
- agentAddress,
164
- { from: myAddress, type: opts.type, note: opts.note, txHash: tx.hash },
165
- registryAddress,
166
- provider
167
- );
168
- } catch (err) {
169
- console.warn(`Warning: could not notify recipient endpoint: ${err instanceof Error ? err.message : String(err)}`);
170
- }
171
-
172
- if (opts.json) {
173
- console.log(JSON.stringify({ tx: tx.hash, from: myAddress, to: agentAddress, type: opts.type, note: opts.note }));
174
- } else {
175
- const treeItems = [
176
- { label: "From", value: myAddress },
177
- { label: "To", value: agentAddress },
178
- { label: "Type", value: opts.type },
179
- ...(opts.note ? [{ label: "Note", value: opts.note as string }] : []),
180
- ...(opts.tip ? [{ label: "Tip", value: `${opts.tip as string} ETH` }] : []),
181
- ...(opts.usdc ? [{ label: "Tip", value: `${opts.usdc as string} USDC` }] : []),
182
- { label: "Tx", value: tx.hash as string, last: true },
183
- ];
184
- renderTree(treeItems);
185
- }
186
- });
187
-
188
- // ── batch ─────────────────────────────────────────────────────────────────
189
- hs.command("batch")
190
- .description("Send handshakes to multiple agents at once (onboarding ritual).")
191
- .argument("<agents...>", "Agent addresses to handshake (up to 10)")
192
- .option("--type <type>", "Handshake type for all", "hello")
193
- .option("--note <note>", "Note for all", "")
194
- .action(async (agents: string[], opts) => {
195
- const config = loadConfig();
196
- const { signer, provider } = await requireSigner(config);
197
- const myAddress = await signer.getAddress();
198
-
199
- if (!config.handshakeAddress || !config.policyEngineAddress) {
200
- console.error("handshakeAddress or policyEngineAddress not configured.");
201
- process.exit(1);
202
- }
203
-
204
- await ensureWhitelisted(signer, provider, myAddress, config.policyEngineAddress, config.handshakeAddress);
205
-
206
- const hsType = HANDSHAKE_TYPES[opts.type.toLowerCase()];
207
- if (hsType === undefined) {
208
- console.error(`Unknown type: ${opts.type}. Valid: ${Object.keys(HANDSHAKE_TYPES).join(", ")}`);
209
- process.exit(1);
210
- }
211
-
212
- if (agents.length > 10) {
213
- console.error("Max 10 agents per batch.");
214
- process.exit(1);
215
- }
216
-
217
- const handshake = new ethers.Contract(config.handshakeAddress, HANDSHAKE_ABI, signer);
218
- const types = agents.map(() => hsType);
219
- const notes = agents.map(() => opts.note);
220
-
221
- const tx = await handshake.sendBatch(agents, types, notes);
222
- console.log(`✓ Batch handshake sent to ${agents.length} agents`);
223
- agents.forEach(a => console.log(` → ${a}`));
224
- console.log(` tx: ${tx.hash}`);
225
- });
226
-
227
- // ── stats ─────────────────────────────────────────────────────────────────
228
- hs.command("stats [address]")
229
- .description("View handshake stats for an agent.")
230
- .action(async (address?: string) => {
231
- const config = loadConfig();
232
- const { signer, provider } = await requireSigner(config);
233
- const target = address || await signer.getAddress();
234
-
235
- if (!config.handshakeAddress) {
236
- console.error("handshakeAddress not configured.");
237
- process.exit(1);
238
- }
239
-
240
- const handshake = new ethers.Contract(config.handshakeAddress, HANDSHAKE_ABI, provider);
241
- const [sent, received, unique] = await handshake.getStats(target);
242
- const total = await handshake.totalHandshakes();
243
-
244
- console.log(`Handshake Stats: ${target}`);
245
- console.log(` Sent: ${sent}`);
246
- console.log(` Received: ${received}`);
247
- console.log(` Unique senders: ${unique}`);
248
- console.log(` Network total: ${total}`);
249
- });
250
-
251
- // ── check ─────────────────────────────────────────────────────────────────
252
- hs.command("check <agentAddress>")
253
- .description("Check if a connection or mutual handshake exists with an agent.")
254
- .action(async (agentAddress: string) => {
255
- const config = loadConfig();
256
- const { signer, provider } = await requireSigner(config);
257
- const myAddress = await signer.getAddress();
258
-
259
- if (!config.handshakeAddress) {
260
- console.error("handshakeAddress not configured.");
261
- process.exit(1);
262
- }
263
-
264
- const handshake = new ethers.Contract(config.handshakeAddress, HANDSHAKE_ABI, provider);
265
- const iSent = await handshake.hasConnection(myAddress, agentAddress);
266
- const theySent = await handshake.hasConnection(agentAddress, myAddress);
267
- const mutual = await handshake.isMutual(myAddress, agentAddress);
268
-
269
- console.log(`Connection: ${myAddress} ↔ ${agentAddress}`);
270
- console.log(` You → them: ${iSent ? "✓ handshaked" : "✗ no handshake"}`);
271
- console.log(` Them → you: ${theySent ? "✓ handshaked" : "✗ no handshake"}`);
272
- console.log(` Mutual: ${mutual ? "✓ yes" : "✗ no"}`);
273
- });
274
- }
@@ -1,122 +0,0 @@
1
- import { Command } from "commander";
2
- import chalk from "chalk";
3
- import { runFeed, FeedOptions } from "./feed.js";
4
- import { c } from "../ui/colors.js";
5
-
6
- const SUBGRAPH_URL = "https://api.studio.thegraph.com/query/1744310/arc-402/v0.2.0";
7
-
8
- async function gql(query: string): Promise<Record<string, unknown>> {
9
- const res = await fetch(SUBGRAPH_URL, {
10
- method: "POST",
11
- headers: { "Content-Type": "application/json" },
12
- body: JSON.stringify({ query }),
13
- });
14
- if (!res.ok) throw new Error(`Subgraph HTTP ${res.status}`);
15
- const json = (await res.json()) as { data?: Record<string, unknown>; errors?: unknown[] };
16
- if (json.errors?.length) throw new Error(`Subgraph error: ${JSON.stringify(json.errors[0])}`);
17
- return json.data ?? {};
18
- }
19
-
20
- export function registerArenaCommands(program: Command): void {
21
- const arena = program.command("arena").description("Arena network commands");
22
-
23
- // ─── arena stats ───────────────────────────────────────────────────────────
24
-
25
- arena
26
- .command("stats")
27
- .description("Show Arena network statistics")
28
- .option("--json", "Output as JSON")
29
- .action(async (opts) => {
30
- try {
31
- const data = await gql(`{
32
- protocolStats(id: "global") {
33
- totalAgents
34
- totalWallets
35
- totalAgreements
36
- totalHandshakes
37
- totalConnections
38
- totalVouches
39
- totalCapabilityClaims
40
- }
41
- }`);
42
-
43
- const stats = data["protocolStats"] as Record<string, unknown> | null;
44
- if (!stats) {
45
- const msg = "No stats available — subgraph may still be syncing.";
46
- if (opts.json) {
47
- console.log(JSON.stringify({ error: msg }));
48
- } else {
49
- console.error(' ' + c.warning + c.white(` ${msg}`));
50
- }
51
- process.exit(1);
52
- }
53
-
54
- // Try to count active agreements separately — non-fatal if it fails
55
- let activeAgreements = 0;
56
- try {
57
- const agData = await gql(`{
58
- proposals: agreements(where: { state: 0 }, first: 1000) { id }
59
- accepted: agreements(where: { state: 1 }, first: 1000) { id }
60
- }`);
61
- activeAgreements =
62
- ((agData["proposals"] as unknown[]) ?? []).length +
63
- ((agData["accepted"] as unknown[]) ?? []).length;
64
- } catch {
65
- // ignore — active count just stays 0
66
- }
67
-
68
- if (opts.json) {
69
- console.log(JSON.stringify({ ...stats, activeAgreements }, null, 2));
70
- return;
71
- }
72
-
73
- const pad = (v: unknown) => String(v ?? 0).padStart(6);
74
- console.log(chalk.bold("╔══════════════════════════════════════╗"));
75
- console.log(chalk.bold("║ ARC Arena — Network Stats ║"));
76
- console.log(chalk.bold("╚══════════════════════════════════════╝"));
77
- console.log();
78
- console.log(` Agents ${pad(stats["totalAgents"])} registered`);
79
- console.log(` Wallets ${pad(stats["totalWallets"])} deployed`);
80
- console.log(
81
- ` Agreements ${pad(stats["totalAgreements"])} total (${activeAgreements} active)`,
82
- );
83
- console.log(` Handshakes ${pad(stats["totalHandshakes"])} sent`);
84
- console.log(` Connections ${pad(stats["totalConnections"])} unique pairs`);
85
- console.log(` Vouches ${pad(stats["totalVouches"])} active`);
86
- console.log(` Capabilities ${pad(stats["totalCapabilityClaims"])} claimed`);
87
- console.log();
88
- console.log(chalk.dim(" Subgraph: v0.2.0 · synced"));
89
- } catch (err) {
90
- const msg = err instanceof Error ? err.message : String(err);
91
- if (opts.json) {
92
- console.log(JSON.stringify({ error: "Subgraph unavailable", details: msg }));
93
- } else {
94
- console.error(' ' + c.failure + c.white(` Subgraph unavailable: ${msg}`));
95
- }
96
- process.exit(1);
97
- }
98
- });
99
-
100
- // ─── arena feed (alias) ─────────────────────────────────────────────────────
101
-
102
- arena
103
- .command("feed")
104
- .description("Live terminal feed of recent Arena events (alias for arc402 feed)")
105
- .option("--limit <n>", "Number of events to show", "20")
106
- .option("--live", "Poll every 30s for new events")
107
- .option("--type <type>", "Filter by event type: handshake|hire|fulfill|vouch")
108
- .option("--json", "Output as JSON")
109
- .action(async (opts) => {
110
- try {
111
- await runFeed(opts as FeedOptions);
112
- } catch (err) {
113
- const msg = err instanceof Error ? err.message : String(err);
114
- if ((opts as FeedOptions).json) {
115
- console.log(JSON.stringify({ error: "Subgraph unavailable", details: msg }));
116
- } else {
117
- console.error(' ' + c.failure + c.white(` Subgraph unavailable: ${msg}`));
118
- }
119
- process.exit(1);
120
- }
121
- });
122
- }
@@ -1,117 +0,0 @@
1
- import { Command } from "commander";
2
- import { execSync } from "child_process";
3
- import fs from "fs";
4
- import path from "path";
5
- import os from "os";
6
- import { c } from "../ui/colors.js";
7
-
8
- const ARC402_DIR = path.join(os.homedir(), ".arc402");
9
-
10
- // Files/patterns to exclude from backup
11
- const EXCLUDE_PATTERNS = [
12
- "daemon.db",
13
- "daemon.log",
14
- "daemon.pid",
15
- "daemon.sock",
16
- "repl_history",
17
- ];
18
-
19
- function todayStr(): string {
20
- const d = new Date();
21
- const y = d.getFullYear();
22
- const m = (d.getMonth() + 1).toString().padStart(2, "0");
23
- const day = d.getDate().toString().padStart(2, "0");
24
- return `${y}-${m}-${day}`;
25
- }
26
-
27
- export function registerBackupCommand(program: Command): void {
28
- // ── backup ─────────────────────────────────────────────────────────────────
29
- program
30
- .command("backup")
31
- .description("Backup ~/.arc402/ config, keys, and wallet storage to a tar.gz archive")
32
- .option("--output <path>", "Output file path (default: arc402-backup-YYYY-MM-DD.tar.gz)")
33
- .action((opts: { output?: string }) => {
34
- if (!fs.existsSync(ARC402_DIR)) {
35
- console.error(` ${c.failure} No ~/.arc402/ directory found. Nothing to back up.`);
36
- process.exit(1);
37
- }
38
-
39
- const outFile = opts.output ?? `arc402-backup-${todayStr()}.tar.gz`;
40
- const absOut = path.isAbsolute(outFile) ? outFile : path.join(process.cwd(), outFile);
41
-
42
- // Build --exclude flags
43
- const excludeFlags = EXCLUDE_PATTERNS.map((p) => `--exclude='.arc402/${p}'`).join(" ");
44
-
45
- try {
46
- execSync(
47
- `tar -czf "${absOut}" ${excludeFlags} -C "${os.homedir()}" .arc402`,
48
- { stdio: "pipe" }
49
- );
50
- } catch (err) {
51
- const msg = err instanceof Error ? err.message : String(err);
52
- console.error(` ${c.failure} Backup failed: ${msg}`);
53
- process.exit(1);
54
- }
55
-
56
- // Verify the file was created
57
- if (!fs.existsSync(absOut)) {
58
- console.error(` ${c.failure} Archive not found after tar completed.`);
59
- process.exit(1);
60
- }
61
-
62
- const sizeBytes = fs.statSync(absOut).size;
63
- const sizeStr = sizeBytes < 1024
64
- ? `${sizeBytes} B`
65
- : sizeBytes < 1024 * 1024
66
- ? `${(sizeBytes / 1024).toFixed(1)} KB`
67
- : `${(sizeBytes / (1024 * 1024)).toFixed(2)} MB`;
68
-
69
- console.log(` ${c.success} Backup saved to ${c.white(path.basename(absOut))} ${c.dim(`(${sizeStr})`)}`);
70
- });
71
-
72
- // ── restore ────────────────────────────────────────────────────────────────
73
- program
74
- .command("restore")
75
- .description("Restore ~/.arc402/ from a backup archive")
76
- .argument("<archive>", "Path to arc402-backup-*.tar.gz")
77
- .action((archive: string) => {
78
- const absArchive = path.isAbsolute(archive) ? archive : path.join(process.cwd(), archive);
79
-
80
- if (!fs.existsSync(absArchive)) {
81
- console.error(` ${c.failure} Archive not found: ${absArchive}`);
82
- process.exit(1);
83
- }
84
-
85
- // Warn if ~/.arc402/ already exists
86
- if (fs.existsSync(ARC402_DIR)) {
87
- const existing = fs.readdirSync(ARC402_DIR);
88
- if (existing.length > 0) {
89
- console.warn(` ${c.warning} Existing ~/.arc402/ has ${existing.length} file(s) — merging (existing files take precedence for conflicts).`);
90
- }
91
- }
92
-
93
- try {
94
- // Extract to home dir — tar archive has .arc402/ as the root entry
95
- execSync(`tar -xzf "${absArchive}" -C "${os.homedir()}"`, { stdio: "pipe" });
96
- } catch (err) {
97
- const msg = err instanceof Error ? err.message : String(err);
98
- console.error(` ${c.failure} Restore failed: ${msg}`);
99
- process.exit(1);
100
- }
101
-
102
- // Verify config.json is present
103
- const configPath = path.join(ARC402_DIR, "config.json");
104
- if (!fs.existsSync(configPath)) {
105
- console.error(` ${c.failure} config.json not found after restore — archive may be incomplete.`);
106
- process.exit(1);
107
- }
108
-
109
- // Fix permissions on restored directory
110
- try {
111
- fs.chmodSync(ARC402_DIR, 0o700);
112
- fs.chmodSync(configPath, 0o600);
113
- } catch { /* best-effort */ }
114
-
115
- console.log(` ${c.success} Config restored. Run ${c.white("arc402 doctor")} to verify.`);
116
- });
117
- }
@@ -1,35 +0,0 @@
1
- import { Command } from "commander";
2
- import { ServiceAgreementClient } from "@arc402/sdk";
3
- import { loadConfig } from "../config.js";
4
- import { requireSigner } from "../client.js";
5
- import { printSenderInfo, executeContractWriteViaWallet } from "../wallet-router.js";
6
- import { SERVICE_AGREEMENT_ABI } from "../abis.js";
7
- import { c } from "../ui/colors.js";
8
- import { startSpinner } from "../ui/spinner.js";
9
-
10
- export function registerCancelCommand(program: Command): void {
11
- program.command("cancel <id>").description("Cancel a proposed agreement; use --expired for post-deadline recovery paths").option("--expired", "Call expiredCancel()", false).action(async (id, opts) => {
12
- const config = loadConfig();
13
- if (!config.serviceAgreementAddress) throw new Error("serviceAgreementAddress missing in config");
14
- const { signer } = await requireSigner(config);
15
- printSenderInfo(config);
16
- const spinner = startSpinner("Submitting transaction...");
17
- try {
18
- if (config.walletContractAddress) {
19
- const fn = opts.expired ? "expiredCancel" : "cancel";
20
- await executeContractWriteViaWallet(
21
- config.walletContractAddress, signer, config.serviceAgreementAddress,
22
- SERVICE_AGREEMENT_ABI, fn, [BigInt(id)],
23
- );
24
- } else {
25
- const client = new ServiceAgreementClient(config.serviceAgreementAddress, signer);
26
- if (opts.expired) await client.expiredCancel(BigInt(id)); else await client.cancel(BigInt(id));
27
- }
28
- spinner.succeed();
29
- } catch (err) {
30
- spinner.fail();
31
- throw err;
32
- }
33
- console.log(' ' + c.success + c.white(` Cancelled — agreement #${id}`));
34
- });
35
- }