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
package/src/config.ts DELETED
@@ -1,220 +0,0 @@
1
- import * as fs from "fs";
2
- import * as path from "path";
3
- import * as os from "os";
4
- import { randomUUID } from "crypto";
5
-
6
- export interface Arc402Config {
7
- network: "base-mainnet" | "base-sepolia";
8
- rpcUrl: string;
9
- privateKey?: string;
10
- guardianPrivateKey?: string;
11
- guardianAddress?: string;
12
- walletConnectProjectId?: string;
13
- ownerAddress?: string;
14
- agentRegistryAddress?: string;
15
- agentRegistryV2Address?: string;
16
- serviceAgreementAddress?: string;
17
- disputeArbitrationAddress?: string;
18
- disputeModuleAddress?: string;
19
- trustRegistryAddress: string;
20
- trustRegistryV2Address?: string;
21
- intentAttestationAddress?: string;
22
- settlementCoordinatorAddress?: string;
23
- sessionChannelsAddress?: string;
24
- reputationOracleAddress?: string;
25
- sponsorshipAttestationAddress?: string;
26
- capabilityRegistryAddress?: string;
27
- governanceAddress?: string;
28
- agreementTreeAddress?: string;
29
- policyEngineAddress?: string;
30
- walletFactoryAddress?: string;
31
- walletContractAddress?: string;
32
- watchtowerRegistryAddress?: string;
33
- governedTokenWhitelistAddress?: string;
34
- vouchingRegistryAddress?: string;
35
- migrationRegistryAddress?: string;
36
- handshakeAddress?: string;
37
- paymasterUrl?: string; // CDP paymaster endpoint
38
- cdpKeyName?: string; // CDP API key name (org/.../apiKeys/...)
39
- cdpPrivateKey?: string; // CDP EC private key — base64 DER SEC1 (store in CDP_PRIVATE_KEY env var)
40
- subdomainApi?: string; // defaults to https://api.arc402.xyz
41
- telegramBotToken?: string;
42
- telegramChatId?: string;
43
- telegramThreadId?: number;
44
- /** Tracks onboarding progress so `wallet deploy` can resume after interruption. */
45
- onboardingProgress?: {
46
- walletAddress: string;
47
- step: number; // last completed step number (2=machineKey, 3=passkey, 4=policy, 5=agent)
48
- completedSteps: string[];
49
- };
50
- wcSession?: {
51
- topic: string;
52
- expiry: number; // Unix timestamp
53
- account: string; // Phone wallet address
54
- chainId: number;
55
- };
56
- deviceId?: string; // UUID identifying the device this config was created on
57
- lastCliVersion?: string; // Last CLI version that wrote this config (for upgrade detection)
58
- }
59
-
60
- const CONFIG_DIR = path.join(os.homedir(), ".arc402");
61
- const CONFIG_PATH = process.env.ARC402_CONFIG || path.join(CONFIG_DIR, "config.json");
62
- const DEVICE_ID_PATH = path.join(CONFIG_DIR, "device.id");
63
-
64
- // WalletConnect project ID — get your own at cloud.walletconnect.com
65
- const DEFAULT_WC_PROJECT_ID = "455e9425343b9156fce1428250c9a54a";
66
- export const getWcProjectId = () => process.env.WC_PROJECT_ID ?? DEFAULT_WC_PROJECT_ID;
67
-
68
- export const getConfigPath = () => CONFIG_PATH;
69
-
70
- /** Returns this device's stable UUID, creating it on first call. */
71
- function getOrCreateDeviceId(): string {
72
- if (fs.existsSync(DEVICE_ID_PATH)) {
73
- return fs.readFileSync(DEVICE_ID_PATH, "utf-8").trim();
74
- }
75
- const id = randomUUID();
76
- fs.mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
77
- fs.writeFileSync(DEVICE_ID_PATH, id, { mode: 0o600 });
78
- return id;
79
- }
80
-
81
- export function loadConfig(): Arc402Config {
82
- const thisDeviceId = getOrCreateDeviceId();
83
-
84
- if (!fs.existsSync(CONFIG_PATH)) {
85
- // Auto-create with Base Mainnet defaults — zero friction
86
- const defaults = NETWORK_DEFAULTS["base-mainnet"] ?? {};
87
- const d = defaults as unknown as Record<string,string>;
88
- const autoConfig: Arc402Config = {
89
- network: "base-mainnet",
90
- rpcUrl: defaults.rpcUrl ?? "https://mainnet.base.org",
91
- walletConnectProjectId: getWcProjectId(),
92
- ownerAddress: undefined,
93
- policyEngineAddress: defaults.policyEngineAddress,
94
- trustRegistryAddress: defaults.trustRegistryAddress ?? "",
95
- agentRegistryAddress: d.agentRegistryV2Address ?? defaults.agentRegistryAddress,
96
- serviceAgreementAddress: defaults.serviceAgreementAddress,
97
- reputationOracleAddress: defaults.reputationOracleAddress,
98
- sponsorshipAttestationAddress: defaults.sponsorshipAttestationAddress,
99
- capabilityRegistryAddress: defaults.capabilityRegistryAddress,
100
- governanceAddress: defaults.governanceAddress,
101
- walletFactoryAddress: defaults.walletFactoryAddress,
102
- sessionChannelsAddress: defaults.sessionChannelsAddress,
103
- disputeModuleAddress: defaults.disputeModuleAddress,
104
- deviceId: thisDeviceId,
105
- };
106
- saveConfig(autoConfig);
107
- console.log(`◈ Config auto-created at ${CONFIG_PATH} (Base Mainnet)`);
108
- console.log("⚠ Base Mainnet — real funds at risk. Use arc402 config init for testnet.");
109
- return autoConfig;
110
- }
111
-
112
- const config = JSON.parse(fs.readFileSync(CONFIG_PATH, "utf-8")) as Arc402Config;
113
-
114
- // Multi-device awareness: warn if config was created on a different device
115
- if (config.deviceId && config.deviceId !== thisDeviceId) {
116
- console.warn("⚠ This config was created on a different device. Some keys may not work.");
117
- }
118
-
119
- // Backfill deviceId if missing (older config)
120
- if (!config.deviceId) {
121
- config.deviceId = thisDeviceId;
122
- saveConfig(config);
123
- }
124
-
125
- return config;
126
- }
127
-
128
- export function saveConfig(config: Arc402Config): void {
129
- const configDir = path.dirname(CONFIG_PATH);
130
- fs.mkdirSync(configDir, { recursive: true, mode: 0o700 });
131
- fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2), { mode: 0o600 });
132
- if (config.privateKey) {
133
- console.warn("⚠ Private key stored in plaintext at ~/.arc402/config.json");
134
- }
135
- }
136
-
137
- export const configExists = () => fs.existsSync(CONFIG_PATH);
138
-
139
- // Public Base RPC — stale state, do not use for production. Alchemy recommended.
140
- export const PUBLIC_BASE_RPC = "https://mainnet.base.org";
141
- export const ALCHEMY_BASE_RPC = "https://mainnet.base.org";
142
-
143
- /**
144
- * Warn at runtime if the configured RPC is the public Base endpoint.
145
- * Public Base RPC has delayed state propagation — use Alchemy for production.
146
- */
147
- export function warnIfPublicRpc(config: Arc402Config): void {
148
- if (config.rpcUrl === PUBLIC_BASE_RPC || config.rpcUrl === "https://sepolia.base.org") {
149
- console.warn("WARN: Using public Base RPC — state reads may be stale. Set rpcUrl to an Alchemy endpoint for production.");
150
- console.warn(` Recommended: arc402 config set rpcUrl ${ALCHEMY_BASE_RPC}`);
151
- }
152
- }
153
-
154
- export const NETWORK_DEFAULTS: Record<string, Partial<Arc402Config> & { usdcAddress: string }> = {
155
- "base-mainnet": {
156
- rpcUrl: ALCHEMY_BASE_RPC,
157
- usdcAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
158
- paymasterUrl: "https://api.developer.coinbase.com/rpc/v1/base/dca85088-a2ac-4ec3-8647-5154b150e7a9",
159
- // Base Mainnet deployments — v2 deployed 2026-03-15
160
- policyEngineAddress: "0xAA5Ef3489C929bFB3BFf5D5FE15aa62d3763c847",
161
- trustRegistryAddress: "0x22366D6dabb03062Bc0a5E893EfDff15D8E329b1", // TrustRegistryV3 — v2
162
- trustRegistryV2Address: "0xdA1D377991B2E580991B0DD381CdD635dd71aC39", // old v2, kept for reference
163
- intentAttestationAddress: "0x7ad8db6C5f394542E8e9658F86C85cC99Cf6D460",
164
- settlementCoordinatorAddress: "0xd52d8Be9728976E0D70C89db9F8ACeb5B5e97cA2", // SettlementCoordinatorV2
165
- agentRegistryAddress: "0xcc0D8731ccCf6CFfF4e66F6d68cA86330Ea8B622", // ARC402RegistryV2
166
- agentRegistryV2Address: "0xD5c2851B00090c92Ba7F4723FB548bb30C9B6865", // AgentRegistry
167
- walletFactoryAddress: "0xcB52B5d746eEc05e141039E92e3dBefeAe496051", // WalletFactoryV5 — redeployed 2026-03-19 (optimized bytecode, FOUNDRY_PROFILE=deploy)
168
- sponsorshipAttestationAddress: "0xD6c2edE89Ea71aE19Db2Be848e172b444Ed38f22",
169
- serviceAgreementAddress: "0xC98B402CAB9156da68A87a69E3B4bf167A3CCcF6",
170
- sessionChannelsAddress: "0x578f8d1bd82E8D6268E329d664d663B4d985BE61",
171
- disputeModuleAddress: "0x5ebd301cEF0C908AB17Fd183aD9c274E4B34e9d6",
172
- reputationOracleAddress: "0x359F76a54F9A345546E430e4d6665A7dC9DaECd4",
173
- governanceAddress: "0xE931DD2EEb9Af9353Dd5E2c1250492A0135E0EC4", // ARC402Governance
174
- guardianAddress: "0xED0A033B79626cdf9570B6c3baC7f699cD0032D8", // ARC402Guardian
175
- walletContractAddress: "0xfd5C8c0a08fDcdeD2fe03e0DC9FA55595667F313", // ARC402Wallet instance
176
- agreementTreeAddress: "0x6a82240512619B25583b9e95783410cf782915b1",
177
- capabilityRegistryAddress: "0x7becb642668B80502dD957A594E1dD0aC414c1a3",
178
- disputeArbitrationAddress: "0xF61b75E4903fbC81169FeF8b7787C13cB7750601",
179
- governedTokenWhitelistAddress: "0xeB58896337244Bb408362Fea727054f9e7157451",
180
- watchtowerRegistryAddress: "0xbC811d1e3c5C5b67CA57df1DFb08847b1c8c458A",
181
- vouchingRegistryAddress: "0x94519194Bf17865770faD59eF581feC512Ae99c9",
182
- migrationRegistryAddress: "0xb60B62357b90F254f555f03B162a30E22890e3B5",
183
- handshakeAddress: "0x4F5A38Bb746d7E5d49d8fd26CA6beD141Ec2DDb3",
184
- },
185
- "base-sepolia": {
186
- rpcUrl: "https://sepolia.base.org",
187
- usdcAddress: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
188
- // v2 deployment — Base Sepolia (chain 84532) — deployed 2026-03-15
189
- // Unchanged v1 contracts:
190
- policyEngineAddress: "0x44102e70c2A366632d98Fe40d892a2501fC7fFF2",
191
- intentAttestationAddress: "0x942c807Cc6E0240A061e074b61345618aBadc457",
192
- settlementCoordinatorAddress: "0x52b565797975781f069368Df40d6633b2aD03390",
193
- agentRegistryV2Address: "0x07D526f8A8e148570509aFa249EFF295045A0cc9", // AgentRegistry
194
- reputationOracleAddress: "0x410e650113fd163389C956BC7fC51c5642617187",
195
- walletFactoryAddress: "0xD560C22aD5372Aa830ee5ffBFa4a5D9f528e7B87",
196
- sponsorshipAttestationAddress:"0xc0d927745AcF8DEeE551BE11A12c97c492DDC989",
197
- governanceAddress: "0x504b3D73A8dFbcAB9551d8a11Bb0B07C90C4c926",
198
- guardianAddress: "0x5c1D2cD6B9B291b436BF1b109A711F0E477EB6fe",
199
- walletContractAddress: "0xc77854f9091A25eD1f35EA24E9bdFb64d0850E45",
200
- agreementTreeAddress: "0x8F46F31FcEbd60f526308AD20e4a008887709720",
201
- capabilityRegistryAddress: "0x6a413e74b65828A014dD8DA61861Bf9E1b6372D2",
202
- governedTokenWhitelistAddress:"0x64C15CA701167C7c901a8a5575a5232b37CAF213",
203
- watchtowerRegistryAddress: "0x70c4E53E3A916eB8A695630f129B943af9C61C57",
204
- // v2 contracts (new/redeployed 2026-03-15):
205
- trustRegistryAddress: "0xf2aE072BB8575c23B0efbF44bDc8188aA900cA7a", // TrustRegistryV3
206
- agentRegistryAddress: "0x0461b2b7A1E50866962CB07326000A94009c58Ff", // ARC402RegistryV2
207
- serviceAgreementAddress: "0xbbb1DA355D810E9baEF1a7D072B2132E4755976B",
208
- sessionChannelsAddress: "0x5EF144AE2C8456d014e6E3F293c162410C043564",
209
- disputeModuleAddress: "0x01866144495fBBbBB7aaD81605de051B2A62594A",
210
- disputeArbitrationAddress: "0xa4f6F77927Da53a25926A5f0bffBEB0210108cA8",
211
- vouchingRegistryAddress: "0x96432aDc7aC06256297AdF11B94C47f68b2F13A2",
212
- migrationRegistryAddress: "0x3aeAaD32386D6fC40eeb5c2C27a5aCFE6aDf9ABD",
213
- },
214
- };
215
-
216
- export const getUsdcAddress = (config: Arc402Config) => NETWORK_DEFAULTS[config.network]?.usdcAddress ?? "";
217
-
218
- export function getSubdomainApi(config: Arc402Config): string {
219
- return config.subdomainApi ?? "https://api.arc402.xyz";
220
- }
@@ -1,344 +0,0 @@
1
- /**
2
- * Daemon configuration loader.
3
- * Parses ~/.arc402/daemon.toml, enforces env: prefix for secrets,
4
- * resolves env: values from the environment.
5
- */
6
- import * as fs from "fs";
7
- import * as path from "path";
8
- import * as os from "os";
9
- import { ethers } from "ethers";
10
- import { parse as parseToml } from "smol-toml";
11
-
12
- export const DAEMON_DIR = path.join(os.homedir(), ".arc402");
13
- export const DAEMON_TOML = path.join(DAEMON_DIR, "daemon.toml");
14
- export const DAEMON_PID = path.join(DAEMON_DIR, "daemon.pid");
15
- export const DAEMON_LOG = path.join(DAEMON_DIR, "daemon.log");
16
- export const DAEMON_DB = path.join(DAEMON_DIR, "daemon.db");
17
- export const DAEMON_SOCK = path.join(DAEMON_DIR, "daemon.sock");
18
-
19
- export interface DaemonConfig {
20
- wallet: {
21
- contract_address: string;
22
- owner_address: string;
23
- machine_key: string; // must be "env:VAR_NAME"
24
- };
25
- network: {
26
- rpc_url: string;
27
- chain_id: number;
28
- entry_point: string;
29
- };
30
- bundler: {
31
- mode: "external" | "arc402" | "self";
32
- endpoint: string;
33
- earn_fees: boolean;
34
- eth_float: string;
35
- sweep_threshold: string;
36
- sweep_to: string;
37
- rpc_url: string;
38
- };
39
- relay: {
40
- enabled: boolean;
41
- listen_port: number;
42
- endpoint: string;
43
- max_concurrent_agreements: number;
44
- poll_interval_seconds: number;
45
- relay_url: string;
46
- };
47
- watchtower: {
48
- enabled: boolean;
49
- poll_interval_seconds: number;
50
- challenge_confirmation_blocks: number;
51
- external_watchtower_url: string;
52
- update_interval_states: number;
53
- };
54
- policy: {
55
- auto_accept: boolean;
56
- max_price_eth: string;
57
- allowed_capabilities: string[];
58
- require_min_trust_score: number;
59
- min_hire_lead_time_seconds: number;
60
- };
61
- notifications: {
62
- telegram_bot_token: string;
63
- telegram_chat_id: string;
64
- notify_on_hire_request: boolean;
65
- notify_on_hire_accepted: boolean;
66
- notify_on_hire_rejected: boolean;
67
- notify_on_delivery: boolean;
68
- notify_on_dispute: boolean;
69
- notify_on_channel_challenge: boolean;
70
- notify_on_low_balance: boolean;
71
- low_balance_threshold_eth: string;
72
- discord: { webhook_url: string };
73
- webhook: { url: string; headers: Record<string, string> };
74
- email: { smtp_host: string; smtp_port: number; smtp_user: string; smtp_pass: string; to: string };
75
- };
76
- work: {
77
- handler: "exec" | "http" | "noop";
78
- exec_command: string;
79
- http_url: string;
80
- http_auth_token: string;
81
- };
82
- }
83
-
84
- function resolveEnvValue(value: string, field: string): string {
85
- if (!value.startsWith("env:")) return value;
86
- const varName = value.slice(4);
87
- const resolved = process.env[varName];
88
- if (!resolved) {
89
- throw new Error(`Environment variable ${varName} is not set (required for ${field})`);
90
- }
91
- return resolved;
92
- }
93
-
94
- function tryResolveEnvValue(value: string): string {
95
- if (!value.startsWith("env:")) return value;
96
- const varName = value.slice(4);
97
- return process.env[varName] ?? "";
98
- }
99
-
100
- function str(v: unknown, def = ""): string {
101
- return typeof v === "string" ? v : def;
102
- }
103
- function num(v: unknown, def: number): number {
104
- return typeof v === "number" ? v : def;
105
- }
106
- function bool(v: unknown, def: boolean): boolean {
107
- return typeof v === "boolean" ? v : def;
108
- }
109
- function strArr(v: unknown): string[] {
110
- return Array.isArray(v) ? (v as string[]) : [];
111
- }
112
-
113
- function withDefaults(raw: Record<string, unknown>): DaemonConfig {
114
- const w = (raw.wallet as Record<string, unknown>) ?? {};
115
- const n = (raw.network as Record<string, unknown>) ?? {};
116
- const b = (raw.bundler as Record<string, unknown>) ?? {};
117
- const r = (raw.relay as Record<string, unknown>) ?? {};
118
- const wt = (raw.watchtower as Record<string, unknown>) ?? {};
119
- const p = (raw.policy as Record<string, unknown>) ?? {};
120
- const notif = (raw.notifications as Record<string, unknown>) ?? {};
121
- const notifDiscord = (notif.discord as Record<string, unknown>) ?? {};
122
- const notifWebhook = (notif.webhook as Record<string, unknown>) ?? {};
123
- const notifEmail = (notif.email as Record<string, unknown>) ?? {};
124
- const work = (raw.work as Record<string, unknown>) ?? {};
125
-
126
- return {
127
- wallet: {
128
- contract_address: str(w.contract_address),
129
- owner_address: str(w.owner_address),
130
- machine_key: str(w.machine_key, "env:ARC402_MACHINE_KEY"),
131
- },
132
- network: {
133
- rpc_url: str(n.rpc_url, "https://mainnet.base.org"),
134
- chain_id: num(n.chain_id, 8453),
135
- entry_point: str(n.entry_point, "0x0000000071727De22E5E9d8BAf0edAc6f37da032"),
136
- },
137
- bundler: {
138
- mode: (str(b.mode, "external")) as "external" | "arc402" | "self",
139
- endpoint: str(b.endpoint),
140
- earn_fees: bool(b.earn_fees, false),
141
- eth_float: str(b.eth_float, "0.01"),
142
- sweep_threshold: str(b.sweep_threshold, "0.005"),
143
- sweep_to: str(b.sweep_to),
144
- rpc_url: str(b.rpc_url),
145
- },
146
- relay: {
147
- enabled: bool(r.enabled, true),
148
- listen_port: num(r.listen_port, 4402),
149
- endpoint: str(r.endpoint),
150
- max_concurrent_agreements: num(r.max_concurrent_agreements, 10),
151
- poll_interval_seconds: num(r.poll_interval_seconds, 2),
152
- relay_url: str(r.relay_url),
153
- },
154
- watchtower: {
155
- enabled: bool(wt.enabled, true),
156
- poll_interval_seconds: num(wt.poll_interval_seconds, 60),
157
- challenge_confirmation_blocks: num(wt.challenge_confirmation_blocks, 2),
158
- external_watchtower_url: str(wt.external_watchtower_url),
159
- update_interval_states: num(wt.update_interval_states, 10),
160
- },
161
- policy: {
162
- auto_accept: bool(p.auto_accept, false),
163
- max_price_eth: str(p.max_price_eth, "0.1"),
164
- allowed_capabilities: strArr(p.allowed_capabilities),
165
- require_min_trust_score: num(p.require_min_trust_score, 50),
166
- min_hire_lead_time_seconds: num(p.min_hire_lead_time_seconds, 300),
167
- },
168
- notifications: {
169
- telegram_bot_token: str(notif.telegram_bot_token, "env:TELEGRAM_BOT_TOKEN"),
170
- telegram_chat_id: str(notif.telegram_chat_id, "env:TELEGRAM_CHAT_ID"),
171
- notify_on_hire_request: bool(notif.notify_on_hire_request, true),
172
- notify_on_hire_accepted: bool(notif.notify_on_hire_accepted, true),
173
- notify_on_hire_rejected: bool(notif.notify_on_hire_rejected, true),
174
- notify_on_delivery: bool(notif.notify_on_delivery, true),
175
- notify_on_dispute: bool(notif.notify_on_dispute, true),
176
- notify_on_channel_challenge: bool(notif.notify_on_channel_challenge, true),
177
- notify_on_low_balance: bool(notif.notify_on_low_balance, true),
178
- low_balance_threshold_eth: str(notif.low_balance_threshold_eth, "0.005"),
179
- discord: { webhook_url: str(notifDiscord.webhook_url) },
180
- webhook: {
181
- url: str(notifWebhook.url),
182
- headers: (notifWebhook.headers as Record<string, string>) ?? {},
183
- },
184
- email: {
185
- smtp_host: str(notifEmail.smtp_host),
186
- smtp_port: num(notifEmail.smtp_port, 587),
187
- smtp_user: str(notifEmail.smtp_user),
188
- smtp_pass: str(notifEmail.smtp_pass, "env:SMTP_PASS"),
189
- to: str(notifEmail.to),
190
- },
191
- },
192
- work: {
193
- handler: (str(work.handler, "noop")) as "exec" | "http" | "noop",
194
- exec_command: str(work.exec_command),
195
- http_url: str(work.http_url),
196
- http_auth_token: str(work.http_auth_token),
197
- },
198
- };
199
- }
200
-
201
- export function loadDaemonConfig(configPath = DAEMON_TOML): DaemonConfig {
202
- if (!fs.existsSync(configPath)) {
203
- throw new Error(`daemon.toml not found at ${configPath}. Run: arc402 daemon init`);
204
- }
205
-
206
- const raw = fs.readFileSync(configPath, "utf-8");
207
- let parsed: Record<string, unknown>;
208
- try {
209
- parsed = parseToml(raw) as Record<string, unknown>;
210
- } catch (err) {
211
- throw new Error(`Failed to parse daemon.toml: ${err instanceof Error ? err.message : String(err)}`);
212
- }
213
-
214
- const config = withDefaults(parsed);
215
-
216
- // Required fields
217
- if (!config.wallet.contract_address) {
218
- throw new Error("daemon.toml: wallet.contract_address is required");
219
- }
220
- if (!config.network.rpc_url) {
221
- throw new Error("daemon.toml: network.rpc_url is required");
222
- }
223
- if (!config.network.chain_id) {
224
- throw new Error("daemon.toml: network.chain_id is required");
225
- }
226
-
227
- // Machine key MUST use env: prefix — never hardcoded
228
- if (!config.wallet.machine_key.startsWith("env:")) {
229
- throw new Error("ERROR: machine_key must use env: prefix — never hardcode keys");
230
- }
231
-
232
- // Resolve optional env: values silently (missing = disabled feature)
233
- config.notifications.telegram_bot_token = tryResolveEnvValue(config.notifications.telegram_bot_token);
234
- config.notifications.telegram_chat_id = tryResolveEnvValue(config.notifications.telegram_chat_id);
235
- config.notifications.discord.webhook_url = tryResolveEnvValue(config.notifications.discord.webhook_url);
236
- config.notifications.webhook.url = tryResolveEnvValue(config.notifications.webhook.url);
237
- config.notifications.email.smtp_pass = tryResolveEnvValue(config.notifications.email.smtp_pass);
238
- config.work.http_auth_token = tryResolveEnvValue(config.work.http_auth_token);
239
-
240
- return config;
241
- }
242
-
243
- export function loadMachineKey(config: DaemonConfig): { privateKey: string; address: string } {
244
- const envVarName = config.wallet.machine_key.startsWith("env:")
245
- ? config.wallet.machine_key.slice(4)
246
- : "ARC402_MACHINE_KEY";
247
-
248
- const privateKey = process.env[envVarName];
249
- if (!privateKey) {
250
- throw new Error(`Machine key not found. Set environment variable: ${envVarName}`);
251
- }
252
-
253
- // ethers imported at top level
254
- let address: string;
255
- try {
256
- const w = new ethers.Wallet(privateKey);
257
- address = w.address;
258
- } catch {
259
- throw new Error(`Invalid machine key format in ${envVarName}`);
260
- }
261
-
262
- return { privateKey, address };
263
- }
264
-
265
- export const TEMPLATE_DAEMON_TOML = `# ~/.arc402/daemon.toml
266
- # ARC-402 Daemon Configuration
267
- # Generated by: arc402 daemon init
268
- #
269
- # SECURITY: Never put private keys here. Use environment variables.
270
-
271
- [wallet]
272
- contract_address = "" # ARC402Wallet contract address (required)
273
- owner_address = "" # Owner EOA address — for display and verification only
274
- machine_key = "env:ARC402_MACHINE_KEY" # Machine key loaded from environment. NEVER hardcode here.
275
-
276
- [network]
277
- rpc_url = "https://mainnet.base.org" # Public Base RPC (default)
278
- chain_id = 8453 # Base mainnet. Use 84532 for Base Sepolia.
279
- entry_point = "0x0000000071727De22E5E9d8BAf0edAc6f37da032" # ERC-4337 EntryPoint v0.7
280
-
281
- [bundler]
282
- mode = "external" # external | arc402 | self
283
- endpoint = "" # Required when mode = external. Pimlico, Alchemy, etc.
284
- earn_fees = false # self mode only: bundle for other network agents
285
- eth_float = "0.01" # Minimum ETH to maintain in bundler EOA for gas fronting
286
- sweep_threshold = "0.005" # Sweep fees to wallet when bundler EOA exceeds this (ETH)
287
- sweep_to = "" # Sweep destination. Defaults to wallet.contract_address.
288
- rpc_url = "" # self mode: private RPC. Defaults to network.rpc_url if empty.
289
-
290
- [relay]
291
- enabled = true
292
- listen_port = 4402 # Port for incoming relay messages
293
- endpoint = "" # Your public URL — run: arc402 setup endpoint
294
- # Example: https://gigabrain.arc402.xyz
295
- max_concurrent_agreements = 10 # Refuse new hire requests when this many are in-flight
296
- poll_interval_seconds = 2 # How often to poll relay for incoming messages
297
- relay_url = "" # The relay to poll. Defaults to agent metadata relay if empty.
298
-
299
- [watchtower]
300
- enabled = true
301
- poll_interval_seconds = 60 # How often to poll chain for stale-close events
302
- challenge_confirmation_blocks = 2 # Wait N block confirmations before accepting close as final
303
- external_watchtower_url = "" # Register open channels here as backup (Tier 2 watchtower)
304
- update_interval_states = 10 # Forward state to external watchtower every N state changes
305
-
306
- [policy]
307
- auto_accept = false # If true: auto-accept all hire requests within policy bounds
308
- max_price_eth = "0.1" # Refuse any hire priced above this (ETH)
309
- allowed_capabilities = [] # Empty list = accept any capability. Non-empty = whitelist.
310
- require_min_trust_score = 50 # Refuse hirers whose wallet trust score is below this (0–100)
311
- min_hire_lead_time_seconds = 300 # Refuse hires with delivery deadline < this many seconds away
312
-
313
- [notifications]
314
- telegram_bot_token = "env:TELEGRAM_BOT_TOKEN" # Load from env, not hardcoded
315
- telegram_chat_id = "env:TELEGRAM_CHAT_ID" # Load from env, not hardcoded
316
- notify_on_hire_request = true # Notify when a hire request arrives (pending approval)
317
- notify_on_hire_accepted = true # Notify when daemon accepts a hire
318
- notify_on_hire_rejected = true # Notify when daemon rejects a hire
319
- notify_on_delivery = true # Notify when work is delivered and fulfill() submitted
320
- notify_on_dispute = true # Notify when a dispute is raised (by either party)
321
- notify_on_channel_challenge = true # Notify when watchtower submits a channel challenge
322
- notify_on_low_balance = false # Disabled by default — enable if you want balance alerts
323
- low_balance_threshold_eth = "0.005" # Balance alert threshold
324
-
325
- [notifications.discord]
326
- webhook_url = "" # Discord channel webhook URL (leave empty to disable)
327
-
328
- [notifications.webhook]
329
- url = "" # POST JSON {title, body, timestamp} to this URL (leave empty to disable)
330
- # headers = { Authorization = "Bearer ..." } # Optional headers
331
-
332
- [notifications.email]
333
- smtp_host = "" # SMTP server hostname (leave empty to disable)
334
- smtp_port = 587
335
- smtp_user = "" # SMTP login / from address
336
- smtp_pass = "env:SMTP_PASS" # Load from env, not hardcoded
337
- to = "" # Recipient address
338
-
339
- [work]
340
- handler = "noop" # exec | http | noop
341
- exec_command = "" # called with agreementId and spec as args (exec mode)
342
- http_url = "" # POST {agreementId, specHash, deadline} as JSON (http mode)
343
- http_auth_token = "env:WORKER_AUTH_TOKEN"
344
- `;