arc402-cli 0.7.4 → 0.8.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 (256) hide show
  1. package/MIGRATION-SPEC.md +108 -0
  2. package/dist/abis.js +14 -17
  3. package/dist/abis.js.map +1 -1
  4. package/dist/bundler.d.ts +1 -1
  5. package/dist/bundler.d.ts.map +1 -1
  6. package/dist/bundler.js +27 -61
  7. package/dist/bundler.js.map +1 -1
  8. package/dist/client.d.ts +1 -1
  9. package/dist/client.d.ts.map +1 -1
  10. package/dist/client.js +5 -9
  11. package/dist/client.js.map +1 -1
  12. package/dist/coinbase-smart-wallet.js +1 -4
  13. package/dist/coinbase-smart-wallet.js.map +1 -1
  14. package/dist/commands/accept.js +25 -28
  15. package/dist/commands/accept.js.map +1 -1
  16. package/dist/commands/agent-handshake.js +15 -18
  17. package/dist/commands/agent-handshake.js.map +1 -1
  18. package/dist/commands/agent.js +98 -104
  19. package/dist/commands/agent.js.map +1 -1
  20. package/dist/commands/agreements.js +62 -98
  21. package/dist/commands/agreements.js.map +1 -1
  22. package/dist/commands/arbitrator.js +45 -81
  23. package/dist/commands/arbitrator.js.map +1 -1
  24. package/dist/commands/arena-handshake.js +27 -30
  25. package/dist/commands/arena-handshake.js.map +1 -1
  26. package/dist/commands/arena.js +12 -18
  27. package/dist/commands/arena.js.map +1 -1
  28. package/dist/commands/backup.js +30 -36
  29. package/dist/commands/backup.js.map +1 -1
  30. package/dist/commands/cancel.js +15 -18
  31. package/dist/commands/cancel.js.map +1 -1
  32. package/dist/commands/channel.js +45 -81
  33. package/dist/commands/channel.js.map +1 -1
  34. package/dist/commands/coldstart.js +31 -34
  35. package/dist/commands/coldstart.js.map +1 -1
  36. package/dist/commands/config.js +23 -29
  37. package/dist/commands/config.js.map +1 -1
  38. package/dist/commands/contract-interaction.js +12 -15
  39. package/dist/commands/contract-interaction.js.map +1 -1
  40. package/dist/commands/daemon.d.ts.map +1 -1
  41. package/dist/commands/daemon.js +98 -135
  42. package/dist/commands/daemon.js.map +1 -1
  43. package/dist/commands/deliver.js +37 -76
  44. package/dist/commands/deliver.js.map +1 -1
  45. package/dist/commands/discover.js +24 -27
  46. package/dist/commands/discover.js.map +1 -1
  47. package/dist/commands/dispute.js +104 -110
  48. package/dist/commands/dispute.js.map +1 -1
  49. package/dist/commands/doctor.js +16 -55
  50. package/dist/commands/doctor.js.map +1 -1
  51. package/dist/commands/endpoint.js +56 -95
  52. package/dist/commands/endpoint.js.map +1 -1
  53. package/dist/commands/feed.js +11 -18
  54. package/dist/commands/feed.js.map +1 -1
  55. package/dist/commands/hire.js +37 -40
  56. package/dist/commands/hire.js.map +1 -1
  57. package/dist/commands/migrate.js +30 -33
  58. package/dist/commands/migrate.js.map +1 -1
  59. package/dist/commands/negotiate.d.ts.map +1 -1
  60. package/dist/commands/negotiate.js +34 -36
  61. package/dist/commands/negotiate.js.map +1 -1
  62. package/dist/commands/openshell.js +68 -104
  63. package/dist/commands/openshell.js.map +1 -1
  64. package/dist/commands/owner.js +17 -20
  65. package/dist/commands/owner.js.map +1 -1
  66. package/dist/commands/policy.js +41 -43
  67. package/dist/commands/policy.js.map +1 -1
  68. package/dist/commands/relay.d.ts.map +1 -1
  69. package/dist/commands/relay.js +18 -51
  70. package/dist/commands/relay.js.map +1 -1
  71. package/dist/commands/remediate.js +20 -23
  72. package/dist/commands/remediate.js.map +1 -1
  73. package/dist/commands/reputation.js +25 -27
  74. package/dist/commands/reputation.js.map +1 -1
  75. package/dist/commands/setup.js +65 -104
  76. package/dist/commands/setup.js.map +1 -1
  77. package/dist/commands/trust.js +17 -20
  78. package/dist/commands/trust.js.map +1 -1
  79. package/dist/commands/verify.js +18 -21
  80. package/dist/commands/verify.js.map +1 -1
  81. package/dist/commands/wallet.js +619 -625
  82. package/dist/commands/wallet.js.map +1 -1
  83. package/dist/commands/watch.js +33 -36
  84. package/dist/commands/watch.js.map +1 -1
  85. package/dist/commands/watchtower.js +37 -73
  86. package/dist/commands/watchtower.js.map +1 -1
  87. package/dist/commands/workroom.d.ts.map +1 -1
  88. package/dist/commands/workroom.js +138 -171
  89. package/dist/commands/workroom.js.map +1 -1
  90. package/dist/config.js +21 -65
  91. package/dist/config.js.map +1 -1
  92. package/dist/daemon/config.d.ts.map +1 -1
  93. package/dist/daemon/config.js +16 -53
  94. package/dist/daemon/config.js.map +1 -1
  95. package/dist/daemon/hire-listener.d.ts +3 -3
  96. package/dist/daemon/hire-listener.d.ts.map +1 -1
  97. package/dist/daemon/hire-listener.js +13 -47
  98. package/dist/daemon/hire-listener.js.map +1 -1
  99. package/dist/daemon/index.d.ts +1 -1
  100. package/dist/daemon/index.d.ts.map +1 -1
  101. package/dist/daemon/index.js +50 -88
  102. package/dist/daemon/index.js.map +1 -1
  103. package/dist/daemon/job-lifecycle.d.ts +1 -1
  104. package/dist/daemon/job-lifecycle.d.ts.map +1 -1
  105. package/dist/daemon/job-lifecycle.js +11 -51
  106. package/dist/daemon/job-lifecycle.js.map +1 -1
  107. package/dist/daemon/notify.d.ts +1 -1
  108. package/dist/daemon/notify.d.ts.map +1 -1
  109. package/dist/daemon/notify.js +19 -53
  110. package/dist/daemon/notify.js.map +1 -1
  111. package/dist/daemon/token-metering.js +8 -47
  112. package/dist/daemon/token-metering.js.map +1 -1
  113. package/dist/daemon/userops.d.ts +2 -2
  114. package/dist/daemon/userops.d.ts.map +1 -1
  115. package/dist/daemon/userops.js +23 -27
  116. package/dist/daemon/userops.js.map +1 -1
  117. package/dist/daemon/wallet-monitor.d.ts +1 -1
  118. package/dist/daemon/wallet-monitor.d.ts.map +1 -1
  119. package/dist/daemon/wallet-monitor.js +8 -12
  120. package/dist/daemon/wallet-monitor.js.map +1 -1
  121. package/dist/drain-v4.js +26 -64
  122. package/dist/drain-v4.js.map +1 -1
  123. package/dist/endpoint-config.js +20 -63
  124. package/dist/endpoint-config.js.map +1 -1
  125. package/dist/endpoint-notify.js +9 -48
  126. package/dist/endpoint-notify.js.map +1 -1
  127. package/dist/index.js +16 -50
  128. package/dist/index.js.map +1 -1
  129. package/dist/openshell-runtime.d.ts.map +1 -1
  130. package/dist/openshell-runtime.js +38 -82
  131. package/dist/openshell-runtime.js.map +1 -1
  132. package/dist/program.d.ts.map +1 -1
  133. package/dist/program.js +77 -83
  134. package/dist/program.js.map +1 -1
  135. package/dist/repl.js +25 -31
  136. package/dist/repl.js.map +1 -1
  137. package/dist/signing.js +3 -6
  138. package/dist/signing.js.map +1 -1
  139. package/dist/telegram-notify.js +3 -40
  140. package/dist/telegram-notify.js.map +1 -1
  141. package/dist/tui/App.d.ts.map +1 -1
  142. package/dist/tui/App.js +44 -50
  143. package/dist/tui/App.js.map +1 -1
  144. package/dist/tui/Footer.js +4 -7
  145. package/dist/tui/Footer.js.map +1 -1
  146. package/dist/tui/Header.js +7 -13
  147. package/dist/tui/Header.js.map +1 -1
  148. package/dist/tui/InputLine.js +17 -23
  149. package/dist/tui/InputLine.js.map +1 -1
  150. package/dist/tui/Viewport.js +5 -8
  151. package/dist/tui/Viewport.js.map +1 -1
  152. package/dist/tui/WalletConnectPairing.d.ts +23 -0
  153. package/dist/tui/WalletConnectPairing.d.ts.map +1 -0
  154. package/dist/tui/WalletConnectPairing.js +75 -0
  155. package/dist/tui/WalletConnectPairing.js.map +1 -0
  156. package/dist/tui/index.d.ts.map +1 -1
  157. package/dist/tui/index.js +14 -21
  158. package/dist/tui/index.js.map +1 -1
  159. package/dist/tui/useChat.js +13 -19
  160. package/dist/tui/useChat.js.map +1 -1
  161. package/dist/tui/useCommand.js +12 -18
  162. package/dist/tui/useCommand.js.map +1 -1
  163. package/dist/tui/useScroll.js +9 -12
  164. package/dist/tui/useScroll.js.map +1 -1
  165. package/dist/ui/banner.js +12 -19
  166. package/dist/ui/banner.js.map +1 -1
  167. package/dist/ui/colors.js +13 -19
  168. package/dist/ui/colors.js.map +1 -1
  169. package/dist/ui/format.js +6 -14
  170. package/dist/ui/format.js.map +1 -1
  171. package/dist/ui/spinner.js +6 -12
  172. package/dist/ui/spinner.js.map +1 -1
  173. package/dist/ui/tree.js +3 -6
  174. package/dist/ui/tree.js.map +1 -1
  175. package/dist/utils/format.js +27 -41
  176. package/dist/utils/format.js.map +1 -1
  177. package/dist/utils/hash.js +4 -42
  178. package/dist/utils/hash.js.map +1 -1
  179. package/dist/utils/time.js +2 -6
  180. package/dist/utils/time.js.map +1 -1
  181. package/dist/wallet-router.d.ts +1 -1
  182. package/dist/wallet-router.d.ts.map +1 -1
  183. package/dist/wallet-router.js +12 -19
  184. package/dist/wallet-router.js.map +1 -1
  185. package/dist/walletconnect-session.d.ts +1 -1
  186. package/dist/walletconnect-session.d.ts.map +1 -1
  187. package/dist/walletconnect-session.js +6 -11
  188. package/dist/walletconnect-session.js.map +1 -1
  189. package/dist/walletconnect.d.ts +6 -1
  190. package/dist/walletconnect.d.ts.map +1 -1
  191. package/dist/walletconnect.js +32 -35
  192. package/dist/walletconnect.js.map +1 -1
  193. package/package.json +7 -6
  194. package/src/bundler.ts +1 -1
  195. package/src/client.ts +1 -1
  196. package/src/commands/accept.ts +7 -7
  197. package/src/commands/agent-handshake.ts +4 -4
  198. package/src/commands/agent.ts +9 -9
  199. package/src/commands/agreements.ts +8 -8
  200. package/src/commands/arbitrator.ts +5 -5
  201. package/src/commands/arena-handshake.ts +6 -6
  202. package/src/commands/arena.ts +2 -2
  203. package/src/commands/backup.ts +1 -1
  204. package/src/commands/cancel.ts +6 -6
  205. package/src/commands/channel.ts +6 -6
  206. package/src/commands/coldstart.ts +5 -5
  207. package/src/commands/config.ts +2 -2
  208. package/src/commands/contract-interaction.ts +2 -2
  209. package/src/commands/daemon.ts +14 -11
  210. package/src/commands/deliver.ts +9 -9
  211. package/src/commands/discover.ts +5 -5
  212. package/src/commands/dispute.ts +7 -7
  213. package/src/commands/doctor.ts +2 -2
  214. package/src/commands/endpoint.ts +6 -6
  215. package/src/commands/feed.ts +1 -1
  216. package/src/commands/hire.ts +10 -10
  217. package/src/commands/migrate.ts +7 -7
  218. package/src/commands/negotiate.ts +6 -5
  219. package/src/commands/openshell.ts +4 -4
  220. package/src/commands/owner.ts +5 -5
  221. package/src/commands/policy.ts +5 -5
  222. package/src/commands/relay.ts +5 -1
  223. package/src/commands/remediate.ts +5 -5
  224. package/src/commands/reputation.ts +6 -6
  225. package/src/commands/setup.ts +1 -1
  226. package/src/commands/trust.ts +6 -6
  227. package/src/commands/verify.ts +6 -6
  228. package/src/commands/wallet.ts +15 -15
  229. package/src/commands/watch.ts +3 -3
  230. package/src/commands/watchtower.ts +6 -6
  231. package/src/commands/workroom.ts +14 -10
  232. package/src/daemon/config.ts +2 -1
  233. package/src/daemon/hire-listener.ts +3 -3
  234. package/src/daemon/index.ts +10 -9
  235. package/src/daemon/job-lifecycle.ts +1 -1
  236. package/src/daemon/notify.ts +4 -4
  237. package/src/daemon/userops.ts +4 -4
  238. package/src/daemon/wallet-monitor.ts +2 -2
  239. package/src/endpoint-notify.ts +1 -1
  240. package/src/index.ts +8 -7
  241. package/src/openshell-runtime.ts +5 -1
  242. package/src/program.ts +36 -36
  243. package/src/repl.ts +3 -3
  244. package/src/tui/App.tsx +15 -10
  245. package/src/tui/Header.tsx +1 -1
  246. package/src/tui/InputLine.tsx +1 -1
  247. package/src/tui/WalletConnectPairing.tsx +131 -0
  248. package/src/tui/index.tsx +7 -8
  249. package/src/tui/useChat.ts +1 -1
  250. package/src/tui/useCommand.ts +4 -4
  251. package/src/ui/banner.ts +2 -2
  252. package/src/ui/tree.ts +1 -1
  253. package/src/wallet-router.ts +2 -2
  254. package/src/walletconnect-session.ts +1 -1
  255. package/src/walletconnect.ts +20 -5
  256. package/tsconfig.json +16 -7
@@ -1,7 +1,7 @@
1
1
  import React, { useState, useCallback } from "react";
2
2
  import { Box, Text, useInput } from "ink";
3
3
  import TextInput from "ink-text-input";
4
- import { createProgram } from "../program";
4
+ import { createProgram } from "../program.js";
5
5
 
6
6
  const BUILTIN_CMDS = ["help", "exit", "quit", "clear", "status"];
7
7
 
@@ -0,0 +1,131 @@
1
+ import React, { useState, useEffect, useCallback } from "react";
2
+ import { Box, Text } from "ink";
3
+ import type { WCCallbacks } from "../walletconnect.js";
4
+
5
+ export type WCStage = "connecting" | "connected" | "chain-switching" | "ready" | "error";
6
+
7
+ interface WalletConnectPairingProps {
8
+ projectId: string;
9
+ chainId: number;
10
+ onComplete: (result: { account: string }) => void;
11
+ onError: (err: string) => void;
12
+ /** Called once the component mounts — parent passes the connect function */
13
+ connect: (callbacks: WCCallbacks) => Promise<{ account: string }>;
14
+ }
15
+
16
+ /**
17
+ * Renders WalletConnect pairing inside the Ink TUI viewport:
18
+ * - ASCII QR code
19
+ * - Deep links for MetaMask, Rainbow, Trust, etc.
20
+ * - Status transitions: connecting → connected → chain-switching → ready
21
+ */
22
+ export function WalletConnectPairing({
23
+ onComplete,
24
+ onError,
25
+ connect,
26
+ }: WalletConnectPairingProps) {
27
+ const [stage, setStage] = useState<WCStage>("connecting");
28
+ const [uri, setUri] = useState<string | null>(null);
29
+ const [links, setLinks] = useState<Record<string, string>>({});
30
+ const [account, setAccount] = useState<string | null>(null);
31
+ const [qrLines, setQrLines] = useState<string[]>([]);
32
+ const [detail, setDetail] = useState<string>("");
33
+
34
+ const handleUri = useCallback((wcUri: string, wcLinks: Record<string, string>) => {
35
+ setUri(wcUri);
36
+ setLinks(wcLinks);
37
+ // Generate ASCII QR
38
+ try {
39
+ // qrcode-terminal writes to stdout — capture it
40
+ const origWrite = process.stdout.write.bind(process.stdout);
41
+ const captured: string[] = [];
42
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
43
+ (process.stdout as any).write = (chunk: string | Uint8Array) => {
44
+ const str = typeof chunk === "string" ? chunk : Buffer.from(chunk).toString("utf8");
45
+ captured.push(str);
46
+ return true;
47
+ };
48
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
49
+ import("qrcode-terminal").then((qr) => {
50
+ qr.default.generate(wcUri, { small: true }, (code: string) => {
51
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
52
+ (process.stdout as any).write = origWrite;
53
+ setQrLines(code.split("\n"));
54
+ });
55
+ }).catch(() => {
56
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
57
+ (process.stdout as any).write = origWrite;
58
+ });
59
+ } catch {
60
+ // QR rendering is best-effort
61
+ }
62
+ }, []);
63
+
64
+ const handleStatus = useCallback((status: WCStage, statusDetail?: string) => {
65
+ setStage(status);
66
+ if (statusDetail) setDetail(statusDetail);
67
+ if (status === "connected" && statusDetail) {
68
+ setAccount(statusDetail);
69
+ }
70
+ }, []);
71
+
72
+ useEffect(() => {
73
+ const callbacks: WCCallbacks = {
74
+ onUri: handleUri,
75
+ onStatus: handleStatus,
76
+ };
77
+ connect(callbacks)
78
+ .then((result) => onComplete(result))
79
+ .catch((err: unknown) => onError(err instanceof Error ? err.message : String(err)));
80
+ }, [connect, handleUri, handleStatus, onComplete, onError]);
81
+
82
+ const statusIcon = stage === "error" ? "✗" : stage === "ready" ? "✓" : "◈";
83
+ const statusColor = stage === "error" ? "red" : stage === "ready" ? "green" : "cyan";
84
+
85
+ const statusMessages: Record<WCStage, string> = {
86
+ connecting: "Waiting for wallet approval...",
87
+ connected: `Connected: ${account ?? ""}`,
88
+ "chain-switching": `Switching chain${detail ? `: ${detail}` : ""}...`,
89
+ ready: `Ready — ${account ?? ""}`,
90
+ error: detail || "Connection failed",
91
+ };
92
+
93
+ return (
94
+ <Box flexDirection="column" paddingLeft={1}>
95
+ <Text color="cyan" bold>WalletConnect Pairing</Text>
96
+ <Text> </Text>
97
+
98
+ {/* Status */}
99
+ <Box>
100
+ <Text color={statusColor}>{statusIcon} </Text>
101
+ <Text>{statusMessages[stage]}</Text>
102
+ </Box>
103
+ <Text> </Text>
104
+
105
+ {/* Deep links */}
106
+ {uri && stage === "connecting" && (
107
+ <>
108
+ <Text dimColor>Tap a link for your wallet app:</Text>
109
+ <Text> </Text>
110
+ {Object.entries(links).map(([name, link]) => (
111
+ <Box key={name} flexDirection="column">
112
+ <Text color="white">{name}:</Text>
113
+ <Text dimColor>{link}</Text>
114
+ <Text> </Text>
115
+ </Box>
116
+ ))}
117
+
118
+ {/* QR code */}
119
+ {qrLines.length > 0 && (
120
+ <>
121
+ <Text dimColor>Or scan QR:</Text>
122
+ {qrLines.map((line, i) => (
123
+ <Text key={i}>{line}</Text>
124
+ ))}
125
+ </>
126
+ )}
127
+ </>
128
+ )}
129
+ </Box>
130
+ );
131
+ }
package/src/tui/index.tsx CHANGED
@@ -1,12 +1,12 @@
1
1
  import React from "react";
2
2
  import { render } from "ink";
3
- import { App } from "./App";
4
- import fs from "fs";
5
- import path from "path";
6
- import os from "os";
3
+ import { App } from "./App.js";
4
+ import fs from "node:fs";
5
+ import path from "node:path";
6
+ import os from "node:os";
7
+ import { createRequire } from "node:module";
7
8
 
8
- // eslint-disable-next-line @typescript-eslint/no-var-requires
9
- const pkg = require("../../package.json") as { version: string };
9
+ const pkg = createRequire(import.meta.url)("../../package.json") as { version: string };
10
10
 
11
11
  const CONFIG_PATH = path.join(os.homedir(), ".arc402", "config.json");
12
12
 
@@ -30,8 +30,7 @@ async function getBalance(
30
30
  address: string
31
31
  ): Promise<string | undefined> {
32
32
  try {
33
- // eslint-disable-next-line @typescript-eslint/no-var-requires
34
- const ethersLib = require("ethers") as typeof import("ethers");
33
+ const ethersLib = await import("ethers");
35
34
  const provider = new ethersLib.ethers.JsonRpcProvider(rpcUrl);
36
35
  const bal = await Promise.race([
37
36
  provider.getBalance(address),
@@ -1,6 +1,6 @@
1
1
  import { useState, useCallback } from "react";
2
2
  import chalk from "chalk";
3
- import { c } from "../ui/colors";
3
+ import { c } from "../ui/colors.js";
4
4
 
5
5
  interface UseChatResult {
6
6
  send: (message: string, onLine: (line: string) => void) => Promise<void>;
@@ -1,7 +1,7 @@
1
1
  import { useState, useCallback } from "react";
2
- import { createProgram } from "../program";
2
+ import { createProgram } from "../program.js";
3
3
  import chalk from "chalk";
4
- import { c } from "../ui/colors";
4
+ import { c } from "../ui/colors.js";
5
5
 
6
6
  interface UseCommandResult {
7
7
  execute: (input: string, onLine: (line: string) => void) => Promise<void>;
@@ -64,8 +64,8 @@ export function useCommand(): UseCommandResult {
64
64
  const prog = createProgram();
65
65
  prog.exitOverride();
66
66
  prog.configureOutput({
67
- writeOut: (str) => process.stdout.write(str),
68
- writeErr: (str) => process.stderr.write(str),
67
+ writeOut: (str: string) => process.stdout.write(str),
68
+ writeErr: (str: string) => process.stderr.write(str),
69
69
  });
70
70
 
71
71
  await prog.parseAsync(["node", "arc402", ...tokens]);
package/src/ui/banner.ts CHANGED
@@ -1,7 +1,7 @@
1
+ import { createRequire } from "node:module";
1
2
  import chalk from "chalk";
2
3
 
3
- // eslint-disable-next-line @typescript-eslint/no-var-requires
4
- const _pkg = require("../../package.json") as { version: string };
4
+ const _pkg = createRequire(import.meta.url)("../../package.json") as { version: string };
5
5
 
6
6
  const ART = `
7
7
  ██████╗ ██████╗ ██████╗ ██╗ ██╗ ██████╗ ██████╗
package/src/ui/tree.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { c } from "./colors";
1
+ import { c } from "./colors.js";
2
2
 
3
3
  export interface TreeItem {
4
4
  label: string;
@@ -1,6 +1,6 @@
1
1
  import { ethers } from "ethers";
2
- import { Arc402Config } from "./config";
3
- import { ARC402_WALLET_EXECUTE_ABI } from "./abis";
2
+ import { Arc402Config } from "./config.js";
3
+ import { ARC402_WALLET_EXECUTE_ABI } from "./abis.js";
4
4
 
5
5
  // ─── ARC402Wallet custom error decoder ─────────────────────────────────────
6
6
 
@@ -1,4 +1,4 @@
1
- import { Arc402Config, saveConfig } from "./config";
1
+ import { Arc402Config, saveConfig } from "./config.js";
2
2
 
3
3
  export interface WCSessionData {
4
4
  topic: string;
@@ -3,9 +3,9 @@ import { KeyValueStorage } from "@walletconnect/keyvaluestorage";
3
3
  import qrcode from "qrcode-terminal";
4
4
  import path from "path";
5
5
  import os from "os";
6
- import { Arc402Config } from "./config";
7
- import { loadWCSession, saveWCSession, clearWCSession } from "./walletconnect-session";
8
- import { sendWalletConnectApprovalButton } from "./telegram-notify";
6
+ import { Arc402Config } from "./config.js";
7
+ import { loadWCSession, saveWCSession, clearWCSession } from "./walletconnect-session.js";
8
+ import { sendWalletConnectApprovalButton } from "./telegram-notify.js";
9
9
 
10
10
  // Suppress unhandled rejections from stale WalletConnect sessions (known SDK issue)
11
11
  process.on("unhandledRejection", (reason: unknown) => {
@@ -54,11 +54,16 @@ function walletLinks(encodedUri: string) {
54
54
  * On fresh connect, shows deep links + QR and waits for WC approval.
55
55
  * Saves session to config after a successful fresh pairing.
56
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
+
57
62
  export async function connectPhoneWallet(
58
63
  projectId: string,
59
64
  chainId: number,
60
65
  config: Arc402Config,
61
- opts?: { telegramOpts?: TelegramOpts; prompt?: string; hardware?: boolean }
66
+ opts?: { telegramOpts?: TelegramOpts; prompt?: string; hardware?: boolean; callbacks?: WCCallbacks }
62
67
  ): Promise<{ client: SignClientT; session: WCSession; account: string }> {
63
68
  const client = await makeSignClient(projectId);
64
69
 
@@ -99,8 +104,13 @@ export async function connectPhoneWallet(
99
104
 
100
105
  const encodedUri = encodeURIComponent(uri);
101
106
  const displayPrompt = opts?.prompt ?? "Connect your phone wallet";
107
+ const cbs = opts?.callbacks;
102
108
 
103
- if (opts?.hardware) {
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) {
104
114
  console.log("\n─────────────────────────────────────────────────────");
105
115
  console.log("Paste this URI into Ledger Live, Trezor Suite, or any WalletConnect-compatible signer:\n");
106
116
  console.log(uri);
@@ -137,10 +147,12 @@ export async function connectPhoneWallet(
137
147
 
138
148
  const session = await approval();
139
149
  const account = session.namespaces.eip155.accounts[0].split(":")[2];
150
+ cbs?.onStatus?.("connected", account);
140
151
 
141
152
  // Ensure wallet is on the correct chain before sending any tx
142
153
  const hexChainId = `0x${chainId.toString(16)}`;
143
154
  const networkName = chainId === 8453 ? "Base" : chainId === 84532 ? "Base Sepolia" : `chain ${chainId}`;
155
+ cbs?.onStatus?.("chain-switching", networkName);
144
156
 
145
157
  // First try adding the chain (MetaMask ignores if already added)
146
158
  if (chainId === 8453) {
@@ -175,12 +187,15 @@ export async function connectPhoneWallet(
175
187
  }
176
188
  }
177
189
  if (!chainSwitched) {
190
+ cbs?.onStatus?.("error", `Could not auto-switch to ${networkName}`);
178
191
  console.log(`\n⚠ Could not auto-switch to ${networkName}. IMPORTANT: Switch to ${networkName} in your wallet NOW before approving the next transaction.`);
179
192
  console.log(` Otherwise the transaction will go to Ethereum mainnet and fail.`);
180
193
  // Give user 5 seconds to read the warning and switch
181
194
  await new Promise(r => setTimeout(r, 5000));
182
195
  }
183
196
 
197
+ cbs?.onStatus?.("ready", account);
198
+
184
199
  // Persist session (WC sessions last 7 days by default)
185
200
  const expiry = Math.floor(Date.now() / 1000) + 7 * 24 * 60 * 60;
186
201
  saveWCSession(config, { topic: session.topic, expiry, account, chainId });
package/tsconfig.json CHANGED
@@ -1,8 +1,11 @@
1
1
  {
2
2
  "compilerOptions": {
3
- "target": "ES2020",
4
- "module": "commonjs",
5
- "lib": ["ES2020"],
3
+ "target": "ES2022",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "NodeNext",
6
+ "lib": [
7
+ "ES2022"
8
+ ],
6
9
  "jsx": "react-jsx",
7
10
  "outDir": "./dist",
8
11
  "rootDir": "./src",
@@ -15,10 +18,16 @@
15
18
  "declarationMap": true,
16
19
  "sourceMap": true,
17
20
  "paths": {
18
- "ink": ["./node_modules/ink/build/index.d.ts"],
19
- "ink-text-input": ["./node_modules/ink-text-input/build/index.d.ts"]
21
+ "ethers": [
22
+ "./node_modules/ethers/lib.commonjs/index.d.ts"
23
+ ]
20
24
  }
21
25
  },
22
- "include": ["src/**/*"],
23
- "exclude": ["node_modules", "dist"]
26
+ "include": [
27
+ "src/**/*"
28
+ ],
29
+ "exclude": [
30
+ "node_modules",
31
+ "dist"
32
+ ]
24
33
  }