arc402-cli 0.9.19 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (359) hide show
  1. package/README.md +41 -2
  2. package/dist/abis.d.ts +1 -0
  3. package/dist/abis.d.ts.map +1 -1
  4. package/dist/abis.js +45 -14
  5. package/dist/abis.js.map +1 -1
  6. package/dist/bundler.d.ts +1 -1
  7. package/dist/bundler.d.ts.map +1 -1
  8. package/dist/bundler.js +61 -27
  9. package/dist/bundler.js.map +1 -1
  10. package/dist/client.d.ts +1 -1
  11. package/dist/client.d.ts.map +1 -1
  12. package/dist/client.js +9 -5
  13. package/dist/client.js.map +1 -1
  14. package/dist/coinbase-smart-wallet.js +4 -1
  15. package/dist/coinbase-smart-wallet.js.map +1 -1
  16. package/dist/commands/accept.js +28 -25
  17. package/dist/commands/accept.js.map +1 -1
  18. package/dist/commands/agent-handshake.js +18 -15
  19. package/dist/commands/agent-handshake.js.map +1 -1
  20. package/dist/commands/agent.js +104 -98
  21. package/dist/commands/agent.js.map +1 -1
  22. package/dist/commands/agreements.js +98 -62
  23. package/dist/commands/agreements.js.map +1 -1
  24. package/dist/commands/arbitrator.js +81 -45
  25. package/dist/commands/arbitrator.js.map +1 -1
  26. package/dist/commands/arena-handshake.d.ts.map +1 -1
  27. package/dist/commands/arena-handshake.js +35 -53
  28. package/dist/commands/arena-handshake.js.map +1 -1
  29. package/dist/commands/arena.js +18 -12
  30. package/dist/commands/arena.js.map +1 -1
  31. package/dist/commands/backup.js +36 -30
  32. package/dist/commands/backup.js.map +1 -1
  33. package/dist/commands/cancel.js +18 -15
  34. package/dist/commands/cancel.js.map +1 -1
  35. package/dist/commands/channel.js +81 -45
  36. package/dist/commands/channel.js.map +1 -1
  37. package/dist/commands/coldstart.js +34 -31
  38. package/dist/commands/coldstart.js.map +1 -1
  39. package/dist/commands/compute.d.ts +14 -0
  40. package/dist/commands/compute.d.ts.map +1 -0
  41. package/dist/commands/compute.js +466 -0
  42. package/dist/commands/compute.js.map +1 -0
  43. package/dist/commands/config.js +30 -24
  44. package/dist/commands/config.js.map +1 -1
  45. package/dist/commands/contract-interaction.js +15 -12
  46. package/dist/commands/contract-interaction.js.map +1 -1
  47. package/dist/commands/daemon.d.ts.map +1 -1
  48. package/dist/commands/daemon.js +135 -98
  49. package/dist/commands/daemon.js.map +1 -1
  50. package/dist/commands/deliver.js +76 -37
  51. package/dist/commands/deliver.js.map +1 -1
  52. package/dist/commands/discover.js +27 -24
  53. package/dist/commands/discover.js.map +1 -1
  54. package/dist/commands/dispute.js +110 -104
  55. package/dist/commands/dispute.js.map +1 -1
  56. package/dist/commands/doctor.js +55 -16
  57. package/dist/commands/doctor.js.map +1 -1
  58. package/dist/commands/endpoint.js +95 -56
  59. package/dist/commands/endpoint.js.map +1 -1
  60. package/dist/commands/feed.js +18 -11
  61. package/dist/commands/feed.js.map +1 -1
  62. package/dist/commands/hire.js +40 -37
  63. package/dist/commands/hire.js.map +1 -1
  64. package/dist/commands/migrate.js +33 -30
  65. package/dist/commands/migrate.js.map +1 -1
  66. package/dist/commands/negotiate.d.ts.map +1 -1
  67. package/dist/commands/negotiate.js +36 -34
  68. package/dist/commands/negotiate.js.map +1 -1
  69. package/dist/commands/openshell.js +104 -68
  70. package/dist/commands/openshell.js.map +1 -1
  71. package/dist/commands/owner.js +20 -17
  72. package/dist/commands/owner.js.map +1 -1
  73. package/dist/commands/policy.js +43 -41
  74. package/dist/commands/policy.js.map +1 -1
  75. package/dist/commands/relay.d.ts.map +1 -1
  76. package/dist/commands/relay.js +51 -18
  77. package/dist/commands/relay.js.map +1 -1
  78. package/dist/commands/remediate.js +23 -20
  79. package/dist/commands/remediate.js.map +1 -1
  80. package/dist/commands/reputation.js +27 -25
  81. package/dist/commands/reputation.js.map +1 -1
  82. package/dist/commands/setup.js +104 -65
  83. package/dist/commands/setup.js.map +1 -1
  84. package/dist/commands/trust.js +20 -17
  85. package/dist/commands/trust.js.map +1 -1
  86. package/dist/commands/verify.js +21 -18
  87. package/dist/commands/verify.js.map +1 -1
  88. package/dist/commands/wallet.d.ts.map +1 -1
  89. package/dist/commands/wallet.js +645 -679
  90. package/dist/commands/wallet.js.map +1 -1
  91. package/dist/commands/watch.js +36 -33
  92. package/dist/commands/watch.js.map +1 -1
  93. package/dist/commands/watchtower.js +73 -37
  94. package/dist/commands/watchtower.js.map +1 -1
  95. package/dist/commands/workroom.d.ts.map +1 -1
  96. package/dist/commands/workroom.js +282 -143
  97. package/dist/commands/workroom.js.map +1 -1
  98. package/dist/config.d.ts +3 -0
  99. package/dist/config.d.ts.map +1 -1
  100. package/dist/config.js +71 -22
  101. package/dist/config.js.map +1 -1
  102. package/dist/daemon/compute-metering.d.ts +61 -0
  103. package/dist/daemon/compute-metering.d.ts.map +1 -0
  104. package/dist/daemon/compute-metering.js +299 -0
  105. package/dist/daemon/compute-metering.js.map +1 -0
  106. package/dist/daemon/compute-session.d.ts +100 -0
  107. package/dist/daemon/compute-session.d.ts.map +1 -0
  108. package/dist/daemon/compute-session.js +231 -0
  109. package/dist/daemon/compute-session.js.map +1 -0
  110. package/dist/daemon/config.d.ts +19 -1
  111. package/dist/daemon/config.d.ts.map +1 -1
  112. package/dist/daemon/config.js +90 -16
  113. package/dist/daemon/config.js.map +1 -1
  114. package/dist/daemon/credentials.d.ts +24 -0
  115. package/dist/daemon/credentials.d.ts.map +1 -0
  116. package/dist/daemon/credentials.js +80 -0
  117. package/dist/daemon/credentials.js.map +1 -0
  118. package/dist/daemon/delivery-client.d.ts +35 -0
  119. package/dist/daemon/delivery-client.d.ts.map +1 -0
  120. package/dist/daemon/delivery-client.js +231 -0
  121. package/dist/daemon/delivery-client.js.map +1 -0
  122. package/dist/daemon/file-delivery.d.ts +98 -0
  123. package/dist/daemon/file-delivery.d.ts.map +1 -0
  124. package/dist/daemon/file-delivery.js +461 -0
  125. package/dist/daemon/file-delivery.js.map +1 -0
  126. package/dist/daemon/hire-listener.d.ts +3 -3
  127. package/dist/daemon/hire-listener.d.ts.map +1 -1
  128. package/dist/daemon/hire-listener.js +47 -13
  129. package/dist/daemon/hire-listener.js.map +1 -1
  130. package/dist/daemon/index.d.ts +2 -1
  131. package/dist/daemon/index.d.ts.map +1 -1
  132. package/dist/daemon/index.js +526 -53
  133. package/dist/daemon/index.js.map +1 -1
  134. package/dist/daemon/job-lifecycle.d.ts +1 -1
  135. package/dist/daemon/job-lifecycle.d.ts.map +1 -1
  136. package/dist/daemon/job-lifecycle.js +51 -11
  137. package/dist/daemon/job-lifecycle.js.map +1 -1
  138. package/dist/daemon/notify.d.ts +1 -1
  139. package/dist/daemon/notify.d.ts.map +1 -1
  140. package/dist/daemon/notify.js +53 -19
  141. package/dist/daemon/notify.js.map +1 -1
  142. package/dist/daemon/token-metering.js +47 -8
  143. package/dist/daemon/token-metering.js.map +1 -1
  144. package/dist/daemon/userops.d.ts +2 -2
  145. package/dist/daemon/userops.d.ts.map +1 -1
  146. package/dist/daemon/userops.js +27 -23
  147. package/dist/daemon/userops.js.map +1 -1
  148. package/dist/daemon/wallet-monitor.d.ts +1 -1
  149. package/dist/daemon/wallet-monitor.d.ts.map +1 -1
  150. package/dist/daemon/wallet-monitor.js +12 -8
  151. package/dist/daemon/wallet-monitor.js.map +1 -1
  152. package/dist/daemon/worker-executor.d.ts +71 -0
  153. package/dist/daemon/worker-executor.d.ts.map +1 -0
  154. package/dist/daemon/worker-executor.js +382 -0
  155. package/dist/daemon/worker-executor.js.map +1 -0
  156. package/dist/drain-v4.js +64 -26
  157. package/dist/drain-v4.js.map +1 -1
  158. package/dist/endpoint-config.js +63 -20
  159. package/dist/endpoint-config.js.map +1 -1
  160. package/dist/endpoint-notify.d.ts.map +1 -1
  161. package/dist/endpoint-notify.js +49 -15
  162. package/dist/endpoint-notify.js.map +1 -1
  163. package/dist/index.js +50 -18
  164. package/dist/index.js.map +1 -1
  165. package/dist/openshell-runtime.d.ts.map +1 -1
  166. package/dist/openshell-runtime.js +82 -38
  167. package/dist/openshell-runtime.js.map +1 -1
  168. package/dist/program.d.ts.map +1 -1
  169. package/dist/program.js +85 -78
  170. package/dist/program.js.map +1 -1
  171. package/dist/repl.js +31 -25
  172. package/dist/repl.js.map +1 -1
  173. package/dist/signing.js +6 -3
  174. package/dist/signing.js.map +1 -1
  175. package/dist/telegram-notify.js +40 -3
  176. package/dist/telegram-notify.js.map +1 -1
  177. package/dist/tui/App.d.ts.map +1 -1
  178. package/dist/tui/App.js +56 -89
  179. package/dist/tui/App.js.map +1 -1
  180. package/dist/tui/Footer.js +7 -4
  181. package/dist/tui/Footer.js.map +1 -1
  182. package/dist/tui/Header.d.ts +1 -1
  183. package/dist/tui/Header.d.ts.map +1 -1
  184. package/dist/tui/Header.js +14 -9
  185. package/dist/tui/Header.js.map +1 -1
  186. package/dist/tui/InputLine.d.ts +2 -1
  187. package/dist/tui/InputLine.d.ts.map +1 -1
  188. package/dist/tui/InputLine.js +47 -97
  189. package/dist/tui/InputLine.js.map +1 -1
  190. package/dist/tui/Viewport.d.ts +1 -2
  191. package/dist/tui/Viewport.d.ts.map +1 -1
  192. package/dist/tui/Viewport.js +26 -6
  193. package/dist/tui/Viewport.js.map +1 -1
  194. package/dist/tui/WalletConnectPairing.js +19 -16
  195. package/dist/tui/WalletConnectPairing.js.map +1 -1
  196. package/dist/tui/components/Button.js +9 -6
  197. package/dist/tui/components/Button.js.map +1 -1
  198. package/dist/tui/components/CeremonyView.js +8 -5
  199. package/dist/tui/components/CeremonyView.js.map +1 -1
  200. package/dist/tui/components/CompletionDropdown.js +9 -6
  201. package/dist/tui/components/CompletionDropdown.js.map +1 -1
  202. package/dist/tui/components/ConfirmPrompt.js +8 -5
  203. package/dist/tui/components/ConfirmPrompt.js.map +1 -1
  204. package/dist/tui/components/CustomTextInput.js +14 -11
  205. package/dist/tui/components/CustomTextInput.js.map +1 -1
  206. package/dist/tui/components/InteractiveTable.js +12 -9
  207. package/dist/tui/components/InteractiveTable.js.map +1 -1
  208. package/dist/tui/components/StepSpinner.js +13 -10
  209. package/dist/tui/components/StepSpinner.js.map +1 -1
  210. package/dist/tui/components/Toast.js +12 -8
  211. package/dist/tui/components/Toast.js.map +1 -1
  212. package/dist/tui/index.d.ts.map +1 -1
  213. package/dist/tui/index.js +21 -28
  214. package/dist/tui/index.js.map +1 -1
  215. package/dist/tui/useChat.js +19 -13
  216. package/dist/tui/useChat.js.map +1 -1
  217. package/dist/tui/useCommand.d.ts +2 -3
  218. package/dist/tui/useCommand.d.ts.map +1 -1
  219. package/dist/tui/useCommand.js +24 -100
  220. package/dist/tui/useCommand.js.map +1 -1
  221. package/dist/tui/useNotifications.js +8 -5
  222. package/dist/tui/useNotifications.js.map +1 -1
  223. package/dist/tui/useScroll.d.ts.map +1 -1
  224. package/dist/tui/useScroll.js +12 -15
  225. package/dist/tui/useScroll.js.map +1 -1
  226. package/dist/ui/banner.d.ts +0 -12
  227. package/dist/ui/banner.d.ts.map +1 -1
  228. package/dist/ui/banner.js +19 -35
  229. package/dist/ui/banner.js.map +1 -1
  230. package/dist/ui/colors.js +19 -13
  231. package/dist/ui/colors.js.map +1 -1
  232. package/dist/ui/format.js +14 -6
  233. package/dist/ui/format.js.map +1 -1
  234. package/dist/ui/qr-render.js +11 -4
  235. package/dist/ui/qr-render.js.map +1 -1
  236. package/dist/ui/rpc-fallback.js +11 -6
  237. package/dist/ui/rpc-fallback.js.map +1 -1
  238. package/dist/ui/spinner.js +12 -6
  239. package/dist/ui/spinner.js.map +1 -1
  240. package/dist/ui/tree.js +6 -3
  241. package/dist/ui/tree.js.map +1 -1
  242. package/dist/utils/format.js +41 -27
  243. package/dist/utils/format.js.map +1 -1
  244. package/dist/utils/hash.js +42 -4
  245. package/dist/utils/hash.js.map +1 -1
  246. package/dist/utils/time.js +6 -2
  247. package/dist/utils/time.js.map +1 -1
  248. package/dist/wallet-router.d.ts +1 -1
  249. package/dist/wallet-router.d.ts.map +1 -1
  250. package/dist/wallet-router.js +19 -12
  251. package/dist/wallet-router.js.map +1 -1
  252. package/dist/walletconnect-session.d.ts +1 -1
  253. package/dist/walletconnect-session.d.ts.map +1 -1
  254. package/dist/walletconnect-session.js +11 -6
  255. package/dist/walletconnect-session.js.map +1 -1
  256. package/dist/walletconnect.d.ts +5 -6
  257. package/dist/walletconnect.d.ts.map +1 -1
  258. package/dist/walletconnect.js +35 -32
  259. package/dist/walletconnect.js.map +1 -1
  260. package/package.json +11 -10
  261. package/INK6-UX-SPEC.md +0 -446
  262. package/MIGRATION-SPEC.md +0 -108
  263. package/TUI-SPEC.md +0 -214
  264. package/scripts/authorize-machine-key.ts +0 -43
  265. package/scripts/drain-wallet.ts +0 -149
  266. package/scripts/execute-spend-only.ts +0 -81
  267. package/scripts/register-agent-userop.ts +0 -186
  268. package/src/abis.ts +0 -187
  269. package/src/bundler.ts +0 -235
  270. package/src/client.ts +0 -36
  271. package/src/coinbase-smart-wallet.ts +0 -51
  272. package/src/commands/accept.ts +0 -64
  273. package/src/commands/agent-handshake.ts +0 -72
  274. package/src/commands/agent.ts +0 -691
  275. package/src/commands/agreements.ts +0 -350
  276. package/src/commands/arbitrator.ts +0 -180
  277. package/src/commands/arena-handshake.ts +0 -274
  278. package/src/commands/arena.ts +0 -122
  279. package/src/commands/backup.ts +0 -117
  280. package/src/commands/cancel.ts +0 -35
  281. package/src/commands/channel.ts +0 -218
  282. package/src/commands/coldstart.ts +0 -165
  283. package/src/commands/config.ts +0 -68
  284. package/src/commands/contract-interaction.ts +0 -166
  285. package/src/commands/daemon.ts +0 -1054
  286. package/src/commands/deliver.ts +0 -148
  287. package/src/commands/discover.ts +0 -350
  288. package/src/commands/dispute.ts +0 -375
  289. package/src/commands/doctor.ts +0 -172
  290. package/src/commands/endpoint.ts +0 -620
  291. package/src/commands/feed.ts +0 -229
  292. package/src/commands/hire.ts +0 -245
  293. package/src/commands/migrate.ts +0 -177
  294. package/src/commands/negotiate.ts +0 -272
  295. package/src/commands/openshell.ts +0 -1055
  296. package/src/commands/owner.ts +0 -35
  297. package/src/commands/policy.ts +0 -263
  298. package/src/commands/relay.ts +0 -277
  299. package/src/commands/remediate.ts +0 -24
  300. package/src/commands/reputation.ts +0 -79
  301. package/src/commands/setup.ts +0 -343
  302. package/src/commands/trust.ts +0 -27
  303. package/src/commands/verify.ts +0 -91
  304. package/src/commands/wallet.ts +0 -3548
  305. package/src/commands/watch.ts +0 -220
  306. package/src/commands/watchtower.ts +0 -248
  307. package/src/commands/workroom.ts +0 -963
  308. package/src/config.ts +0 -220
  309. package/src/daemon/config.ts +0 -344
  310. package/src/daemon/hire-listener.ts +0 -226
  311. package/src/daemon/index.ts +0 -1089
  312. package/src/daemon/job-lifecycle.ts +0 -215
  313. package/src/daemon/notify.ts +0 -297
  314. package/src/daemon/token-metering.ts +0 -183
  315. package/src/daemon/userops.ts +0 -119
  316. package/src/daemon/wallet-monitor.ts +0 -90
  317. package/src/drain-v4.ts +0 -159
  318. package/src/endpoint-config.ts +0 -83
  319. package/src/endpoint-notify.ts +0 -134
  320. package/src/index.ts +0 -74
  321. package/src/openshell-runtime.ts +0 -281
  322. package/src/program.ts +0 -88
  323. package/src/repl.ts +0 -178
  324. package/src/signing.ts +0 -28
  325. package/src/telegram-notify.ts +0 -88
  326. package/src/tui/App.tsx +0 -263
  327. package/src/tui/Footer.tsx +0 -18
  328. package/src/tui/Header.tsx +0 -45
  329. package/src/tui/InputLine.tsx +0 -243
  330. package/src/tui/Viewport.tsx +0 -51
  331. package/src/tui/WalletConnectPairing.tsx +0 -114
  332. package/src/tui/components/Button.tsx +0 -38
  333. package/src/tui/components/CeremonyView.tsx +0 -39
  334. package/src/tui/components/CompletionDropdown.tsx +0 -56
  335. package/src/tui/components/ConfirmPrompt.tsx +0 -36
  336. package/src/tui/components/CustomTextInput.tsx +0 -132
  337. package/src/tui/components/InteractiveTable.tsx +0 -106
  338. package/src/tui/components/StepSpinner.tsx +0 -84
  339. package/src/tui/components/Toast.tsx +0 -59
  340. package/src/tui/index.tsx +0 -90
  341. package/src/tui/useChat.ts +0 -103
  342. package/src/tui/useCommand.ts +0 -238
  343. package/src/tui/useNotifications.ts +0 -28
  344. package/src/tui/useScroll.ts +0 -69
  345. package/src/ui/banner.ts +0 -78
  346. package/src/ui/colors.ts +0 -30
  347. package/src/ui/format.ts +0 -78
  348. package/src/ui/qr-render.ts +0 -92
  349. package/src/ui/rpc-fallback.ts +0 -59
  350. package/src/ui/spinner.ts +0 -56
  351. package/src/ui/tree.ts +0 -16
  352. package/src/utils/format.ts +0 -48
  353. package/src/utils/hash.ts +0 -5
  354. package/src/utils/time.ts +0 -15
  355. package/src/wallet-router.ts +0 -178
  356. package/src/walletconnect-session.ts +0 -27
  357. package/src/walletconnect.ts +0 -309
  358. package/test/time.test.js +0 -11
  359. package/tsconfig.json +0 -33
@@ -1,309 +0,0 @@
1
- import { SignClient } from "@walletconnect/sign-client";
2
- import { KeyValueStorage } from "@walletconnect/keyvaluestorage";
3
- import { printQR } from "./ui/qr-render.js";
4
- import path from "path";
5
- import os from "os";
6
- import { Arc402Config } from "./config.js";
7
- import { loadWCSession, saveWCSession, clearWCSession } from "./walletconnect-session.js";
8
- import { sendWalletConnectApprovalButton } from "./telegram-notify.js";
9
-
10
- // Suppress unhandled rejections from stale WalletConnect sessions (known SDK issue)
11
- process.on("unhandledRejection", (reason: unknown) => {
12
- const msg = reason instanceof Error ? reason.message : String(reason);
13
- if (msg.includes("No matching key") || msg.includes("session topic doesn't exist")) return;
14
- console.error("Unhandled rejection:", msg);
15
- });
16
-
17
- export type TelegramOpts = {
18
- botToken: string;
19
- chatId: string;
20
- threadId?: number;
21
- };
22
-
23
- // Infer SignClient instance and session types from the SDK
24
- type SignClientT = Awaited<ReturnType<typeof SignClient.init>>;
25
- type WCSession = ReturnType<SignClientT["session"]["get"]>;
26
-
27
- async function makeSignClient(projectId: string): Promise<SignClientT> {
28
- const storageDir = path.join(os.homedir(), ".arc402");
29
- const storagePath = path.join(storageDir, "wc-storage.json");
30
- return SignClient.init({
31
- projectId,
32
- metadata: {
33
- name: "ARC-402 CLI",
34
- description: "ARC-402 Protocol CLI",
35
- url: "https://app.arc402.xyz",
36
- icons: [],
37
- },
38
- storage: new KeyValueStorage({ database: storagePath }),
39
- });
40
- }
41
-
42
- function walletLinks(encodedUri: string) {
43
- return {
44
- "MetaMask": `metamask://wc?uri=${encodedUri}`,
45
- "Rabby": `rabby://wc?uri=${encodedUri}`,
46
- "Coinbase Wallet": `cbwallet://wc?uri=${encodedUri}`,
47
- "Trust Wallet": `trust://wc?uri=${encodedUri}`,
48
- "Rainbow": `rainbow://wc?uri=${encodedUri}`,
49
- };
50
- }
51
-
52
- /**
53
- * Step 1 of the two-step flow: connect the phone wallet (or resume a valid session).
54
- * On fresh connect, shows deep links + QR and waits for WC approval.
55
- * Saves session to config after a successful fresh pairing.
56
- */
57
- export type WCCallbacks = {
58
- onUri?: (uri: string, links: Record<string, string>) => void;
59
- onStatus?: (status: "connecting" | "connected" | "chain-switching" | "ready" | "error", detail?: string) => void;
60
- };
61
-
62
- export async function connectPhoneWallet(
63
- projectId: string,
64
- chainId: number,
65
- config: Arc402Config,
66
- opts?: { telegramOpts?: TelegramOpts; prompt?: string; hardware?: boolean; callbacks?: WCCallbacks }
67
- ): Promise<{ client: SignClientT; session: WCSession; account: string }> {
68
- const client = await makeSignClient(projectId);
69
-
70
- // Try to restore an existing valid session
71
- const stored = loadWCSession(config, chainId);
72
- if (stored) {
73
- try {
74
- const session = client.session.get(stored.topic);
75
- // Verify the session is actually alive on the relay side (MetaMask may have
76
- // killed it without notifying us). We do a lightweight ping; if it times out
77
- // or throws the session is stale — fall through to fresh pairing.
78
- await Promise.race([
79
- client.ping({ topic: stored.topic }),
80
- new Promise<never>((_, reject) => setTimeout(() => reject(new Error("ping timeout")), 5000)),
81
- ]);
82
- return { client, session, account: stored.account };
83
- } catch {
84
- // Session stale or timed out — clear locally and do fresh pairing
85
- clearWCSession(config);
86
- try {
87
- await client.disconnect({ topic: stored.topic, reason: { code: 6000, message: "session stale" } });
88
- } catch { /* best-effort — may already be gone */ }
89
- }
90
- }
91
-
92
- // Fresh pairing flow
93
- const { uri, approval } = await client.connect({
94
- requiredNamespaces: {
95
- eip155: {
96
- methods: ["eth_sendTransaction", "personal_sign", "wallet_switchEthereumChain"],
97
- chains: [`eip155:${chainId}`],
98
- events: ["accountsChanged"],
99
- },
100
- },
101
- });
102
-
103
- if (!uri) throw new Error("Failed to create WalletConnect session");
104
-
105
- const encodedUri = encodeURIComponent(uri);
106
- const displayPrompt = opts?.prompt ?? "Connect your phone wallet";
107
- const cbs = opts?.callbacks;
108
-
109
- if (cbs?.onUri) {
110
- // Callback mode — let the caller handle rendering (e.g. Ink TUI)
111
- cbs.onUri(uri, walletLinks(encodedUri));
112
- cbs.onStatus?.("connecting");
113
- } else if (opts?.hardware) {
114
- console.log("\n─────────────────────────────────────────────────────");
115
- console.log("Paste this URI into Ledger Live, Trezor Suite, or any WalletConnect-compatible signer:\n");
116
- console.log(uri);
117
- console.log("\n─────────────────────────────────────────────────────");
118
- console.log("Waiting for connection...");
119
- } else {
120
- const links = walletLinks(encodedUri);
121
- console.log(`\n${displayPrompt}`);
122
- console.log("─────────────────────────────────────");
123
- console.log("Tap the link for your wallet app (opens directly):\n");
124
- for (const [name, link] of Object.entries(links)) {
125
- console.log(`${name}:\n${link}\n`);
126
- }
127
- console.log("Or scan QR:");
128
- printQR(uri);
129
- console.log("\nWaiting for approval...");
130
- }
131
-
132
- const telegramOpts = opts?.hardware ? undefined : opts?.telegramOpts;
133
- if (telegramOpts) {
134
- await sendWalletConnectApprovalButton({
135
- botToken: telegramOpts.botToken,
136
- chatId: telegramOpts.chatId,
137
- threadId: telegramOpts.threadId,
138
- prompt: displayPrompt,
139
- walletLinks: [
140
- { label: "🦊 MetaMask", url: `https://metamask.app.link/wc?uri=${encodedUri}` },
141
- { label: "🌈 Rainbow", url: `https://rnbwapp.com/wc?uri=${encodedUri}` },
142
- { label: "🔵 Trust Wallet", url: `https://link.trustwallet.com/wc?uri=${encodedUri}` },
143
- ],
144
- });
145
- console.log("Approval request sent to Telegram ✓");
146
- }
147
-
148
- const session = await approval();
149
- const account = session.namespaces.eip155.accounts[0].split(":")[2];
150
- cbs?.onStatus?.("connected", account);
151
-
152
- // Ensure wallet is on the correct chain before sending any tx
153
- const hexChainId = `0x${chainId.toString(16)}`;
154
- const networkName = chainId === 8453 ? "Base" : chainId === 84532 ? "Base Sepolia" : `chain ${chainId}`;
155
- cbs?.onStatus?.("chain-switching", networkName);
156
-
157
- // First try adding the chain (MetaMask ignores if already added)
158
- if (chainId === 8453) {
159
- try {
160
- await client.request({
161
- topic: session.topic,
162
- chainId: `eip155:1`,
163
- request: {
164
- method: "wallet_addEthereumChain",
165
- params: [{ chainId: hexChainId, chainName: "Base", nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, rpcUrls: ["https://mainnet.base.org"], blockExplorerUrls: ["https://basescan.org"] }],
166
- },
167
- });
168
- } catch { /* already added or unsupported */ }
169
- }
170
-
171
- // Then switch — retry up to 3 times
172
- let chainSwitched = false;
173
- for (let attempt = 0; attempt < 3; attempt++) {
174
- try {
175
- await client.request({
176
- topic: session.topic,
177
- chainId: `eip155:${chainId}`,
178
- request: {
179
- method: "wallet_switchEthereumChain",
180
- params: [{ chainId: hexChainId }],
181
- },
182
- });
183
- chainSwitched = true;
184
- break;
185
- } catch {
186
- await new Promise(r => setTimeout(r, 1500));
187
- }
188
- }
189
- if (!chainSwitched) {
190
- cbs?.onStatus?.("error", `Could not auto-switch to ${networkName}`);
191
- console.log(`\n⚠ Could not auto-switch to ${networkName}. IMPORTANT: Switch to ${networkName} in your wallet NOW before approving the next transaction.`);
192
- console.log(` Otherwise the transaction will go to Ethereum mainnet and fail.`);
193
- // Give user 5 seconds to read the warning and switch
194
- await new Promise(r => setTimeout(r, 5000));
195
- }
196
-
197
- cbs?.onStatus?.("ready", account);
198
-
199
- // Persist session (WC sessions last 7 days by default)
200
- const expiry = Math.floor(Date.now() / 1000) + 7 * 24 * 60 * 60;
201
- saveWCSession(config, { topic: session.topic, expiry, account, chainId });
202
-
203
- return { client, session, account };
204
- }
205
-
206
- /**
207
- * Step 2 of the two-step flow: send a transaction with an established session.
208
- * Returns the transaction hash.
209
- */
210
- export async function sendTransactionWithSession(
211
- client: SignClientT,
212
- session: WCSession,
213
- account: string,
214
- chainId: number,
215
- tx: { to: string; data: string; value?: string }
216
- ): Promise<string> {
217
- return client.request<string>({
218
- topic: session.topic,
219
- chainId: `eip155:${chainId}`,
220
- request: {
221
- method: "eth_sendTransaction",
222
- params: [{ from: account, to: tx.to, data: tx.data, value: tx.value ?? "0x0" }],
223
- },
224
- });
225
- }
226
-
227
- /**
228
- * Convenience wrapper: connect + send in one call.
229
- * Used by commands that haven't been split into two steps (e.g. policy set-limit).
230
- */
231
- export async function requestPhoneWalletSignature(
232
- projectId: string,
233
- chainId: number,
234
- buildTx: (account: string) => { to: string; data: string; value?: string },
235
- prompt: string,
236
- telegramOpts?: TelegramOpts,
237
- config?: Arc402Config
238
- ): Promise<{ txHash: string; account: string }> {
239
- if (!config) {
240
- // Legacy path: no session persistence, disconnect after use
241
- const client = await makeSignClient(projectId);
242
- const { uri, approval } = await client.connect({
243
- requiredNamespaces: {
244
- eip155: {
245
- methods: ["eth_sendTransaction", "personal_sign", "wallet_switchEthereumChain"],
246
- chains: [`eip155:${chainId}`],
247
- events: ["accountsChanged"],
248
- },
249
- },
250
- });
251
- if (!uri) throw new Error("Failed to create WalletConnect session");
252
- const encodedUri = encodeURIComponent(uri);
253
- const links = walletLinks(encodedUri);
254
- console.log(`\n${prompt}`);
255
- console.log("─────────────────────────────────────");
256
- console.log("Tap the link for your wallet app (opens directly):\n");
257
- for (const [name, link] of Object.entries(links)) console.log(`${name}:\n${link}\n`);
258
- console.log("Or scan QR:");
259
- printQR(uri);
260
- console.log("\nWaiting for approval...");
261
- if (telegramOpts) {
262
- await sendWalletConnectApprovalButton({
263
- botToken: telegramOpts.botToken,
264
- chatId: telegramOpts.chatId,
265
- threadId: telegramOpts.threadId,
266
- prompt,
267
- walletLinks: [
268
- { label: "🦊 MetaMask", url: `https://metamask.app.link/wc?uri=${encodedUri}` },
269
- { label: "🌈 Rainbow", url: `https://rnbwapp.com/wc?uri=${encodedUri}` },
270
- { label: "🔵 Trust Wallet", url: `https://link.trustwallet.com/wc?uri=${encodedUri}` },
271
- ],
272
- });
273
- console.log("Approval request sent to Telegram ✓");
274
- }
275
- const session = await approval();
276
- const account = session.namespaces.eip155.accounts[0].split(":")[2];
277
- // Switch chain — retry up to 3 times
278
- const hexId = `0x${chainId.toString(16)}`;
279
- let switched = false;
280
- for (let i = 0; i < 3; i++) {
281
- try {
282
- await client.request({
283
- topic: session.topic,
284
- chainId: `eip155:${chainId}`,
285
- request: { method: "wallet_switchEthereumChain", params: [{ chainId: hexId }] },
286
- });
287
- switched = true;
288
- break;
289
- } catch { await new Promise(r => setTimeout(r, 1000)); }
290
- }
291
- if (!switched) {
292
- const net = chainId === 8453 ? "Base" : chainId === 84532 ? "Base Sepolia" : `chain ${chainId}`;
293
- console.log(`\n⚠ Could not auto-switch chain. Please switch to ${net} manually in your wallet before approving.`);
294
- }
295
- const tx = buildTx(account);
296
- const txHash = await client.request<string>({
297
- topic: session.topic,
298
- chainId: `eip155:${chainId}`,
299
- request: { method: "eth_sendTransaction", params: [{ from: account, to: tx.to, data: tx.data, value: tx.value ?? "0x0" }] },
300
- });
301
- await client.disconnect({ topic: session.topic, reason: { code: 0, message: "done" } });
302
- return { txHash, account };
303
- }
304
-
305
- const { client, session, account } = await connectPhoneWallet(projectId, chainId, config, { telegramOpts, prompt });
306
- const tx = buildTx(account);
307
- const txHash = await sendTransactionWithSession(client, session, account, chainId, tx);
308
- return { txHash, account };
309
- }
package/test/time.test.js DELETED
@@ -1,11 +0,0 @@
1
- const test = require('node:test');
2
- const assert = require('node:assert/strict');
3
- const { parseDuration } = require('../dist/utils/time');
4
-
5
- test('parseDuration supports hours and days', () => {
6
- const now = Math.floor(Date.now() / 1000);
7
- const twoHours = parseDuration('2h');
8
- const sevenDays = parseDuration('7d');
9
- assert.ok(twoHours > now + 7100 && twoHours < now + 7300);
10
- assert.ok(sevenDays > now + 604000 && sevenDays < now + 605000);
11
- });
package/tsconfig.json DELETED
@@ -1,33 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "NodeNext",
5
- "moduleResolution": "NodeNext",
6
- "lib": [
7
- "ES2022"
8
- ],
9
- "jsx": "react-jsx",
10
- "outDir": "./dist",
11
- "rootDir": "./src",
12
- "strict": true,
13
- "esModuleInterop": true,
14
- "skipLibCheck": true,
15
- "forceConsistentCasingInFileNames": true,
16
- "resolveJsonModule": true,
17
- "declaration": true,
18
- "declarationMap": true,
19
- "sourceMap": true,
20
- "paths": {
21
- "ethers": [
22
- "./node_modules/ethers/lib.commonjs/index.d.ts"
23
- ]
24
- }
25
- },
26
- "include": [
27
- "src/**/*"
28
- ],
29
- "exclude": [
30
- "node_modules",
31
- "dist"
32
- ]
33
- }