arc402-cli 0.7.1 → 0.7.2

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.
@@ -1,14 +1,42 @@
1
+ import type { DaemonConfig } from "./config";
1
2
  export type NotifyEvent = "hire_request" | "hire_accepted" | "hire_rejected" | "delivery" | "dispute" | "channel_challenge" | "low_balance" | "daemon_started" | "daemon_stopped";
2
- export interface TelegramConfig {
3
- botToken: string;
4
- chatId: string;
3
+ export interface NotificationChannel {
4
+ send(title: string, body: string): Promise<void>;
5
+ }
6
+ export declare class TelegramChannel implements NotificationChannel {
7
+ private botToken;
8
+ private chatId;
9
+ constructor(botToken: string, chatId: string);
10
+ send(title: string, body: string): Promise<void>;
11
+ }
12
+ export declare class DiscordChannel implements NotificationChannel {
13
+ private webhookUrl;
14
+ constructor(webhookUrl: string);
15
+ send(title: string, body: string): Promise<void>;
16
+ }
17
+ export declare class WebhookChannel implements NotificationChannel {
18
+ private url;
19
+ private headers;
20
+ constructor(url: string, headers?: Record<string, string>);
21
+ send(title: string, body: string): Promise<void>;
22
+ }
23
+ export declare class EmailChannel implements NotificationChannel {
24
+ private cfg;
25
+ constructor(cfg: {
26
+ smtpHost: string;
27
+ smtpPort: number;
28
+ smtpUser: string;
29
+ smtpPass: string;
30
+ to: string;
31
+ });
32
+ send(title: string, body: string): Promise<void>;
5
33
  }
6
34
  export declare class Notifier {
7
- private config;
35
+ private channels;
8
36
  private notifyFlags;
9
- constructor(botToken: string, chatId: string, flags?: Partial<Record<NotifyEvent, boolean>>);
37
+ constructor(channels: NotificationChannel[], flags?: Partial<Record<NotifyEvent, boolean>>);
10
38
  isEnabled(): boolean;
11
- send(event: NotifyEvent, message: string): Promise<void>;
39
+ send(event: NotifyEvent, title: string, body: string): Promise<void>;
12
40
  notifyHireRequest(hireId: string, hirerAddress: string, priceEth: string, capability: string): Promise<void>;
13
41
  notifyHireAccepted(hireId: string, agreementId: string): Promise<void>;
14
42
  notifyHireRejected(hireId: string, reason: string): Promise<void>;
@@ -19,4 +47,5 @@ export declare class Notifier {
19
47
  notifyStarted(walletAddress: string, subsystems: string[]): Promise<void>;
20
48
  notifyStopped(): Promise<void>;
21
49
  }
50
+ export declare function buildNotifier(config: DaemonConfig): Notifier;
22
51
  //# sourceMappingURL=notify.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"notify.d.ts","sourceRoot":"","sources":["../../src/daemon/notify.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,WAAW,GACnB,cAAc,GACd,eAAe,GACf,eAAe,GACf,UAAU,GACV,SAAS,GACT,mBAAmB,GACnB,aAAa,GACb,gBAAgB,GAChB,gBAAgB,CAAC;AAErB,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAiCD,qBAAa,QAAQ;IACnB,OAAO,CAAC,MAAM,CAAwB;IACtC,OAAO,CAAC,WAAW,CAA+B;gBAGhD,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,KAAK,GAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAM;IAgBnD,SAAS,IAAI,OAAO;IAId,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAexD,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAe5G,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMtE,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMjE,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM5F,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMnE,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMxE,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMzE,aAAa,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAMzE,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;CAGrC"}
1
+ {"version":3,"file":"notify.d.ts","sourceRoot":"","sources":["../../src/daemon/notify.ts"],"names":[],"mappings":"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"}
@@ -33,35 +33,38 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.Notifier = void 0;
36
+ exports.Notifier = exports.EmailChannel = exports.WebhookChannel = exports.DiscordChannel = exports.TelegramChannel = void 0;
37
+ exports.buildNotifier = buildNotifier;
37
38
  /**
38
- * Telegram notification module for daemon events.
39
- * Uses Telegram Bot API no external dependencies.
39
+ * Multi-channel notification module for daemon events.
40
+ * Supports Telegram, Discord webhooks, generic webhooks, and email (via nodemailer).
40
41
  */
41
42
  const https = __importStar(require("https"));
42
- function telegramPost(botToken, method, body) {
43
+ const http = __importStar(require("http"));
44
+ // ─── HTTP helper ──────────────────────────────────────────────────────────────
45
+ function httpPost(url, payload, extraHeaders) {
43
46
  return new Promise((resolve, reject) => {
44
- const payload = JSON.stringify(body);
47
+ const parsed = new URL(url);
48
+ const mod = parsed.protocol === "https:" ? https : http;
45
49
  const options = {
46
- hostname: "api.telegram.org",
47
- port: 443,
48
- path: `/bot${botToken}/${method}`,
50
+ hostname: parsed.hostname,
51
+ port: parsed.port || (parsed.protocol === "https:" ? 443 : 80),
52
+ path: parsed.pathname + parsed.search,
49
53
  method: "POST",
50
54
  headers: {
51
55
  "Content-Type": "application/json",
52
56
  "Content-Length": Buffer.byteLength(payload),
57
+ ...extraHeaders,
53
58
  },
54
59
  };
55
- const req = https.request(options, (res) => {
56
- let data = "";
57
- res.on("data", (c) => { data += c.toString(); });
60
+ const req = mod.request(options, (res) => {
61
+ res.resume();
58
62
  res.on("end", () => {
59
- const parsed = JSON.parse(data);
60
- if (!parsed.ok) {
61
- reject(new Error(`Telegram API error: ${parsed.description}`));
63
+ if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
64
+ resolve();
62
65
  }
63
66
  else {
64
- resolve();
67
+ reject(new Error(`HTTP ${res.statusCode}`));
65
68
  }
66
69
  });
67
70
  });
@@ -70,9 +73,105 @@ function telegramPost(botToken, method, body) {
70
73
  req.end();
71
74
  });
72
75
  }
76
+ // ─── Telegram channel ─────────────────────────────────────────────────────────
77
+ class TelegramChannel {
78
+ constructor(botToken, chatId) {
79
+ this.botToken = botToken;
80
+ this.chatId = chatId;
81
+ }
82
+ async send(title, body) {
83
+ const text = body ? `<b>${title}</b>\n${body}` : `<b>${title}</b>`;
84
+ const payload = JSON.stringify({ chat_id: this.chatId, text, parse_mode: "HTML" });
85
+ const options = {
86
+ hostname: "api.telegram.org",
87
+ port: 443,
88
+ path: `/bot${this.botToken}/sendMessage`,
89
+ method: "POST",
90
+ headers: {
91
+ "Content-Type": "application/json",
92
+ "Content-Length": Buffer.byteLength(payload),
93
+ },
94
+ };
95
+ await new Promise((resolve, reject) => {
96
+ const req = https.request(options, (res) => {
97
+ let data = "";
98
+ res.on("data", (c) => { data += c.toString(); });
99
+ res.on("end", () => {
100
+ const parsed = JSON.parse(data);
101
+ if (!parsed.ok) {
102
+ reject(new Error(`Telegram API error: ${parsed.description}`));
103
+ }
104
+ else {
105
+ resolve();
106
+ }
107
+ });
108
+ });
109
+ req.on("error", reject);
110
+ req.write(payload);
111
+ req.end();
112
+ });
113
+ }
114
+ }
115
+ exports.TelegramChannel = TelegramChannel;
116
+ // ─── Discord channel ──────────────────────────────────────────────────────────
117
+ class DiscordChannel {
118
+ constructor(webhookUrl) {
119
+ this.webhookUrl = webhookUrl;
120
+ }
121
+ async send(title, body) {
122
+ const content = body ? `**${title}**\n${body}` : `**${title}**`;
123
+ await httpPost(this.webhookUrl, JSON.stringify({ content }), {});
124
+ }
125
+ }
126
+ exports.DiscordChannel = DiscordChannel;
127
+ // ─── Generic webhook channel ──────────────────────────────────────────────────
128
+ class WebhookChannel {
129
+ constructor(url, headers = {}) {
130
+ this.url = url;
131
+ this.headers = headers;
132
+ }
133
+ async send(title, body) {
134
+ await httpPost(this.url, JSON.stringify({ title, body, timestamp: new Date().toISOString() }), this.headers);
135
+ }
136
+ }
137
+ exports.WebhookChannel = WebhookChannel;
138
+ // ─── Email channel (optional — requires nodemailer) ───────────────────────────
139
+ class EmailChannel {
140
+ constructor(cfg) {
141
+ this.cfg = cfg;
142
+ }
143
+ async send(title, body) {
144
+ // nodemailer is an optional runtime dependency — load via require to skip
145
+ // compile-time module resolution. Throws a clear message if not installed.
146
+ // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-explicit-any
147
+ let nodemailer;
148
+ try {
149
+ // Using Function constructor avoids TypeScript static import analysis.
150
+ nodemailer = (new Function("require", "return require('nodemailer')"))(require);
151
+ }
152
+ catch {
153
+ throw new Error("nodemailer is not installed. Run: npm install nodemailer");
154
+ }
155
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
156
+ const transport = nodemailer.createTransport({
157
+ host: this.cfg.smtpHost,
158
+ port: this.cfg.smtpPort,
159
+ auth: { user: this.cfg.smtpUser, pass: this.cfg.smtpPass },
160
+ });
161
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
162
+ await transport.sendMail({
163
+ from: this.cfg.smtpUser,
164
+ to: this.cfg.to,
165
+ subject: title,
166
+ text: body,
167
+ });
168
+ }
169
+ }
170
+ exports.EmailChannel = EmailChannel;
171
+ // ─── Notifier ─────────────────────────────────────────────────────────────────
73
172
  class Notifier {
74
- constructor(botToken, chatId, flags = {}) {
75
- this.config = botToken && chatId ? { botToken, chatId } : null;
173
+ constructor(channels, flags = {}) {
174
+ this.channels = channels;
76
175
  this.notifyFlags = {
77
176
  hire_request: flags.hire_request ?? true,
78
177
  hire_accepted: flags.hire_accepted ?? true,
@@ -86,63 +185,92 @@ class Notifier {
86
185
  };
87
186
  }
88
187
  isEnabled() {
89
- return this.config !== null;
188
+ return this.channels.length > 0;
90
189
  }
91
- async send(event, message) {
92
- if (!this.config)
93
- return;
190
+ async send(event, title, body) {
94
191
  if (!this.notifyFlags[event])
95
192
  return;
96
- try {
97
- await telegramPost(this.config.botToken, "sendMessage", {
98
- chat_id: this.config.chatId,
99
- text: message,
100
- parse_mode: "HTML",
101
- });
102
- }
103
- catch (err) {
104
- // Non-fatal — log and continue
105
- process.stderr.write(`[notify] Telegram send failed: ${err}\n`);
106
- }
193
+ await Promise.all(this.channels.map(async (ch) => {
194
+ try {
195
+ await ch.send(title, body);
196
+ }
197
+ catch (err) {
198
+ process.stderr.write(`[notify] Channel send failed: ${err}\n`);
199
+ }
200
+ }));
107
201
  }
108
202
  async notifyHireRequest(hireId, hirerAddress, priceEth, capability) {
109
203
  const short = hirerAddress.slice(0, 10);
110
- const msg = [
111
- `⚡ <b>Hire Request</b>`,
112
- `ID: <code>${hireId}</code>`,
113
- `From: <code>${short}...</code>`,
204
+ await this.send("hire_request", "Hire Request", [
205
+ `ID: ${hireId}`,
206
+ `From: ${short}...`,
114
207
  `Capability: ${capability || "unspecified"}`,
115
208
  `Price: ${priceEth} ETH`,
116
209
  ``,
117
- `Approve: <code>arc402 daemon approve ${hireId}</code>`,
118
- `Reject: <code>arc402 daemon reject ${hireId}</code>`,
119
- ].join("\n");
120
- await this.send("hire_request", msg);
210
+ `Approve: arc402 daemon approve ${hireId}`,
211
+ `Reject: arc402 daemon reject ${hireId}`,
212
+ ].join("\n"));
121
213
  }
122
214
  async notifyHireAccepted(hireId, agreementId) {
123
- await this.send("hire_accepted", `✅ <b>Hire Accepted</b>\nID: <code>${hireId}</code>\nAgreement: <code>${agreementId}</code>`);
215
+ await this.send("hire_accepted", "Hire Accepted", `ID: ${hireId}\nAgreement: ${agreementId}`);
124
216
  }
125
217
  async notifyHireRejected(hireId, reason) {
126
- await this.send("hire_rejected", `❌ <b>Hire Rejected</b>\nID: <code>${hireId}</code>\nReason: ${reason}`);
218
+ await this.send("hire_rejected", "Hire Rejected", `ID: ${hireId}\nReason: ${reason}`);
127
219
  }
128
220
  async notifyDelivery(agreementId, deliveryHash, userOpHash) {
129
- await this.send("delivery", `📦 <b>Delivery Submitted</b>\nAgreement: <code>${agreementId}</code>\nDelivery hash: <code>${deliveryHash.slice(0, 16)}...</code>\nUserOp: <code>${userOpHash.slice(0, 16)}...</code>`);
221
+ await this.send("delivery", "Delivery Submitted", [
222
+ `Agreement: ${agreementId}`,
223
+ `Delivery hash: ${deliveryHash.slice(0, 16)}...`,
224
+ `UserOp: ${userOpHash.slice(0, 16)}...`,
225
+ ].join("\n"));
130
226
  }
131
227
  async notifyDispute(agreementId, raisedBy) {
132
- await this.send("dispute", `⚠️ <b>Dispute Raised</b>\nAgreement: <code>${agreementId}</code>\nBy: <code>${raisedBy}</code>`);
228
+ await this.send("dispute", "Dispute Raised", `Agreement: ${agreementId}\nBy: ${raisedBy}`);
133
229
  }
134
230
  async notifyChannelChallenge(channelId, txHash) {
135
- await this.send("channel_challenge", `🔔 <b>Channel Challenged</b>\nChannel: <code>${channelId.slice(0, 16)}...</code>\nTx: <code>${txHash.slice(0, 16)}...</code>`);
231
+ await this.send("channel_challenge", "Channel Challenged", `Channel: ${channelId.slice(0, 16)}...\nTx: ${txHash.slice(0, 16)}...`);
136
232
  }
137
233
  async notifyLowBalance(balanceEth, thresholdEth) {
138
- await this.send("low_balance", `💸 <b>Low Balance Alert</b>\nCurrent: ${balanceEth} ETH\nThreshold: ${thresholdEth} ETH`);
234
+ await this.send("low_balance", "Low Balance Alert", `Current: ${balanceEth} ETH\nThreshold: ${thresholdEth} ETH`);
139
235
  }
140
236
  async notifyStarted(walletAddress, subsystems) {
141
- await this.send("daemon_started", `🟢 <b>ARC-402 Daemon Started</b>\nWallet: <code>${walletAddress}</code>\nSubsystems: ${subsystems.join(", ")}`);
237
+ await this.send("daemon_started", "ARC-402 Daemon Started", `Wallet: ${walletAddress}\nSubsystems: ${subsystems.join(", ")}`);
142
238
  }
143
239
  async notifyStopped() {
144
- await this.send("daemon_stopped", `🔴 <b>ARC-402 Daemon Stopped</b>`);
240
+ await this.send("daemon_stopped", "ARC-402 Daemon Stopped", "");
145
241
  }
146
242
  }
147
243
  exports.Notifier = Notifier;
244
+ // ─── Factory ──────────────────────────────────────────────────────────────────
245
+ function buildNotifier(config) {
246
+ const notif = config.notifications;
247
+ const channels = [];
248
+ if (notif.telegram_bot_token && notif.telegram_chat_id) {
249
+ channels.push(new TelegramChannel(notif.telegram_bot_token, notif.telegram_chat_id));
250
+ }
251
+ if (notif.discord?.webhook_url) {
252
+ channels.push(new DiscordChannel(notif.discord.webhook_url));
253
+ }
254
+ if (notif.webhook?.url) {
255
+ channels.push(new WebhookChannel(notif.webhook.url, notif.webhook.headers ?? {}));
256
+ }
257
+ if (notif.email?.smtp_host && notif.email?.smtp_user && notif.email?.to) {
258
+ channels.push(new EmailChannel({
259
+ smtpHost: notif.email.smtp_host,
260
+ smtpPort: notif.email.smtp_port,
261
+ smtpUser: notif.email.smtp_user,
262
+ smtpPass: notif.email.smtp_pass,
263
+ to: notif.email.to,
264
+ }));
265
+ }
266
+ return new Notifier(channels, {
267
+ hire_request: notif.notify_on_hire_request,
268
+ hire_accepted: notif.notify_on_hire_accepted,
269
+ hire_rejected: notif.notify_on_hire_rejected,
270
+ delivery: notif.notify_on_delivery,
271
+ dispute: notif.notify_on_dispute,
272
+ channel_challenge: notif.notify_on_channel_challenge,
273
+ low_balance: notif.notify_on_low_balance,
274
+ });
275
+ }
148
276
  //# sourceMappingURL=notify.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"notify.js","sourceRoot":"","sources":["../../src/daemon/notify.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"notify.js","sourceRoot":"","sources":["../../src/daemon/notify.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arc402-cli",
3
- "version": "0.7.1",
3
+ "version": "0.7.2",
4
4
  "description": "ARC-402 CLI for discovery, negotiation payloads, hire/remediation/dispute workflows, and network reads",
5
5
  "bin": {
6
6
  "arc402": "./dist/index.js"
@@ -19,7 +19,9 @@ import {
19
19
  DAEMON_SOCK,
20
20
  DAEMON_TOML,
21
21
  TEMPLATE_DAEMON_TOML,
22
+ loadDaemonConfig,
22
23
  } from "../daemon/config";
24
+ import { buildNotifier } from "../daemon/notify";
23
25
  import {
24
26
  buildOpenShellSecretExports,
25
27
  buildOpenShellSshConfig,
@@ -943,6 +945,77 @@ export function registerDaemonCommands(program: Command): void {
943
945
  console.log(" 5. Start the OpenShell-owned ARC-402 runtime: arc402 daemon start");
944
946
  });
945
947
 
948
+ // ── daemon notifications ──────────────────────────────────────────────────────
949
+ const notifications = daemon
950
+ .command("notifications")
951
+ .description("Show or test configured notification channels");
952
+
953
+ notifications
954
+ .command("show")
955
+ .description("Show all configured notification channels")
956
+ .action(() => {
957
+ if (!fs.existsSync(DAEMON_TOML)) {
958
+ console.error("daemon.toml not found. Run `arc402 daemon init` first.");
959
+ process.exit(1);
960
+ }
961
+ const cfg = loadDaemonConfig();
962
+ const notif = cfg.notifications;
963
+ const channels: string[] = [];
964
+
965
+ if (notif.telegram_bot_token && notif.telegram_chat_id) {
966
+ channels.push(`telegram chat_id=${notif.telegram_chat_id}`);
967
+ }
968
+ if (notif.discord?.webhook_url) {
969
+ const u = new URL(notif.discord.webhook_url);
970
+ channels.push(`discord ${u.hostname}${u.pathname.slice(0, 30)}...`);
971
+ }
972
+ if (notif.webhook?.url) {
973
+ channels.push(`webhook ${notif.webhook.url}`);
974
+ }
975
+ if (notif.email?.smtp_host && notif.email?.to) {
976
+ channels.push(`email ${notif.email.smtp_host}:${notif.email.smtp_port} → ${notif.email.to}`);
977
+ }
978
+
979
+ if (channels.length === 0) {
980
+ console.log("No notification channels configured.");
981
+ console.log("Edit ~/.arc402/daemon.toml to add Telegram, Discord, webhook, or email.");
982
+ } else {
983
+ console.log(`Configured channels (${channels.length}):`);
984
+ for (const ch of channels) console.log(` ${ch}`);
985
+ }
986
+ });
987
+
988
+ notifications
989
+ .command("test")
990
+ .description("Send a test message to all configured channels")
991
+ .action(async () => {
992
+ if (!fs.existsSync(DAEMON_TOML)) {
993
+ console.error("daemon.toml not found. Run `arc402 daemon init` first.");
994
+ process.exit(1);
995
+ }
996
+ const cfg = loadDaemonConfig();
997
+ const notifier = buildNotifier(cfg);
998
+ if (!notifier.isEnabled()) {
999
+ console.log("No notification channels configured. Nothing to test.");
1000
+ process.exit(0);
1001
+ }
1002
+ console.log("Sending test notification to all channels...");
1003
+ try {
1004
+ await notifier.send("daemon_started", "ARC-402 Test Notification",
1005
+ "This is a test message from arc402 daemon notifications test."
1006
+ );
1007
+ console.log("Test notification sent successfully.");
1008
+ } catch (err) {
1009
+ console.error(`Test notification failed: ${err instanceof Error ? err.message : String(err)}`);
1010
+ process.exit(1);
1011
+ }
1012
+ });
1013
+
1014
+ // Default action: show (arc402 daemon notifications → arc402 daemon notifications show)
1015
+ notifications.action(() => {
1016
+ notifications.help();
1017
+ });
1018
+
946
1019
  // ── daemon channel-watch ─────────────────────────────────────────────────────
947
1020
  daemon
948
1021
  .command("channel-watch")
@@ -68,6 +68,9 @@ export interface DaemonConfig {
68
68
  notify_on_channel_challenge: boolean;
69
69
  notify_on_low_balance: boolean;
70
70
  low_balance_threshold_eth: string;
71
+ discord: { webhook_url: string };
72
+ webhook: { url: string; headers: Record<string, string> };
73
+ email: { smtp_host: string; smtp_port: number; smtp_user: string; smtp_pass: string; to: string };
71
74
  };
72
75
  work: {
73
76
  handler: "exec" | "http" | "noop";
@@ -114,6 +117,9 @@ function withDefaults(raw: Record<string, unknown>): DaemonConfig {
114
117
  const wt = (raw.watchtower as Record<string, unknown>) ?? {};
115
118
  const p = (raw.policy as Record<string, unknown>) ?? {};
116
119
  const notif = (raw.notifications as Record<string, unknown>) ?? {};
120
+ const notifDiscord = (notif.discord as Record<string, unknown>) ?? {};
121
+ const notifWebhook = (notif.webhook as Record<string, unknown>) ?? {};
122
+ const notifEmail = (notif.email as Record<string, unknown>) ?? {};
117
123
  const work = (raw.work as Record<string, unknown>) ?? {};
118
124
 
119
125
  return {
@@ -169,6 +175,18 @@ function withDefaults(raw: Record<string, unknown>): DaemonConfig {
169
175
  notify_on_channel_challenge: bool(notif.notify_on_channel_challenge, true),
170
176
  notify_on_low_balance: bool(notif.notify_on_low_balance, true),
171
177
  low_balance_threshold_eth: str(notif.low_balance_threshold_eth, "0.005"),
178
+ discord: { webhook_url: str(notifDiscord.webhook_url) },
179
+ webhook: {
180
+ url: str(notifWebhook.url),
181
+ headers: (notifWebhook.headers as Record<string, string>) ?? {},
182
+ },
183
+ email: {
184
+ smtp_host: str(notifEmail.smtp_host),
185
+ smtp_port: num(notifEmail.smtp_port, 587),
186
+ smtp_user: str(notifEmail.smtp_user),
187
+ smtp_pass: str(notifEmail.smtp_pass, "env:SMTP_PASS"),
188
+ to: str(notifEmail.to),
189
+ },
172
190
  },
173
191
  work: {
174
192
  handler: (str(work.handler, "noop")) as "exec" | "http" | "noop",
@@ -213,6 +231,9 @@ export function loadDaemonConfig(configPath = DAEMON_TOML): DaemonConfig {
213
231
  // Resolve optional env: values silently (missing = disabled feature)
214
232
  config.notifications.telegram_bot_token = tryResolveEnvValue(config.notifications.telegram_bot_token);
215
233
  config.notifications.telegram_chat_id = tryResolveEnvValue(config.notifications.telegram_chat_id);
234
+ config.notifications.discord.webhook_url = tryResolveEnvValue(config.notifications.discord.webhook_url);
235
+ config.notifications.webhook.url = tryResolveEnvValue(config.notifications.webhook.url);
236
+ config.notifications.email.smtp_pass = tryResolveEnvValue(config.notifications.email.smtp_pass);
216
237
  config.work.http_auth_token = tryResolveEnvValue(config.work.http_auth_token);
217
238
 
218
239
  return config;
@@ -300,6 +321,20 @@ notify_on_channel_challenge = true # Notify when watchtower submits a channel c
300
321
  notify_on_low_balance = false # Disabled by default — enable if you want balance alerts
301
322
  low_balance_threshold_eth = "0.005" # Balance alert threshold
302
323
 
324
+ [notifications.discord]
325
+ webhook_url = "" # Discord channel webhook URL (leave empty to disable)
326
+
327
+ [notifications.webhook]
328
+ url = "" # POST JSON {title, body, timestamp} to this URL (leave empty to disable)
329
+ # headers = { Authorization = "Bearer ..." } # Optional headers
330
+
331
+ [notifications.email]
332
+ smtp_host = "" # SMTP server hostname (leave empty to disable)
333
+ smtp_port = 587
334
+ smtp_user = "" # SMTP login / from address
335
+ smtp_pass = "env:SMTP_PASS" # Load from env, not hardcoded
336
+ to = "" # Recipient address
337
+
303
338
  [work]
304
339
  handler = "noop" # exec | http | noop
305
340
  exec_command = "" # called with agreementId and spec as args (exec mode)
@@ -27,7 +27,7 @@ import {
27
27
  type DaemonConfig,
28
28
  } from "./config";
29
29
  import { verifyWallet, getWalletBalance } from "./wallet-monitor";
30
- import { Notifier } from "./notify";
30
+ import { buildNotifier } from "./notify";
31
31
  import { HireListener } from "./hire-listener";
32
32
  import { UserOpsManager, buildAcceptCalldata } from "./userops";
33
33
  import { generateReceipt, extractLearnings, createJobDirectory, cleanJobDirectory } from "./job-lifecycle";
@@ -519,19 +519,7 @@ export async function runDaemon(foreground = false): Promise<void> {
519
519
  }
520
520
 
521
521
  // ── Setup notifier ───────────────────────────────────────────────────────
522
- const notifier = new Notifier(
523
- config.notifications.telegram_bot_token,
524
- config.notifications.telegram_chat_id,
525
- {
526
- hire_request: config.notifications.notify_on_hire_request,
527
- hire_accepted: config.notifications.notify_on_hire_accepted,
528
- hire_rejected: config.notifications.notify_on_hire_rejected,
529
- delivery: config.notifications.notify_on_delivery,
530
- dispute: config.notifications.notify_on_dispute,
531
- channel_challenge: config.notifications.notify_on_channel_challenge,
532
- low_balance: config.notifications.notify_on_low_balance,
533
- }
534
- );
522
+ const notifier = buildNotifier(config);
535
523
 
536
524
  // ── Step 10: Start relay listener ───────────────────────────────────────
537
525
  const hireListener = new HireListener(config, db, notifier, config.wallet.contract_address);