arc402-cli 0.2.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 (308) hide show
  1. package/README.md +245 -0
  2. package/dist/abis.d.ts +19 -0
  3. package/dist/abis.d.ts.map +1 -0
  4. package/dist/abis.js +177 -0
  5. package/dist/abis.js.map +1 -0
  6. package/dist/bundler.d.ts +65 -0
  7. package/dist/bundler.d.ts.map +1 -0
  8. package/dist/bundler.js +181 -0
  9. package/dist/bundler.js.map +1 -0
  10. package/dist/client.d.ts +14 -0
  11. package/dist/client.d.ts.map +1 -0
  12. package/dist/client.js +24 -0
  13. package/dist/client.js.map +1 -0
  14. package/dist/coinbase-smart-wallet.d.ts +28 -0
  15. package/dist/coinbase-smart-wallet.d.ts.map +1 -0
  16. package/dist/coinbase-smart-wallet.js +38 -0
  17. package/dist/coinbase-smart-wallet.js.map +1 -0
  18. package/dist/commands/accept.d.ts +3 -0
  19. package/dist/commands/accept.d.ts.map +1 -0
  20. package/dist/commands/accept.js +26 -0
  21. package/dist/commands/accept.js.map +1 -0
  22. package/dist/commands/agent-handshake.d.ts +3 -0
  23. package/dist/commands/agent-handshake.d.ts.map +1 -0
  24. package/dist/commands/agent-handshake.js +61 -0
  25. package/dist/commands/agent-handshake.js.map +1 -0
  26. package/dist/commands/agent.d.ts +3 -0
  27. package/dist/commands/agent.d.ts.map +1 -0
  28. package/dist/commands/agent.js +417 -0
  29. package/dist/commands/agent.js.map +1 -0
  30. package/dist/commands/agreements.d.ts +3 -0
  31. package/dist/commands/agreements.d.ts.map +1 -0
  32. package/dist/commands/agreements.js +344 -0
  33. package/dist/commands/agreements.js.map +1 -0
  34. package/dist/commands/arbitrator.d.ts +3 -0
  35. package/dist/commands/arbitrator.d.ts.map +1 -0
  36. package/dist/commands/arbitrator.js +157 -0
  37. package/dist/commands/arbitrator.js.map +1 -0
  38. package/dist/commands/arena-handshake.d.ts +3 -0
  39. package/dist/commands/arena-handshake.d.ts.map +1 -0
  40. package/dist/commands/arena-handshake.js +187 -0
  41. package/dist/commands/arena-handshake.js.map +1 -0
  42. package/dist/commands/cancel.d.ts +3 -0
  43. package/dist/commands/cancel.d.ts.map +1 -0
  44. package/dist/commands/cancel.js +30 -0
  45. package/dist/commands/cancel.js.map +1 -0
  46. package/dist/commands/channel.d.ts +3 -0
  47. package/dist/commands/channel.d.ts.map +1 -0
  48. package/dist/commands/channel.js +238 -0
  49. package/dist/commands/channel.js.map +1 -0
  50. package/dist/commands/coldstart.d.ts +3 -0
  51. package/dist/commands/coldstart.d.ts.map +1 -0
  52. package/dist/commands/coldstart.js +148 -0
  53. package/dist/commands/coldstart.js.map +1 -0
  54. package/dist/commands/config.d.ts +3 -0
  55. package/dist/commands/config.d.ts.map +1 -0
  56. package/dist/commands/config.js +40 -0
  57. package/dist/commands/config.js.map +1 -0
  58. package/dist/commands/contract-interaction.d.ts +3 -0
  59. package/dist/commands/contract-interaction.d.ts.map +1 -0
  60. package/dist/commands/contract-interaction.js +165 -0
  61. package/dist/commands/contract-interaction.js.map +1 -0
  62. package/dist/commands/daemon.d.ts +3 -0
  63. package/dist/commands/daemon.d.ts.map +1 -0
  64. package/dist/commands/daemon.js +891 -0
  65. package/dist/commands/daemon.js.map +1 -0
  66. package/dist/commands/deliver.d.ts +3 -0
  67. package/dist/commands/deliver.d.ts.map +1 -0
  68. package/dist/commands/deliver.js +156 -0
  69. package/dist/commands/deliver.js.map +1 -0
  70. package/dist/commands/discover.d.ts +3 -0
  71. package/dist/commands/discover.d.ts.map +1 -0
  72. package/dist/commands/discover.js +224 -0
  73. package/dist/commands/discover.js.map +1 -0
  74. package/dist/commands/dispute.d.ts +3 -0
  75. package/dist/commands/dispute.d.ts.map +1 -0
  76. package/dist/commands/dispute.js +348 -0
  77. package/dist/commands/dispute.js.map +1 -0
  78. package/dist/commands/endpoint.d.ts +3 -0
  79. package/dist/commands/endpoint.d.ts.map +1 -0
  80. package/dist/commands/endpoint.js +604 -0
  81. package/dist/commands/endpoint.js.map +1 -0
  82. package/dist/commands/hire.d.ts +3 -0
  83. package/dist/commands/hire.d.ts.map +1 -0
  84. package/dist/commands/hire.js +189 -0
  85. package/dist/commands/hire.js.map +1 -0
  86. package/dist/commands/migrate.d.ts +3 -0
  87. package/dist/commands/migrate.d.ts.map +1 -0
  88. package/dist/commands/migrate.js +163 -0
  89. package/dist/commands/migrate.js.map +1 -0
  90. package/dist/commands/negotiate.d.ts +3 -0
  91. package/dist/commands/negotiate.d.ts.map +1 -0
  92. package/dist/commands/negotiate.js +247 -0
  93. package/dist/commands/negotiate.js.map +1 -0
  94. package/dist/commands/openshell.d.ts +3 -0
  95. package/dist/commands/openshell.d.ts.map +1 -0
  96. package/dist/commands/openshell.js +952 -0
  97. package/dist/commands/openshell.js.map +1 -0
  98. package/dist/commands/owner.d.ts +3 -0
  99. package/dist/commands/owner.d.ts.map +1 -0
  100. package/dist/commands/owner.js +32 -0
  101. package/dist/commands/owner.js.map +1 -0
  102. package/dist/commands/policy.d.ts +4 -0
  103. package/dist/commands/policy.d.ts.map +1 -0
  104. package/dist/commands/policy.js +248 -0
  105. package/dist/commands/policy.js.map +1 -0
  106. package/dist/commands/relay.d.ts +3 -0
  107. package/dist/commands/relay.d.ts.map +1 -0
  108. package/dist/commands/relay.js +279 -0
  109. package/dist/commands/relay.js.map +1 -0
  110. package/dist/commands/remediate.d.ts +3 -0
  111. package/dist/commands/remediate.d.ts.map +1 -0
  112. package/dist/commands/remediate.js +42 -0
  113. package/dist/commands/remediate.js.map +1 -0
  114. package/dist/commands/reputation.d.ts +4 -0
  115. package/dist/commands/reputation.d.ts.map +1 -0
  116. package/dist/commands/reputation.js +72 -0
  117. package/dist/commands/reputation.js.map +1 -0
  118. package/dist/commands/setup.d.ts +3 -0
  119. package/dist/commands/setup.d.ts.map +1 -0
  120. package/dist/commands/setup.js +332 -0
  121. package/dist/commands/setup.js.map +1 -0
  122. package/dist/commands/trust.d.ts +3 -0
  123. package/dist/commands/trust.d.ts.map +1 -0
  124. package/dist/commands/trust.js +23 -0
  125. package/dist/commands/trust.js.map +1 -0
  126. package/dist/commands/verify.d.ts +3 -0
  127. package/dist/commands/verify.d.ts.map +1 -0
  128. package/dist/commands/verify.js +88 -0
  129. package/dist/commands/verify.js.map +1 -0
  130. package/dist/commands/wallet.d.ts +3 -0
  131. package/dist/commands/wallet.d.ts.map +1 -0
  132. package/dist/commands/wallet.js +2520 -0
  133. package/dist/commands/wallet.js.map +1 -0
  134. package/dist/commands/watchtower.d.ts +3 -0
  135. package/dist/commands/watchtower.d.ts.map +1 -0
  136. package/dist/commands/watchtower.js +238 -0
  137. package/dist/commands/watchtower.js.map +1 -0
  138. package/dist/commands/workroom.d.ts +3 -0
  139. package/dist/commands/workroom.d.ts.map +1 -0
  140. package/dist/commands/workroom.js +855 -0
  141. package/dist/commands/workroom.js.map +1 -0
  142. package/dist/config.d.ts +62 -0
  143. package/dist/config.d.ts.map +1 -0
  144. package/dist/config.js +141 -0
  145. package/dist/config.js.map +1 -0
  146. package/dist/daemon/config.d.ts +74 -0
  147. package/dist/daemon/config.d.ts.map +1 -0
  148. package/dist/daemon/config.js +271 -0
  149. package/dist/daemon/config.js.map +1 -0
  150. package/dist/daemon/hire-listener.d.ts +31 -0
  151. package/dist/daemon/hire-listener.d.ts.map +1 -0
  152. package/dist/daemon/hire-listener.js +207 -0
  153. package/dist/daemon/hire-listener.js.map +1 -0
  154. package/dist/daemon/index.d.ts +29 -0
  155. package/dist/daemon/index.d.ts.map +1 -0
  156. package/dist/daemon/index.js +535 -0
  157. package/dist/daemon/index.js.map +1 -0
  158. package/dist/daemon/job-lifecycle.d.ts +62 -0
  159. package/dist/daemon/job-lifecycle.d.ts.map +1 -0
  160. package/dist/daemon/job-lifecycle.js +201 -0
  161. package/dist/daemon/job-lifecycle.js.map +1 -0
  162. package/dist/daemon/notify.d.ts +22 -0
  163. package/dist/daemon/notify.d.ts.map +1 -0
  164. package/dist/daemon/notify.js +148 -0
  165. package/dist/daemon/notify.js.map +1 -0
  166. package/dist/daemon/token-metering.d.ts +42 -0
  167. package/dist/daemon/token-metering.d.ts.map +1 -0
  168. package/dist/daemon/token-metering.js +178 -0
  169. package/dist/daemon/token-metering.js.map +1 -0
  170. package/dist/daemon/userops.d.ts +21 -0
  171. package/dist/daemon/userops.d.ts.map +1 -0
  172. package/dist/daemon/userops.js +88 -0
  173. package/dist/daemon/userops.js.map +1 -0
  174. package/dist/daemon/wallet-monitor.d.ts +16 -0
  175. package/dist/daemon/wallet-monitor.d.ts.map +1 -0
  176. package/dist/daemon/wallet-monitor.js +57 -0
  177. package/dist/daemon/wallet-monitor.js.map +1 -0
  178. package/dist/drain-v4.d.ts +2 -0
  179. package/dist/drain-v4.d.ts.map +1 -0
  180. package/dist/drain-v4.js +167 -0
  181. package/dist/drain-v4.js.map +1 -0
  182. package/dist/endpoint-config.d.ts +36 -0
  183. package/dist/endpoint-config.d.ts.map +1 -0
  184. package/dist/endpoint-config.js +96 -0
  185. package/dist/endpoint-config.js.map +1 -0
  186. package/dist/index.d.ts +3 -0
  187. package/dist/index.d.ts.map +1 -0
  188. package/dist/index.js +79 -0
  189. package/dist/index.js.map +1 -0
  190. package/dist/openshell-runtime.d.ts +55 -0
  191. package/dist/openshell-runtime.d.ts.map +1 -0
  192. package/dist/openshell-runtime.js +268 -0
  193. package/dist/openshell-runtime.js.map +1 -0
  194. package/dist/signing.d.ts +2 -0
  195. package/dist/signing.d.ts.map +1 -0
  196. package/dist/signing.js +23 -0
  197. package/dist/signing.js.map +1 -0
  198. package/dist/telegram-notify.d.ts +23 -0
  199. package/dist/telegram-notify.d.ts.map +1 -0
  200. package/dist/telegram-notify.js +106 -0
  201. package/dist/telegram-notify.js.map +1 -0
  202. package/dist/ui/banner.d.ts +7 -0
  203. package/dist/ui/banner.d.ts.map +1 -0
  204. package/dist/ui/banner.js +37 -0
  205. package/dist/ui/banner.js.map +1 -0
  206. package/dist/ui/colors.d.ts +14 -0
  207. package/dist/ui/colors.d.ts.map +1 -0
  208. package/dist/ui/colors.js +29 -0
  209. package/dist/ui/colors.js.map +1 -0
  210. package/dist/ui/format.d.ts +26 -0
  211. package/dist/ui/format.d.ts.map +1 -0
  212. package/dist/ui/format.js +77 -0
  213. package/dist/ui/format.js.map +1 -0
  214. package/dist/ui/spinner.d.ts +8 -0
  215. package/dist/ui/spinner.d.ts.map +1 -0
  216. package/dist/ui/spinner.js +43 -0
  217. package/dist/ui/spinner.js.map +1 -0
  218. package/dist/utils/format.d.ts +10 -0
  219. package/dist/utils/format.d.ts.map +1 -0
  220. package/dist/utils/format.js +61 -0
  221. package/dist/utils/format.js.map +1 -0
  222. package/dist/utils/hash.d.ts +3 -0
  223. package/dist/utils/hash.d.ts.map +1 -0
  224. package/dist/utils/hash.js +43 -0
  225. package/dist/utils/hash.js.map +1 -0
  226. package/dist/utils/time.d.ts +3 -0
  227. package/dist/utils/time.d.ts.map +1 -0
  228. package/dist/utils/time.js +21 -0
  229. package/dist/utils/time.js.map +1 -0
  230. package/dist/wallet-router.d.ts +25 -0
  231. package/dist/wallet-router.d.ts.map +1 -0
  232. package/dist/wallet-router.js +153 -0
  233. package/dist/wallet-router.js.map +1 -0
  234. package/dist/walletconnect-session.d.ts +12 -0
  235. package/dist/walletconnect-session.d.ts.map +1 -0
  236. package/dist/walletconnect-session.js +26 -0
  237. package/dist/walletconnect-session.js.map +1 -0
  238. package/dist/walletconnect.d.ts +46 -0
  239. package/dist/walletconnect.d.ts.map +1 -0
  240. package/dist/walletconnect.js +267 -0
  241. package/dist/walletconnect.js.map +1 -0
  242. package/package.json +38 -0
  243. package/scripts/authorize-machine-key.ts +43 -0
  244. package/scripts/drain-wallet.ts +149 -0
  245. package/scripts/execute-spend-only.ts +81 -0
  246. package/scripts/register-agent-userop.ts +186 -0
  247. package/src/abis.ts +187 -0
  248. package/src/bundler.ts +235 -0
  249. package/src/client.ts +34 -0
  250. package/src/coinbase-smart-wallet.ts +51 -0
  251. package/src/commands/accept.ts +25 -0
  252. package/src/commands/agent-handshake.ts +67 -0
  253. package/src/commands/agent.ts +458 -0
  254. package/src/commands/agreements.ts +324 -0
  255. package/src/commands/arbitrator.ts +129 -0
  256. package/src/commands/arena-handshake.ts +217 -0
  257. package/src/commands/cancel.ts +26 -0
  258. package/src/commands/channel.ts +208 -0
  259. package/src/commands/coldstart.ts +156 -0
  260. package/src/commands/config.ts +35 -0
  261. package/src/commands/contract-interaction.ts +166 -0
  262. package/src/commands/daemon.ts +971 -0
  263. package/src/commands/deliver.ts +116 -0
  264. package/src/commands/discover.ts +295 -0
  265. package/src/commands/dispute.ts +373 -0
  266. package/src/commands/endpoint.ts +619 -0
  267. package/src/commands/hire.ts +200 -0
  268. package/src/commands/migrate.ts +175 -0
  269. package/src/commands/negotiate.ts +270 -0
  270. package/src/commands/openshell.ts +1053 -0
  271. package/src/commands/owner.ts +30 -0
  272. package/src/commands/policy.ts +252 -0
  273. package/src/commands/relay.ts +272 -0
  274. package/src/commands/remediate.ts +22 -0
  275. package/src/commands/reputation.ts +71 -0
  276. package/src/commands/setup.ts +343 -0
  277. package/src/commands/trust.ts +15 -0
  278. package/src/commands/verify.ts +88 -0
  279. package/src/commands/wallet.ts +2892 -0
  280. package/src/commands/watchtower.ts +232 -0
  281. package/src/commands/workroom.ts +889 -0
  282. package/src/config.ts +153 -0
  283. package/src/daemon/config.ts +308 -0
  284. package/src/daemon/hire-listener.ts +226 -0
  285. package/src/daemon/index.ts +609 -0
  286. package/src/daemon/job-lifecycle.ts +215 -0
  287. package/src/daemon/notify.ts +157 -0
  288. package/src/daemon/token-metering.ts +183 -0
  289. package/src/daemon/userops.ts +119 -0
  290. package/src/daemon/wallet-monitor.ts +90 -0
  291. package/src/drain-v4.ts +159 -0
  292. package/src/endpoint-config.ts +83 -0
  293. package/src/index.ts +75 -0
  294. package/src/openshell-runtime.ts +277 -0
  295. package/src/signing.ts +28 -0
  296. package/src/telegram-notify.ts +88 -0
  297. package/src/ui/banner.ts +41 -0
  298. package/src/ui/colors.ts +30 -0
  299. package/src/ui/format.ts +77 -0
  300. package/src/ui/spinner.ts +46 -0
  301. package/src/utils/format.ts +48 -0
  302. package/src/utils/hash.ts +5 -0
  303. package/src/utils/time.ts +15 -0
  304. package/src/wallet-router.ts +178 -0
  305. package/src/walletconnect-session.ts +27 -0
  306. package/src/walletconnect.ts +294 -0
  307. package/test/time.test.js +11 -0
  308. package/tsconfig.json +19 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"walletconnect.d.ts","sourceRoot":"","sources":["../src/walletconnect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAKxD,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAWxC,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAGF,KAAK,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;AAC/D,KAAK,SAAS,GAAG,UAAU,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AA2B3D;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,YAAY,EACpB,IAAI,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,YAAY,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GAC1E,OAAO,CAAC;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CA+HvE;AAED;;;GAGG;AACH,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,SAAS,EAClB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,EAAE,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/C,OAAO,CAAC,MAAM,CAAC,CASjB;AAED;;;GAGG;AACH,wBAAsB,2BAA2B,CAC/C,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,EAC1E,MAAM,EAAE,MAAM,EACd,YAAY,CAAC,EAAE,YAAY,EAC3B,MAAM,CAAC,EAAE,YAAY,GACpB,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAuE9C"}
@@ -0,0 +1,267 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.connectPhoneWallet = connectPhoneWallet;
7
+ exports.sendTransactionWithSession = sendTransactionWithSession;
8
+ exports.requestPhoneWalletSignature = requestPhoneWalletSignature;
9
+ const sign_client_1 = require("@walletconnect/sign-client");
10
+ const keyvaluestorage_1 = require("@walletconnect/keyvaluestorage");
11
+ const qrcode_terminal_1 = __importDefault(require("qrcode-terminal"));
12
+ const path_1 = __importDefault(require("path"));
13
+ const os_1 = __importDefault(require("os"));
14
+ const walletconnect_session_1 = require("./walletconnect-session");
15
+ const telegram_notify_1 = require("./telegram-notify");
16
+ // Suppress unhandled rejections from stale WalletConnect sessions (known SDK issue)
17
+ process.on("unhandledRejection", (reason) => {
18
+ const msg = reason instanceof Error ? reason.message : String(reason);
19
+ if (msg.includes("No matching key") || msg.includes("session topic doesn't exist"))
20
+ return;
21
+ console.error("Unhandled rejection:", msg);
22
+ });
23
+ async function makeSignClient(projectId) {
24
+ const storageDir = path_1.default.join(os_1.default.homedir(), ".arc402");
25
+ const storagePath = path_1.default.join(storageDir, "wc-storage.json");
26
+ return sign_client_1.SignClient.init({
27
+ projectId,
28
+ metadata: {
29
+ name: "ARC-402 CLI",
30
+ description: "ARC-402 Protocol CLI",
31
+ url: "https://app.arc402.xyz",
32
+ icons: [],
33
+ },
34
+ storage: new keyvaluestorage_1.KeyValueStorage({ database: storagePath }),
35
+ });
36
+ }
37
+ function walletLinks(encodedUri) {
38
+ return {
39
+ "MetaMask": `metamask://wc?uri=${encodedUri}`,
40
+ "Rabby": `rabby://wc?uri=${encodedUri}`,
41
+ "Coinbase Wallet": `cbwallet://wc?uri=${encodedUri}`,
42
+ "Trust Wallet": `trust://wc?uri=${encodedUri}`,
43
+ "Rainbow": `rainbow://wc?uri=${encodedUri}`,
44
+ };
45
+ }
46
+ /**
47
+ * Step 1 of the two-step flow: connect the phone wallet (or resume a valid session).
48
+ * On fresh connect, shows deep links + QR and waits for WC approval.
49
+ * Saves session to config after a successful fresh pairing.
50
+ */
51
+ async function connectPhoneWallet(projectId, chainId, config, opts) {
52
+ const client = await makeSignClient(projectId);
53
+ // Try to restore an existing valid session
54
+ const stored = (0, walletconnect_session_1.loadWCSession)(config, chainId);
55
+ if (stored) {
56
+ try {
57
+ const session = client.session.get(stored.topic);
58
+ // Verify the session is actually alive on the relay side (MetaMask may have
59
+ // killed it without notifying us). We do a lightweight ping; if it times out
60
+ // or throws the session is stale — fall through to fresh pairing.
61
+ await Promise.race([
62
+ client.ping({ topic: stored.topic }),
63
+ new Promise((_, reject) => setTimeout(() => reject(new Error("ping timeout")), 5000)),
64
+ ]);
65
+ return { client, session, account: stored.account };
66
+ }
67
+ catch {
68
+ // Session stale or timed out — clear locally and do fresh pairing
69
+ (0, walletconnect_session_1.clearWCSession)(config);
70
+ try {
71
+ await client.disconnect({ topic: stored.topic, reason: { code: 6000, message: "session stale" } });
72
+ }
73
+ catch { /* best-effort — may already be gone */ }
74
+ }
75
+ }
76
+ // Fresh pairing flow
77
+ const { uri, approval } = await client.connect({
78
+ requiredNamespaces: {
79
+ eip155: {
80
+ methods: ["eth_sendTransaction", "personal_sign", "wallet_switchEthereumChain"],
81
+ chains: [`eip155:${chainId}`],
82
+ events: ["accountsChanged"],
83
+ },
84
+ },
85
+ });
86
+ if (!uri)
87
+ throw new Error("Failed to create WalletConnect session");
88
+ const encodedUri = encodeURIComponent(uri);
89
+ const displayPrompt = opts?.prompt ?? "Connect your phone wallet";
90
+ if (opts?.hardware) {
91
+ console.log("\n─────────────────────────────────────────────────────");
92
+ console.log("Paste this URI into Ledger Live, Trezor Suite, or any WalletConnect-compatible signer:\n");
93
+ console.log(uri);
94
+ console.log("\n─────────────────────────────────────────────────────");
95
+ console.log("Waiting for connection...");
96
+ }
97
+ else {
98
+ const links = walletLinks(encodedUri);
99
+ console.log(`\n${displayPrompt}`);
100
+ console.log("─────────────────────────────────────");
101
+ console.log("Tap the link for your wallet app (opens directly):\n");
102
+ for (const [name, link] of Object.entries(links)) {
103
+ console.log(`${name}:\n${link}\n`);
104
+ }
105
+ console.log("Or scan QR:");
106
+ qrcode_terminal_1.default.generate(uri, { small: true });
107
+ console.log("\nWaiting for approval...");
108
+ }
109
+ const telegramOpts = opts?.hardware ? undefined : opts?.telegramOpts;
110
+ if (telegramOpts) {
111
+ await (0, telegram_notify_1.sendWalletConnectApprovalButton)({
112
+ botToken: telegramOpts.botToken,
113
+ chatId: telegramOpts.chatId,
114
+ threadId: telegramOpts.threadId,
115
+ prompt: displayPrompt,
116
+ walletLinks: [
117
+ { label: "🦊 MetaMask", url: `https://metamask.app.link/wc?uri=${encodedUri}` },
118
+ { label: "🌈 Rainbow", url: `https://rnbwapp.com/wc?uri=${encodedUri}` },
119
+ { label: "🔵 Trust Wallet", url: `https://link.trustwallet.com/wc?uri=${encodedUri}` },
120
+ ],
121
+ });
122
+ console.log("Approval request sent to Telegram ✓");
123
+ }
124
+ const session = await approval();
125
+ const account = session.namespaces.eip155.accounts[0].split(":")[2];
126
+ // Ensure wallet is on the correct chain before sending any tx
127
+ const hexChainId = `0x${chainId.toString(16)}`;
128
+ const networkName = chainId === 8453 ? "Base" : chainId === 84532 ? "Base Sepolia" : `chain ${chainId}`;
129
+ // First try adding the chain (MetaMask ignores if already added)
130
+ if (chainId === 8453) {
131
+ try {
132
+ await client.request({
133
+ topic: session.topic,
134
+ chainId: `eip155:1`,
135
+ request: {
136
+ method: "wallet_addEthereumChain",
137
+ params: [{ chainId: hexChainId, chainName: "Base", nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, rpcUrls: ["https://mainnet.base.org"], blockExplorerUrls: ["https://basescan.org"] }],
138
+ },
139
+ });
140
+ }
141
+ catch { /* already added or unsupported */ }
142
+ }
143
+ // Then switch — retry up to 3 times
144
+ let chainSwitched = false;
145
+ for (let attempt = 0; attempt < 3; attempt++) {
146
+ try {
147
+ await client.request({
148
+ topic: session.topic,
149
+ chainId: `eip155:${chainId}`,
150
+ request: {
151
+ method: "wallet_switchEthereumChain",
152
+ params: [{ chainId: hexChainId }],
153
+ },
154
+ });
155
+ chainSwitched = true;
156
+ break;
157
+ }
158
+ catch {
159
+ await new Promise(r => setTimeout(r, 1500));
160
+ }
161
+ }
162
+ if (!chainSwitched) {
163
+ console.log(`\n⚠ Could not auto-switch to ${networkName}. IMPORTANT: Switch to ${networkName} in your wallet NOW before approving the next transaction.`);
164
+ console.log(` Otherwise the transaction will go to Ethereum mainnet and fail.`);
165
+ // Give user 5 seconds to read the warning and switch
166
+ await new Promise(r => setTimeout(r, 5000));
167
+ }
168
+ // Persist session (WC sessions last 7 days by default)
169
+ const expiry = Math.floor(Date.now() / 1000) + 7 * 24 * 60 * 60;
170
+ (0, walletconnect_session_1.saveWCSession)(config, { topic: session.topic, expiry, account, chainId });
171
+ return { client, session, account };
172
+ }
173
+ /**
174
+ * Step 2 of the two-step flow: send a transaction with an established session.
175
+ * Returns the transaction hash.
176
+ */
177
+ async function sendTransactionWithSession(client, session, account, chainId, tx) {
178
+ return client.request({
179
+ topic: session.topic,
180
+ chainId: `eip155:${chainId}`,
181
+ request: {
182
+ method: "eth_sendTransaction",
183
+ params: [{ from: account, to: tx.to, data: tx.data, value: tx.value ?? "0x0" }],
184
+ },
185
+ });
186
+ }
187
+ /**
188
+ * Convenience wrapper: connect + send in one call.
189
+ * Used by commands that haven't been split into two steps (e.g. policy set-limit).
190
+ */
191
+ async function requestPhoneWalletSignature(projectId, chainId, buildTx, prompt, telegramOpts, config) {
192
+ if (!config) {
193
+ // Legacy path: no session persistence, disconnect after use
194
+ const client = await makeSignClient(projectId);
195
+ const { uri, approval } = await client.connect({
196
+ requiredNamespaces: {
197
+ eip155: {
198
+ methods: ["eth_sendTransaction", "personal_sign", "wallet_switchEthereumChain"],
199
+ chains: [`eip155:${chainId}`],
200
+ events: ["accountsChanged"],
201
+ },
202
+ },
203
+ });
204
+ if (!uri)
205
+ throw new Error("Failed to create WalletConnect session");
206
+ const encodedUri = encodeURIComponent(uri);
207
+ const links = walletLinks(encodedUri);
208
+ console.log(`\n${prompt}`);
209
+ console.log("─────────────────────────────────────");
210
+ console.log("Tap the link for your wallet app (opens directly):\n");
211
+ for (const [name, link] of Object.entries(links))
212
+ console.log(`${name}:\n${link}\n`);
213
+ console.log("Or scan QR:");
214
+ qrcode_terminal_1.default.generate(uri, { small: true });
215
+ console.log("\nWaiting for approval...");
216
+ if (telegramOpts) {
217
+ await (0, telegram_notify_1.sendWalletConnectApprovalButton)({
218
+ botToken: telegramOpts.botToken,
219
+ chatId: telegramOpts.chatId,
220
+ threadId: telegramOpts.threadId,
221
+ prompt,
222
+ walletLinks: [
223
+ { label: "🦊 MetaMask", url: `https://metamask.app.link/wc?uri=${encodedUri}` },
224
+ { label: "🌈 Rainbow", url: `https://rnbwapp.com/wc?uri=${encodedUri}` },
225
+ { label: "🔵 Trust Wallet", url: `https://link.trustwallet.com/wc?uri=${encodedUri}` },
226
+ ],
227
+ });
228
+ console.log("Approval request sent to Telegram ✓");
229
+ }
230
+ const session = await approval();
231
+ const account = session.namespaces.eip155.accounts[0].split(":")[2];
232
+ // Switch chain — retry up to 3 times
233
+ const hexId = `0x${chainId.toString(16)}`;
234
+ let switched = false;
235
+ for (let i = 0; i < 3; i++) {
236
+ try {
237
+ await client.request({
238
+ topic: session.topic,
239
+ chainId: `eip155:${chainId}`,
240
+ request: { method: "wallet_switchEthereumChain", params: [{ chainId: hexId }] },
241
+ });
242
+ switched = true;
243
+ break;
244
+ }
245
+ catch {
246
+ await new Promise(r => setTimeout(r, 1000));
247
+ }
248
+ }
249
+ if (!switched) {
250
+ const net = chainId === 8453 ? "Base" : chainId === 84532 ? "Base Sepolia" : `chain ${chainId}`;
251
+ console.log(`\n⚠ Could not auto-switch chain. Please switch to ${net} manually in your wallet before approving.`);
252
+ }
253
+ const tx = buildTx(account);
254
+ const txHash = await client.request({
255
+ topic: session.topic,
256
+ chainId: `eip155:${chainId}`,
257
+ request: { method: "eth_sendTransaction", params: [{ from: account, to: tx.to, data: tx.data, value: tx.value ?? "0x0" }] },
258
+ });
259
+ await client.disconnect({ topic: session.topic, reason: { code: 0, message: "done" } });
260
+ return { txHash, account };
261
+ }
262
+ const { client, session, account } = await connectPhoneWallet(projectId, chainId, config, { telegramOpts, prompt });
263
+ const tx = buildTx(account);
264
+ const txHash = await sendTransactionWithSession(client, session, account, chainId, tx);
265
+ return { txHash, account };
266
+ }
267
+ //# sourceMappingURL=walletconnect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"walletconnect.js","sourceRoot":"","sources":["../src/walletconnect.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "arc402-cli",
3
+ "version": "0.2.0",
4
+ "description": "ARC-402 CLI for discovery, negotiation payloads, hire/remediation/dispute workflows, and network reads",
5
+ "bin": {
6
+ "arc402": "./dist/index.js"
7
+ },
8
+ "main": "./dist/index.js",
9
+ "scripts": {
10
+ "build": "tsc",
11
+ "test": "node --test test/**/*.test.js"
12
+ },
13
+ "dependencies": {
14
+ "@arc402/sdk": "file:../reference/sdk",
15
+ "@coinbase/wallet-sdk": "^4.3.7",
16
+ "@types/better-sqlite3": "^7.6.13",
17
+ "@walletconnect/keyvaluestorage": "^1.1.1",
18
+ "@walletconnect/sign-client": "^2.17.4",
19
+ "better-sqlite3": "^12.8.0",
20
+ "chalk": "^5.3.0",
21
+ "cli-table3": "^0.6.3",
22
+ "commander": "^12.1.0",
23
+ "ethers": "^6.13.4",
24
+ "jose": "^6.2.1",
25
+ "ora": "^8.1.1",
26
+ "prompts": "^2.4.2",
27
+ "qrcode-terminal": "^0.12.0",
28
+ "smol-toml": "^1.6.0",
29
+ "tweetnacl": "^1.0.3",
30
+ "yaml": "^2.8.2"
31
+ },
32
+ "devDependencies": {
33
+ "@types/node": "^20.0.0",
34
+ "@types/prompts": "^2.4.9",
35
+ "@types/qrcode-terminal": "^0.12.2",
36
+ "typescript": "^5.4.5"
37
+ }
38
+ }
@@ -0,0 +1,43 @@
1
+ import { ethers } from "ethers";
2
+ import { loadConfig } from "../src/config";
3
+ import { connectPhoneWallet, sendTransactionWithSession } from "../src/walletconnect";
4
+
5
+ const WALLET = "0xC3207bFe22cba39AeC4e8540c97c29B028103c7F";
6
+ const HOT_KEY = "0x747024C2e59C523E3B1621A4b3F92366C1E28A30";
7
+ const CHAIN_ID = 8453;
8
+
9
+ async function main() {
10
+ const config = loadConfig();
11
+ const iface = new ethers.Interface(["function authorizeMachineKey(address key) external"]);
12
+
13
+ const tx = {
14
+ to: WALLET,
15
+ data: iface.encodeFunctionData("authorizeMachineKey", [HOT_KEY]),
16
+ value: "0x0",
17
+ };
18
+
19
+ const tgOpts = {
20
+ botToken: config.telegramBotToken!,
21
+ chatId: config.telegramChatId!,
22
+ threadId: config.telegramThreadId,
23
+ };
24
+
25
+ console.log(`Authorizing hot key ${HOT_KEY} as machine key on ${WALLET}\n`);
26
+
27
+ const { client, session, account } = await connectPhoneWallet(
28
+ config.walletConnectProjectId!,
29
+ CHAIN_ID,
30
+ config,
31
+ {
32
+ telegramOpts: tgOpts,
33
+ prompt: "⛓ BASE — authorizeMachineKey (one-time). After this the hot key runs autonomously.",
34
+ }
35
+ );
36
+
37
+ console.log("Connected:", account);
38
+ const hash = await sendTransactionWithSession(client, session, account, CHAIN_ID, tx);
39
+ console.log("✅ Done:", hash);
40
+ process.exit(0);
41
+ }
42
+
43
+ main().catch(e => { console.error(e.message ?? e); process.exit(1); });
@@ -0,0 +1,149 @@
1
+ /**
2
+ * drain-wallet.ts
3
+ * Drain all ETH from the ARC402Wallet contract to the deployer wallet.
4
+ * Uses WalletConnect — sends MetaMask approval button to Telegram.
5
+ *
6
+ * Flow:
7
+ * 1. Read wallet balance
8
+ * 2. Build openContext + attest + executeSpend calldata
9
+ * 3. Connect via WalletConnect (sends Telegram button)
10
+ * 4. Send all 3 txs sequentially for owner approval
11
+ */
12
+
13
+ import { ethers } from "ethers";
14
+ import { loadConfig } from "../src/config";
15
+ import { connectPhoneWallet, sendTransactionWithSession } from "../src/walletconnect";
16
+
17
+ const DEPLOYER = "0x59A32A792d0f25B0E0a4A4aFbFDf514b94B102fB";
18
+ const WALLET = "0xC3207bFe22cba39AeC4e8540c97c29B028103c7F";
19
+ const RPC = "https://base-mainnet.g.alchemy.com/v2/YIA2uRCsFI-j5pqH-aRzflrACSlV1Qrs";
20
+ const CHAIN_ID = 8453;
21
+
22
+ const WALLET_ABI = [
23
+ "function openContext(bytes32 contextId, string calldata taskType) external",
24
+ "function closeContext() external",
25
+ "function attest(bytes32 attestationId, string calldata action, string calldata reason, address recipient, uint256 amount, address token, uint256 expiresAt) external returns (bytes32)",
26
+ "function executeSpend(address payable recipient, uint256 amount, string calldata category, bytes32 attestationId) external",
27
+ "function contextOpen() external view returns (bool)",
28
+ ];
29
+
30
+ async function main() {
31
+ const config = loadConfig();
32
+
33
+ const balance = await new ethers.JsonRpcProvider(RPC).getBalance(WALLET);
34
+
35
+ if (balance === 0n) {
36
+ console.log("Wallet is already empty.");
37
+ process.exit(0);
38
+ }
39
+
40
+ // Reserve gas for 3 transactions (~300k gas @ ~0.01 gwei = ~0.003 ETH buffer)
41
+ const gasReserve = ethers.parseEther("0.0001");
42
+ const sendAmount = balance - gasReserve;
43
+
44
+ if (sendAmount <= 0n) {
45
+ console.log(`Balance too low to drain safely: ${ethers.formatEther(balance)} ETH`);
46
+ process.exit(0);
47
+ }
48
+
49
+ console.log(`\nDraining ${ethers.formatEther(sendAmount)} ETH from wallet contract`);
50
+ console.log(` From: ${WALLET}`);
51
+ console.log(` To: ${DEPLOYER}\n`);
52
+
53
+ const iface = new ethers.Interface(WALLET_ABI);
54
+
55
+ const contextId = ethers.keccak256(ethers.toUtf8Bytes(`drain-${Date.now()}`));
56
+ const attestId = ethers.keccak256(ethers.toUtf8Bytes(`attest-${Date.now()}`));
57
+ const expiresAt = Math.floor(Date.now() / 1000) + 3600; // 1 hour
58
+
59
+ // Close any existing open context first (from prior partial run)
60
+ const provider = new ethers.JsonRpcProvider(RPC);
61
+ const contextOpenRaw = await provider.call({ to: WALLET, data: iface.encodeFunctionData("contextOpen") });
62
+ const contextAlreadyOpen = ethers.AbiCoder.defaultAbiCoder().decode(["bool"], contextOpenRaw)[0];
63
+
64
+ const txCloseContext = contextAlreadyOpen ? {
65
+ to: WALLET,
66
+ data: iface.encodeFunctionData("closeContext"),
67
+ value: "0x0",
68
+ } : null;
69
+
70
+ const txOpenContext = {
71
+ to: WALLET,
72
+ data: iface.encodeFunctionData("openContext", [contextId, "drain"]),
73
+ value: "0x0",
74
+ };
75
+
76
+ const txAttest = {
77
+ to: WALLET,
78
+ data: iface.encodeFunctionData("attest", [
79
+ attestId,
80
+ "drain",
81
+ "drain to deployer",
82
+ DEPLOYER,
83
+ sendAmount,
84
+ ethers.ZeroAddress,
85
+ expiresAt,
86
+ ]),
87
+ value: "0x0",
88
+ };
89
+
90
+ const txSpend = {
91
+ to: WALLET,
92
+ data: iface.encodeFunctionData("executeSpend", [
93
+ DEPLOYER,
94
+ sendAmount,
95
+ "drain",
96
+ attestId,
97
+ ]),
98
+ value: "0x0",
99
+ };
100
+
101
+ const tgOpts = {
102
+ botToken: config.telegramBotToken!,
103
+ chatId: config.telegramChatId!,
104
+ threadId: config.telegramThreadId,
105
+ };
106
+
107
+ console.log("Connecting WalletConnect — fresh session, Base network enforced...\n");
108
+
109
+ const { client, session, account } = await connectPhoneWallet(
110
+ config.walletConnectProjectId!,
111
+ CHAIN_ID,
112
+ config,
113
+ {
114
+ telegramOpts: tgOpts,
115
+ prompt: `⛓ BASE NETWORK ONLY\nApprove drain of ${ethers.formatEther(sendAmount)} ETH → deployer wallet\n\n⚠️ Make sure MetaMask is on BASE before approving`,
116
+ }
117
+ );
118
+
119
+ console.log(`\nConnected: ${account}`);
120
+
121
+ let txCount = 1;
122
+ const total = (txCloseContext ? 4 : 3);
123
+
124
+ if (txCloseContext) {
125
+ console.log(`Sending tx ${txCount++}/${total}: closeContext (cleaning up prior run)...`);
126
+ const hClose = await sendTransactionWithSession(client, session, account, CHAIN_ID, txCloseContext);
127
+ console.log(` ✓ ${hClose}`);
128
+ }
129
+
130
+ console.log(`Sending tx ${txCount++}/${total}: openContext...`);
131
+ const h1 = await sendTransactionWithSession(client, session, account, CHAIN_ID, txOpenContext);
132
+ console.log(` ✓ ${h1}`);
133
+
134
+ console.log(`Sending tx ${txCount++}/${total}: attest...`);
135
+ const h2 = await sendTransactionWithSession(client, session, account, CHAIN_ID, txAttest);
136
+ console.log(` ✓ ${h2}`);
137
+
138
+ console.log(`Sending tx ${txCount++}/${total}: executeSpend...`);
139
+ const h3 = await sendTransactionWithSession(client, session, account, CHAIN_ID, txSpend);
140
+ console.log(` ✓ ${h3}`);
141
+
142
+ console.log(`\n✅ Done. ${ethers.formatEther(sendAmount)} ETH sent to deployer.`);
143
+ process.exit(0);
144
+ }
145
+
146
+ main().catch(e => {
147
+ console.error(e.message ?? e);
148
+ process.exit(1);
149
+ });
@@ -0,0 +1,81 @@
1
+ /**
2
+ * execute-spend-only.ts
3
+ * Send ONLY the executeSpend tx — context and attest already confirmed on-chain.
4
+ * Uses the attestation ID from the last successful attest tx.
5
+ */
6
+
7
+ import { ethers } from "ethers";
8
+ import { loadConfig } from "../src/config";
9
+ import { connectPhoneWallet, sendTransactionWithSession } from "../src/walletconnect";
10
+
11
+ const DEPLOYER = "0x59A32A792d0f25B0E0a4A4aFbFDf514b94B102fB";
12
+ const WALLET = "0xC3207bFe22cba39AeC4e8540c97c29B028103c7F";
13
+ const RPC = "https://base-mainnet.g.alchemy.com/v2/YIA2uRCsFI-j5pqH-aRzflrACSlV1Qrs";
14
+ const CHAIN_ID = 8453;
15
+
16
+ // Attest tx was: 0x28dbff33aa65b0617c4f25810f06f76bfcf0a430f461b...
17
+ // Recover attestId from the drain script's timestamp-based keccak
18
+ // The attest tx confirmed — we need to recover the attestId used.
19
+ // Re-derive it: the script used `attest-${Date.now()}` at time of that run.
20
+ // Instead, read it from the IntentAttestation contract by checking events.
21
+
22
+ const INTENT_ATTEST_ABI = [
23
+ "event AttestationCreated(bytes32 indexed attestationId, address indexed wallet, address recipient, uint256 amount, address token)",
24
+ "function verify(bytes32 attestationId, address wallet, address recipient, uint256 amount, address token) external view returns (bool)",
25
+ ];
26
+
27
+ const WALLET_ABI = [
28
+ "function executeSpend(address payable recipient, uint256 amount, string calldata category, bytes32 attestationId) external",
29
+ ];
30
+
31
+ const INTENT_ATTEST_ADDR = "0x7ad8db6C5f394542E8e9658F86C85cC99Cf6D460";
32
+
33
+ async function main() {
34
+ const config = loadConfig();
35
+ const provider = new ethers.JsonRpcProvider(RPC);
36
+
37
+ // Find the most recent AttestationCreated event for this wallet → DEPLOYER
38
+ const attestContract = new ethers.Contract(INTENT_ATTEST_ADDR, INTENT_ATTEST_ABI, provider);
39
+ const block = await provider.getBlockNumber();
40
+ // Hardcoded from confirmed attest tx 0x28dbff33...c17
41
+ const attestId = "0x9d8bdb5f551f63e986e5d0c980fd68f4e445b9f7902f71226ec08ce24bceebb0";
42
+ const amount = ethers.parseEther("0.00015");
43
+
44
+ console.log(`Found attestation: ${attestId}`);
45
+ console.log(`Amount: ${ethers.formatEther(amount)} ETH`);
46
+ console.log(`Sending executeSpend → ${DEPLOYER}\n`);
47
+
48
+ const iface = new ethers.Interface(WALLET_ABI);
49
+ const txSpend = {
50
+ to: WALLET,
51
+ data: iface.encodeFunctionData("executeSpend", [DEPLOYER, amount, "drain", attestId]),
52
+ value: "0x0",
53
+ };
54
+
55
+ const tgOpts = {
56
+ botToken: config.telegramBotToken!,
57
+ chatId: config.telegramChatId!,
58
+ threadId: config.telegramThreadId,
59
+ };
60
+
61
+ const { client, session, account } = await connectPhoneWallet(
62
+ config.walletConnectProjectId!,
63
+ CHAIN_ID,
64
+ config,
65
+ {
66
+ telegramOpts: tgOpts,
67
+ prompt: `⛓ BASE ONLY — Final tx: executeSpend ${ethers.formatEther(amount)} ETH → deployer\n\n⚠️ Keep MetaMask on Base and approve`,
68
+ }
69
+ );
70
+
71
+ console.log(`Connected: ${account}`);
72
+ console.log("Sending executeSpend...");
73
+ const hash = await sendTransactionWithSession(client, session, account, CHAIN_ID, txSpend);
74
+ console.log(`\n✅ Done: ${hash}`);
75
+ process.exit(0);
76
+ }
77
+
78
+ main().catch(e => {
79
+ console.error(e.message ?? e);
80
+ process.exit(1);
81
+ });