@btcemail/cli 0.4.0 → 0.5.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.
- package/README.md +32 -1
- package/dist/index.js +48 -2
- package/dist/index.js.map +1 -1
- package/package.json +13 -7
package/README.md
CHANGED
|
@@ -6,6 +6,36 @@ Current version: 0.4.0 (December 28, 2025)
|
|
|
6
6
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
|
9
|
+
### Option 1: Pre-built Binary (Recommended)
|
|
10
|
+
|
|
11
|
+
Download the latest binary for your platform from [GitHub Releases](https://github.com/8bittts/btcemail/releases).
|
|
12
|
+
|
|
13
|
+
macOS (Apple Silicon):
|
|
14
|
+
```bash
|
|
15
|
+
curl -L https://github.com/8bittts/btcemail/releases/latest/download/btcemail-darwin-arm64 -o btcemail
|
|
16
|
+
chmod +x btcemail
|
|
17
|
+
sudo mv btcemail /usr/local/bin/
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
macOS (Intel):
|
|
21
|
+
```bash
|
|
22
|
+
curl -L https://github.com/8bittts/btcemail/releases/latest/download/btcemail-darwin-x64 -o btcemail
|
|
23
|
+
chmod +x btcemail
|
|
24
|
+
sudo mv btcemail /usr/local/bin/
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Linux (x64):
|
|
28
|
+
```bash
|
|
29
|
+
curl -L https://github.com/8bittts/btcemail/releases/latest/download/btcemail-linux-x64 -o btcemail
|
|
30
|
+
chmod +x btcemail
|
|
31
|
+
sudo mv btcemail /usr/local/bin/
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Windows:
|
|
35
|
+
Download `btcemail-windows-x64.exe` from the releases page and add to your PATH.
|
|
36
|
+
|
|
37
|
+
### Option 2: npm/bun
|
|
38
|
+
|
|
9
39
|
```bash
|
|
10
40
|
npm install -g @btcemail/cli
|
|
11
41
|
```
|
|
@@ -307,7 +337,8 @@ bun run typecheck
|
|
|
307
337
|
|
|
308
338
|
## Requirements
|
|
309
339
|
|
|
310
|
-
-
|
|
340
|
+
- Pre-built binary: No runtime required (standalone executable)
|
|
341
|
+
- npm/bun install: Node.js 18 or later
|
|
311
342
|
- An active btc.email account
|
|
312
343
|
|
|
313
344
|
## License
|
package/dist/index.js
CHANGED
|
@@ -175,6 +175,15 @@ async function payForEmail(id, paymentHash) {
|
|
|
175
175
|
body: JSON.stringify({ paymentHash })
|
|
176
176
|
});
|
|
177
177
|
}
|
|
178
|
+
async function acceptPendingEmail(id, whitelist2 = true) {
|
|
179
|
+
return apiRequest(
|
|
180
|
+
`/inbound/${id}/accept`,
|
|
181
|
+
{
|
|
182
|
+
method: "POST",
|
|
183
|
+
body: JSON.stringify({ whitelist: whitelist2 })
|
|
184
|
+
}
|
|
185
|
+
);
|
|
186
|
+
}
|
|
178
187
|
async function sendEmail(options) {
|
|
179
188
|
return apiRequest("/email/send", {
|
|
180
189
|
method: "POST",
|
|
@@ -867,6 +876,34 @@ async function inboundPayCommand(id, options) {
|
|
|
867
876
|
console.log(pc4.dim(`Read email: btcemail read ${result.data.emailId}`));
|
|
868
877
|
console.log();
|
|
869
878
|
}
|
|
879
|
+
async function inboundAcceptCommand(id, options) {
|
|
880
|
+
if (!isAuthenticated()) {
|
|
881
|
+
console.log(pc4.yellow("Not logged in."));
|
|
882
|
+
console.log(pc4.dim("Run `btcemail login` to authenticate."));
|
|
883
|
+
process.exit(1);
|
|
884
|
+
}
|
|
885
|
+
const spinner = ora2("Accepting email...").start();
|
|
886
|
+
const shouldWhitelist = !options.noWhitelist;
|
|
887
|
+
const result = await acceptPendingEmail(id, shouldWhitelist);
|
|
888
|
+
if (!result.ok) {
|
|
889
|
+
if (result.error.code === "NOT_FOUND") {
|
|
890
|
+
spinner.fail(`Pending email not found: ${id}`);
|
|
891
|
+
} else {
|
|
892
|
+
spinner.fail(`Error: ${result.error.message}`);
|
|
893
|
+
}
|
|
894
|
+
process.exit(1);
|
|
895
|
+
}
|
|
896
|
+
spinner.succeed("Email accepted and delivered!");
|
|
897
|
+
console.log();
|
|
898
|
+
console.log(`${pc4.dim("Email ID:")} ${result.data.emailId}`);
|
|
899
|
+
console.log(`${pc4.dim("Status:")} ${result.data.status}`);
|
|
900
|
+
if (result.data.whitelisted) {
|
|
901
|
+
console.log(`${pc4.dim("Sender:")} ${pc4.green(result.data.senderEmail)} ${pc4.dim("(whitelisted)")}`);
|
|
902
|
+
}
|
|
903
|
+
console.log();
|
|
904
|
+
console.log(pc4.dim(`Read email: btcemail read ${result.data.emailId}`));
|
|
905
|
+
console.log();
|
|
906
|
+
}
|
|
870
907
|
function truncate(str, maxLength) {
|
|
871
908
|
if (str.length <= maxLength) return str;
|
|
872
909
|
return `${str.slice(0, maxLength - 1)}\u2026`;
|
|
@@ -1394,7 +1431,7 @@ async function sendCommand(options) {
|
|
|
1394
1431
|
const whoamiResult = await getWhoami();
|
|
1395
1432
|
spinner2.stop();
|
|
1396
1433
|
if (whoamiResult.ok && whoamiResult.data.username) {
|
|
1397
|
-
fromEmail =
|
|
1434
|
+
fromEmail = whoamiResult.data.username;
|
|
1398
1435
|
} else {
|
|
1399
1436
|
const auth = getAuth();
|
|
1400
1437
|
if (auth?.email?.endsWith("@btc.email")) {
|
|
@@ -1846,7 +1883,13 @@ program.command("send").description("Send an email (with Lightning payment)").op
|
|
|
1846
1883
|
wait: options.wait
|
|
1847
1884
|
});
|
|
1848
1885
|
});
|
|
1849
|
-
|
|
1886
|
+
program.command("bin").description("List pending inbound emails (alias for 'inbound pending')").option("-l, --limit <number>", "Number of emails to show", "20").option("--json", "Output as JSON").action(async (options) => {
|
|
1887
|
+
await inboundPendingCommand({
|
|
1888
|
+
limit: parseInt(options.limit, 10),
|
|
1889
|
+
json: options.json
|
|
1890
|
+
});
|
|
1891
|
+
});
|
|
1892
|
+
var inbound = program.command("inbound").alias("in").description("Manage inbound emails (pending and delivered)");
|
|
1850
1893
|
inbound.command("pending").alias("p").description("List pending emails awaiting payment").option("-l, --limit <number>", "Number of emails to show", "20").option("--json", "Output as JSON").action(async (options) => {
|
|
1851
1894
|
await inboundPendingCommand({
|
|
1852
1895
|
limit: parseInt(options.limit, 10),
|
|
@@ -1865,6 +1908,9 @@ inbound.command("view <id>").description("View pending email details and payment
|
|
|
1865
1908
|
inbound.command("pay <id>").description("Pay for a pending email").requiredOption("--payment-hash <hash>", "Payment preimage from Lightning invoice").action(async (id, options) => {
|
|
1866
1909
|
await inboundPayCommand(id, { paymentHash: options.paymentHash });
|
|
1867
1910
|
});
|
|
1911
|
+
inbound.command("accept <id>").alias("a").description("Accept email without payment and whitelist sender").option("--no-whitelist", "Don't add sender to whitelist").action(async (id, options) => {
|
|
1912
|
+
await inboundAcceptCommand(id, { noWhitelist: options.whitelist === false });
|
|
1913
|
+
});
|
|
1868
1914
|
var credits = program.command("credits").description("Manage credits");
|
|
1869
1915
|
credits.command("balance").alias("bal").description("Show credit balance").action(creditsBalanceCommand);
|
|
1870
1916
|
credits.command("history").description("Show transaction history").option("-l, --limit <number>", "Number of transactions to show", "20").option("-t, --type <type>", "Filter by type (topup, email_sent, email_received, refund, bonus)").option("--json", "Output as JSON").action(async (options) => {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/commands/blocklist.ts","../src/config.ts","../src/api.ts","../src/commands/credits.ts","../src/utils/payment-polling.ts","../src/commands/inbound.ts","../src/commands/list.ts","../src/utils/cache.ts","../src/commands/login.ts","../src/commands/logout.ts","../src/commands/network.ts","../src/commands/read.ts","../src/commands/search.ts","../src/commands/send.ts","../src/commands/settings.ts","../src/commands/stats.ts","../src/commands/whitelist.ts","../src/commands/whoami.ts"],"sourcesContent":["/**\n * btc.email CLI\n *\n * Spam-free email powered by Bitcoin Lightning.\n *\n * Pattern from Claude Code:\n * - No args → Show help (TUI coming later)\n * - btcemail <command> → Execute and exit\n */\n\nimport { Command } from \"commander\"\nimport pc from \"picocolors\"\nimport {\n blocklistAddCommand,\n blocklistListCommand,\n blocklistRemoveCommand,\n creditsBalanceCommand,\n creditsHistoryCommand,\n creditsPurchaseCommand,\n inboundDeliveredCommand,\n inboundPayCommand,\n inboundPendingCommand,\n inboundViewCommand,\n listCommand,\n loginCommand,\n logoutCommand,\n networkShowCommand,\n networkSwitchCommand,\n readCommand,\n searchCommand,\n sendCommand,\n settingsAutoReplyCommand,\n settingsAutoWhitelistCommand,\n settingsPricingCommand,\n settingsRequirePaymentCommand,\n settingsShowCommand,\n statsCommand,\n whitelistAddCommand,\n whitelistListCommand,\n whitelistRemoveCommand,\n whoamiCommand,\n} from \"./commands/index.js\"\n\nconst program = new Command()\n\nprogram\n .name(\"btcemail\")\n .description(\"btc.email CLI - Spam-free email powered by Bitcoin Lightning\")\n .version(\"0.4.0\")\n\n// Authentication commands\nprogram\n .command(\"login\")\n .description(\"Authenticate with btc.email (opens browser)\")\n .action(loginCommand)\n\nprogram.command(\"logout\").description(\"Clear stored credentials\").action(logoutCommand)\n\nprogram.command(\"whoami\").description(\"Show current authenticated user\").action(whoamiCommand)\n\n// Email commands\nprogram\n .command(\"list\")\n .alias(\"ls\")\n .description(\"List emails (numbered for quick access)\")\n .option(\"-f, --folder <folder>\", \"Folder to list (inbox, sent, drafts)\", \"inbox\")\n .option(\"-l, --limit <number>\", \"Number of emails to show\", \"20\")\n .option(\"-p, --page <number>\", \"Page number\", \"1\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (options) => {\n await listCommand({\n folder: options.folder,\n limit: parseInt(options.limit, 10),\n page: parseInt(options.page, 10),\n json: options.json,\n })\n })\n\nprogram\n .command(\"read <id>\")\n .alias(\"r\")\n .description(\"Read an email by # (from list) or ID\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (id, options) => {\n await readCommand(id, { json: options.json })\n })\n\nprogram\n .command(\"search <query>\")\n .alias(\"s\")\n .description(\"Search emails by subject, body, or sender\")\n .option(\"-l, --limit <number>\", \"Number of results to show\", \"20\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (query, options) => {\n await searchCommand(query, {\n limit: parseInt(options.limit, 10),\n json: options.json,\n })\n })\n\nprogram\n .command(\"send\")\n .description(\"Send an email (with Lightning payment)\")\n .option(\"-t, --to <emails>\", \"Recipient email(s), comma-separated\")\n .option(\"-s, --subject <subject>\", \"Email subject\")\n .option(\"-b, --body <body>\", \"Email body\")\n .option(\"-f, --from <email>\", \"From email (@btc.email address)\")\n .option(\"--payment-hash <hash>\", \"Payment preimage for L402\")\n .option(\"-w, --wait\", \"Wait for payment confirmation\")\n .action(async (options) => {\n await sendCommand({\n to: options.to,\n subject: options.subject,\n body: options.body,\n fromEmail: options.from,\n paymentHash: options.paymentHash,\n wait: options.wait,\n })\n })\n\n// Inbound commands (pending and delivered emails)\nconst inbound = program\n .command(\"inbound\")\n .description(\"Manage inbound emails (pending and delivered)\")\n\ninbound\n .command(\"pending\")\n .alias(\"p\")\n .description(\"List pending emails awaiting payment\")\n .option(\"-l, --limit <number>\", \"Number of emails to show\", \"20\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (options) => {\n await inboundPendingCommand({\n limit: parseInt(options.limit, 10),\n json: options.json,\n })\n })\n\ninbound\n .command(\"delivered\")\n .alias(\"d\")\n .description(\"List delivered emails (paid by senders)\")\n .option(\"-l, --limit <number>\", \"Number of emails to show\", \"20\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (options) => {\n await inboundDeliveredCommand({\n limit: parseInt(options.limit, 10),\n json: options.json,\n })\n })\n\ninbound\n .command(\"view <id>\")\n .description(\"View pending email details and payment info\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (id, options) => {\n await inboundViewCommand(id, { json: options.json })\n })\n\ninbound\n .command(\"pay <id>\")\n .description(\"Pay for a pending email\")\n .requiredOption(\"--payment-hash <hash>\", \"Payment preimage from Lightning invoice\")\n .action(async (id, options) => {\n await inboundPayCommand(id, { paymentHash: options.paymentHash })\n })\n\n// Credits commands\nconst credits = program.command(\"credits\").description(\"Manage credits\")\n\ncredits\n .command(\"balance\")\n .alias(\"bal\")\n .description(\"Show credit balance\")\n .action(creditsBalanceCommand)\n\ncredits\n .command(\"history\")\n .description(\"Show transaction history\")\n .option(\"-l, --limit <number>\", \"Number of transactions to show\", \"20\")\n .option(\"-t, --type <type>\", \"Filter by type (topup, email_sent, email_received, refund, bonus)\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (options) => {\n await creditsHistoryCommand({\n limit: parseInt(options.limit, 10),\n type: options.type,\n json: options.json,\n })\n })\n\ncredits\n .command(\"purchase\")\n .alias(\"buy\")\n .description(\"Purchase credits with Lightning\")\n .option(\"-o, --option <index>\", \"Purchase option index (0-3)\")\n .option(\"-w, --wait\", \"Wait for payment confirmation\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (options) => {\n await creditsPurchaseCommand({\n option: options.option !== undefined ? parseInt(options.option, 10) : undefined,\n json: options.json,\n wait: options.wait,\n })\n })\n\n// Settings commands\nconst settings = program.command(\"settings\").description(\"Manage email pricing and preferences\")\n\nsettings\n .command(\"show\")\n .description(\"Show current settings\")\n .option(\"-u, --username <name>\", \"Specific @btc.email address\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (options) => {\n await settingsShowCommand({ username: options.username, json: options.json })\n })\n\nsettings\n .command(\"pricing <sats>\")\n .description(\"Set email price in sats\")\n .option(\"-u, --username <name>\", \"Specific @btc.email address\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (sats, options) => {\n await settingsPricingCommand(sats, { username: options.username, json: options.json })\n })\n\nsettings\n .command(\"require-payment <on|off>\")\n .description(\"Toggle payment requirement for unknown senders\")\n .option(\"-u, --username <name>\", \"Specific @btc.email address\")\n .action(async (value, options) => {\n await settingsRequirePaymentCommand(value, { username: options.username })\n })\n\nsettings\n .command(\"auto-whitelist <on|off>\")\n .description(\"Toggle auto-whitelist after payment\")\n .option(\"-u, --username <name>\", \"Specific @btc.email address\")\n .action(async (value, options) => {\n await settingsAutoWhitelistCommand(value, { username: options.username })\n })\n\nsettings\n .command(\"auto-reply [message]\")\n .description(\"Set custom auto-reply message\")\n .option(\"-u, --username <name>\", \"Specific @btc.email address\")\n .option(\"--clear\", \"Reset to default message\")\n .action(async (message, options) => {\n await settingsAutoReplyCommand(message, { username: options.username, clear: options.clear })\n })\n\n// Default action for settings (show)\nsettings.action(async () => {\n await settingsShowCommand({})\n})\n\n// Whitelist commands\nconst whitelist = program\n .command(\"whitelist\")\n .alias(\"wl\")\n .description(\"Manage senders who can email you for free\")\n\nwhitelist\n .command(\"list\")\n .description(\"List whitelist entries\")\n .option(\"-u, --username <name>\", \"Specific @btc.email address\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (options) => {\n await whitelistListCommand({ username: options.username, json: options.json })\n })\n\nwhitelist\n .command(\"add <entry>\")\n .description(\"Add email or @domain to whitelist\")\n .option(\"-u, --username <name>\", \"Specific @btc.email address\")\n .option(\"-n, --note <note>\", \"Optional note\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (entry, options) => {\n await whitelistAddCommand(entry, {\n username: options.username,\n note: options.note,\n json: options.json,\n })\n })\n\nwhitelist\n .command(\"remove <id>\")\n .description(\"Remove entry from whitelist by ID\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (id, options) => {\n await whitelistRemoveCommand(id, { json: options.json })\n })\n\n// Default action for whitelist (list)\nwhitelist.action(async () => {\n await whitelistListCommand({})\n})\n\n// Blocklist commands\nconst blocklist = program.command(\"blocklist\").alias(\"bl\").description(\"Manage blocked senders\")\n\nblocklist\n .command(\"list\")\n .description(\"List blocklist entries\")\n .option(\"-u, --username <name>\", \"Specific @btc.email address\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (options) => {\n await blocklistListCommand({ username: options.username, json: options.json })\n })\n\nblocklist\n .command(\"add <entry>\")\n .description(\"Add email or @domain to blocklist\")\n .option(\"-u, --username <name>\", \"Specific @btc.email address\")\n .option(\"-r, --reason <reason>\", \"Optional reason\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (entry, options) => {\n await blocklistAddCommand(entry, {\n username: options.username,\n reason: options.reason,\n json: options.json,\n })\n })\n\nblocklist\n .command(\"remove <id>\")\n .description(\"Remove entry from blocklist by ID\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (id, options) => {\n await blocklistRemoveCommand(id, { json: options.json })\n })\n\n// Default action for blocklist (list)\nblocklist.action(async () => {\n await blocklistListCommand({})\n})\n\n// Network commands\nconst network = program.command(\"network\").description(\"Manage Lightning network mode\")\n\nnetwork\n .command(\"show\")\n .description(\"Show current network mode\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (options) => {\n await networkShowCommand({ json: options.json })\n })\n\nnetwork\n .command(\"testnet\")\n .description(\"Switch to testnet (fake Bitcoin)\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (options) => {\n await networkSwitchCommand(\"testnet\", { json: options.json })\n })\n\nnetwork\n .command(\"mainnet\")\n .description(\"Switch to mainnet (real Bitcoin)\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (options) => {\n await networkSwitchCommand(\"mainnet\", { json: options.json })\n })\n\n// Default action for network (show)\nnetwork.action(async () => {\n await networkShowCommand({})\n})\n\n// Stats command\nprogram\n .command(\"stats\")\n .description(\"Show dashboard statistics\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (options) => {\n await statsCommand({ json: options.json })\n })\n\n// Default action (no command specified)\nprogram.action(() => {\n console.log()\n console.log(pc.bold(\"btc.email CLI\") + pc.dim(\" - Spam-free email powered by Bitcoin Lightning\"))\n console.log()\n program.outputHelp()\n})\n\n// Parse and run\nprogram.parse()\n","/**\n * Blocklist command for btc.email CLI\n *\n * Manage blocked senders who are silently rejected.\n */\n\nimport pc from \"picocolors\"\nimport { addToBlocklist, getBlocklist, removeFromBlocklist } from \"../api.js\"\nimport { getToken } from \"../config.js\"\n\nexport interface BlocklistListOptions {\n username?: string\n json?: boolean\n}\n\nexport interface BlocklistAddOptions {\n username?: string\n reason?: string\n json?: boolean\n}\n\nexport interface BlocklistRemoveOptions {\n json?: boolean\n}\n\n/**\n * List blocklist entries\n */\nexport async function blocklistListCommand(options: BlocklistListOptions = {}) {\n const token = getToken()\n if (!token) {\n console.error(pc.red(\"Not logged in. Run 'btcemail login' first.\"))\n process.exit(1)\n }\n\n const result = await getBlocklist(options.username)\n\n if (!result.ok) {\n console.error(pc.red(`Error: ${result.error.message}`))\n process.exit(1)\n }\n\n const { username, entries } = result.data\n\n if (options.json) {\n console.log(JSON.stringify({ username, entries }, null, 2))\n return\n }\n\n console.log()\n console.log(pc.bold(\"Blocklist for \") + pc.cyan(`${username}@btc.email`))\n console.log()\n\n if (entries.length === 0) {\n console.log(pc.dim(\" No entries in blocklist.\"))\n console.log()\n console.log(pc.dim(\" Add entries with: btcemail blocklist add <email>\"))\n console.log(pc.dim(\" Or for domains: btcemail blocklist add @domain.com\"))\n console.log()\n return\n }\n\n console.log(pc.dim(` ${entries.length} ${entries.length === 1 ? \"entry\" : \"entries\"}:`))\n console.log()\n\n for (const entry of entries) {\n const value = entry.sender_email || `@${entry.sender_domain}`\n const reason = entry.reason ? pc.dim(` - ${entry.reason}`) : \"\"\n console.log(` ${pc.red(value)}${reason}`)\n console.log(pc.dim(` ID: ${entry.id}`))\n }\n console.log()\n}\n\n/**\n * Add entry to blocklist\n */\nexport async function blocklistAddCommand(entry: string, options: BlocklistAddOptions = {}) {\n const token = getToken()\n if (!token) {\n console.error(pc.red(\"Not logged in. Run 'btcemail login' first.\"))\n process.exit(1)\n }\n\n // Check if it's a domain (starts with @)\n const isDomain = entry.startsWith(\"@\")\n const payload = isDomain\n ? { domain: entry.slice(1), reason: options.reason }\n : { email: entry, reason: options.reason }\n\n const result = await addToBlocklist(payload, options.username)\n\n if (!result.ok) {\n console.error(pc.red(`Error: ${result.error.message}`))\n process.exit(1)\n }\n\n if (options.json) {\n console.log(JSON.stringify({ success: true, entry: result.data.entry }, null, 2))\n return\n }\n\n console.log(pc.green(`Added to blocklist: ${pc.red(entry)}`))\n}\n\n/**\n * Remove entry from blocklist\n */\nexport async function blocklistRemoveCommand(id: string, options: BlocklistRemoveOptions = {}) {\n const token = getToken()\n if (!token) {\n console.error(pc.red(\"Not logged in. Run 'btcemail login' first.\"))\n process.exit(1)\n }\n\n const result = await removeFromBlocklist(id)\n\n if (!result.ok) {\n console.error(pc.red(`Error: ${result.error.message}`))\n process.exit(1)\n }\n\n if (options.json) {\n console.log(JSON.stringify({ success: true }, null, 2))\n return\n }\n\n console.log(pc.green(\"Removed from blocklist\"))\n}\n","/**\n * CLI Configuration Management\n *\n * Stores auth tokens and user preferences in ~/.btcemail/config.json\n */\n\nimport Conf from \"conf\"\n\nexport type CLIConfig = {\n auth?: {\n token: string\n expiresAt: string\n userId: string\n email: string\n }\n api?: {\n baseUrl: string\n }\n preferences?: {\n useCredits: boolean\n defaultEditor: string\n }\n}\n\nconst config = new Conf<CLIConfig>({\n projectName: \"btcemail\",\n schema: {\n auth: {\n type: \"object\",\n properties: {\n token: { type: \"string\" },\n expiresAt: { type: \"string\" },\n userId: { type: \"string\" },\n email: { type: \"string\" },\n },\n },\n api: {\n type: \"object\",\n properties: {\n baseUrl: { type: \"string\" },\n },\n default: {\n baseUrl: \"https://btc.email/api/v1\",\n },\n },\n preferences: {\n type: \"object\",\n properties: {\n useCredits: { type: \"boolean\" },\n defaultEditor: { type: \"string\" },\n },\n default: {\n useCredits: true,\n defaultEditor: \"vim\",\n },\n },\n },\n})\n\nexport function getConfig(): CLIConfig {\n return config.store\n}\n\nexport function getAuth(): CLIConfig[\"auth\"] | undefined {\n return config.get(\"auth\")\n}\n\nexport function setAuth(auth: CLIConfig[\"auth\"]): void {\n config.set(\"auth\", auth)\n}\n\nexport function clearAuth(): void {\n config.delete(\"auth\")\n}\n\nexport function getApiBaseUrl(): string {\n return process.env.BTCEMAIL_API_URL || config.get(\"api.baseUrl\") || \"https://btc.email/api/v1\"\n}\n\nexport function isAuthenticated(): boolean {\n const auth = getAuth()\n if (!auth?.token || !auth?.expiresAt) {\n return false\n }\n\n // Check if token is expired\n const expiresAt = new Date(auth.expiresAt)\n return expiresAt > new Date()\n}\n\n/**\n * Check if token is expiring soon (within 5 minutes)\n */\nexport function isTokenExpiringSoon(): boolean {\n const auth = getAuth()\n if (!auth?.token || !auth?.expiresAt) {\n return false\n }\n\n const expiresAt = new Date(auth.expiresAt)\n const fiveMinutesFromNow = new Date(Date.now() + 5 * 60 * 1000)\n return expiresAt <= fiveMinutesFromNow && expiresAt > new Date()\n}\n\n/**\n * Get time until token expires in human-readable format\n */\nexport function getTokenExpiryInfo(): { expired: boolean; expiresIn?: string } {\n const auth = getAuth()\n if (!auth?.token || !auth?.expiresAt) {\n return { expired: true }\n }\n\n const expiresAt = new Date(auth.expiresAt)\n const now = new Date()\n\n if (expiresAt <= now) {\n return { expired: true }\n }\n\n const diffMs = expiresAt.getTime() - now.getTime()\n const diffMins = Math.floor(diffMs / 60000)\n const diffHours = Math.floor(diffMins / 60)\n\n if (diffHours > 0) {\n return { expired: false, expiresIn: `${diffHours}h ${diffMins % 60}m` }\n }\n return { expired: false, expiresIn: `${diffMins}m` }\n}\n\nexport function getToken(): string | null {\n const auth = getAuth()\n if (!auth?.token) return null\n\n // Check if token is expired\n const expiresAt = new Date(auth.expiresAt)\n if (expiresAt <= new Date()) {\n clearAuth()\n return null\n }\n\n return auth.token\n}\n\nexport { config }\n","/**\n * API Client for btc.email CLI\n *\n * Handles all HTTP requests to the btc.email API.\n * v1 API returns: { success: true, data: {...}, meta: {...} }\n */\n\nimport { getApiBaseUrl, getToken } from \"./config.js\"\n\nexport type ApiResponse<T> =\n | { ok: true; data: T }\n | { ok: false; error: { code: string; message: string; details?: unknown } }\n\nexport type PaginatedResponse<T> = {\n data: T[]\n pagination: {\n total: number\n limit: number\n offset: number\n hasMore: boolean\n }\n}\n\n/**\n * v1 API response format\n */\ntype V1ApiResponse<T> = {\n success: boolean\n data?: T\n error?: { code: string; message: string; details?: unknown }\n meta?: { requestId: string; timestamp: string }\n pagination?: {\n total: number\n limit: number\n offset: number\n hasMore: boolean\n }\n}\n\n/**\n * Make an authenticated API request\n */\nexport async function apiRequest<T>(\n endpoint: string,\n options: RequestInit = {}\n): Promise<ApiResponse<T>> {\n const token = getToken()\n const baseUrl = getApiBaseUrl()\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n }\n\n if (token) {\n headers.Authorization = `Bearer ${token}`\n }\n\n try {\n const response = await fetch(`${baseUrl}${endpoint}`, {\n ...options,\n headers,\n })\n\n const json = (await response.json()) as V1ApiResponse<T>\n\n // Handle v1 API format: { success: boolean, data?: T, error?: {...} }\n if (!response.ok || json.success === false) {\n return {\n ok: false,\n error: json.error || {\n code: \"UNKNOWN_ERROR\",\n message: `Request failed with status ${response.status}`,\n },\n }\n }\n\n // For paginated responses, include pagination in the result\n if (json.pagination) {\n return {\n ok: true,\n data: { data: json.data, pagination: json.pagination } as T,\n }\n }\n\n // Extract data from v1 response format\n return { ok: true, data: json.data as T }\n } catch (error) {\n return {\n ok: false,\n error: {\n code: \"NETWORK_ERROR\",\n message: error instanceof Error ? error.message : \"Network request failed\",\n },\n }\n }\n}\n\n/**\n * Make an unauthenticated API request (for login, etc.)\n */\nexport async function publicRequest<T>(\n endpoint: string,\n options: RequestInit = {}\n): Promise<ApiResponse<T>> {\n const baseUrl = getApiBaseUrl()\n\n try {\n const response = await fetch(`${baseUrl}${endpoint}`, {\n ...options,\n headers: {\n \"Content-Type\": \"application/json\",\n ...options.headers,\n },\n })\n\n const json = (await response.json()) as V1ApiResponse<T>\n\n if (!response.ok || json.success === false) {\n return {\n ok: false,\n error: json.error || {\n code: \"UNKNOWN_ERROR\",\n message: `Request failed with status ${response.status}`,\n },\n }\n }\n\n return { ok: true, data: json.data as T }\n } catch (error) {\n return {\n ok: false,\n error: {\n code: \"NETWORK_ERROR\",\n message: error instanceof Error ? error.message : \"Network request failed\",\n },\n }\n }\n}\n\n// API endpoint helpers\n\nexport async function getEmails(options: {\n folder?: string\n limit?: number\n offset?: number\n search?: string\n}) {\n const params = new URLSearchParams()\n if (options.folder) params.set(\"folder\", options.folder)\n if (options.limit) params.set(\"limit\", String(options.limit))\n if (options.offset) params.set(\"offset\", String(options.offset))\n if (options.search) params.set(\"search\", options.search)\n\n return apiRequest<PaginatedResponse<Email>>(`/email?${params}`)\n}\n\nexport async function getEmail(id: string) {\n return apiRequest<Email>(`/email/${id}`)\n}\n\nexport async function getCreditsBalance() {\n return apiRequest<CreditBalance>(\"/credits/balance\")\n}\n\nexport type CreditBalance = {\n balanceSats: number\n lifetimePurchasedSats: number\n lifetimeSpentSats: number\n lastPurchaseAt: string | null\n}\n\nexport async function getWhoami() {\n return apiRequest<{ id: string; email: string; username?: string }>(\"/auth/whoami\")\n}\n\n// Pending/Inbound email functions\n\nexport async function getPendingEmails(options: { limit?: number; offset?: number } = {}) {\n const params = new URLSearchParams()\n if (options.limit) params.set(\"limit\", String(options.limit))\n if (options.offset) params.set(\"offset\", String(options.offset))\n\n return apiRequest<PaginatedResponse<PendingEmail>>(`/inbound/pending?${params}`)\n}\n\nexport async function getPendingEmail(id: string) {\n return apiRequest<PendingEmailDetail>(`/inbound/${id}`)\n}\n\nexport async function payForEmail(id: string, paymentHash: string) {\n return apiRequest<{ emailId: string; status: string }>(`/inbound/${id}/pay`, {\n method: \"POST\",\n body: JSON.stringify({ paymentHash }),\n })\n}\n\n// Send email functions\n\nexport async function sendEmail(options: {\n to: string[]\n subject: string\n body: string\n bodyText?: string\n fromEmail: string\n paymentHash?: string\n}) {\n return apiRequest<{ emailId: string; status: string; messageId?: string }>(\"/email/send\", {\n method: \"POST\",\n body: JSON.stringify(options),\n })\n}\n\nexport async function getL402Invoice(options: {\n fromEmail: string\n toEmails: string[]\n amountSats?: number\n}) {\n // L402 endpoint is at /api/l402, not /api/v1/l402\n // Derive root API URL from v1 base URL\n const v1BaseUrl = getApiBaseUrl()\n const rootApiUrl = v1BaseUrl.replace(\"/api/v1\", \"/api\")\n const token = getToken()\n\n const headers: HeadersInit = {\n \"Content-Type\": \"application/json\",\n }\n if (token) {\n headers.Authorization = `Bearer ${token}`\n }\n\n try {\n const response = await fetch(`${rootApiUrl}/l402/invoice`, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n sender_email: options.fromEmail,\n recipient_emails: options.toEmails,\n amount_sats: options.amountSats,\n }),\n })\n\n const json = (await response.json()) as {\n success: boolean\n data?: L402Invoice\n error?: { code: string; message: string; details?: unknown }\n }\n\n if (!response.ok || json.success === false) {\n return {\n ok: false as const,\n error: json.error || {\n code: \"UNKNOWN_ERROR\",\n message: `Request failed with status ${response.status}`,\n },\n }\n }\n\n return { ok: true as const, data: json.data as L402Invoice }\n } catch (error) {\n return {\n ok: false as const,\n error: {\n code: \"NETWORK_ERROR\",\n message: error instanceof Error ? error.message : \"Network request failed\",\n },\n }\n }\n}\n\n// Types\n\nexport type Email = {\n id: string\n subject: string\n from: { email: string; name?: string }\n to: { email: string; name?: string }[]\n snippet: string\n body?: string\n bodyText?: string\n date: string\n unread: boolean\n labels: string[]\n}\n\nexport type PendingEmail = {\n id: string\n subject: string\n from: { email: string; name?: string }\n amountSats: number\n createdAt: string\n}\n\nexport type PendingEmailDetail = {\n id: string\n subject: string\n from: { email: string; name?: string }\n body: string\n bodyText: string\n amountSats: number\n createdAt: string\n paymentHash: string | null\n}\n\nexport type L402Invoice = {\n invoice: string\n paymentHash: string\n amountSats: number\n expiresAt: string\n}\n\n// Delivered emails (paid inbound emails)\n\nexport type DeliveredEmail = {\n id: string\n subject: string\n from: { email: string; name?: string }\n snippet: string\n date: string\n}\n\nexport async function getDeliveredEmails(options: { limit?: number; offset?: number } = {}) {\n const params = new URLSearchParams()\n if (options.limit) params.set(\"limit\", String(options.limit))\n if (options.offset) params.set(\"offset\", String(options.offset))\n\n return apiRequest<PaginatedResponse<DeliveredEmail>>(`/inbound/delivered?${params}`)\n}\n\n// Credit transactions\n\nexport type CreditTransaction = {\n id: string\n amountSats: number\n transactionType: string\n balanceAfter: number\n referenceId?: string\n createdAt: string\n}\n\nexport async function getCreditTransactions(\n options: { limit?: number; offset?: number; type?: string } = {}\n) {\n const params = new URLSearchParams()\n if (options.limit) params.set(\"limit\", String(options.limit))\n if (options.offset) params.set(\"offset\", String(options.offset))\n if (options.type) params.set(\"type\", options.type)\n\n return apiRequest<PaginatedResponse<CreditTransaction>>(`/credits/transactions?${params}`)\n}\n\n// Credit purchase\n\nexport type CreditPurchaseOption = {\n amountSats: number\n priceSats: number\n bonusSats: number\n label: string\n description: string\n}\n\nexport type CreditPurchaseResult = {\n paymentId: string\n invoice: string\n paymentHash: string\n amountSats: number\n creditsToReceive: number\n bonusSats: number\n expiresAt: string\n}\n\nexport async function purchaseCredits(optionIndex: number) {\n return apiRequest<CreditPurchaseResult>(\"/credits/purchase\", {\n method: \"POST\",\n body: JSON.stringify({ optionIndex }),\n })\n}\n\n// Check payment status\nexport type PaymentStatusResult = {\n paid: boolean\n delivered?: boolean\n status?: string\n pendingEmailId?: string\n}\n\nexport async function checkPaymentStatus(\n paymentHash: string\n): Promise<ApiResponse<PaymentStatusResult>> {\n // Payment status endpoint is at /api/lightning/webhook (GET)\n // Derive root API URL from v1 base URL\n const v1BaseUrl = getApiBaseUrl()\n const rootApiUrl = v1BaseUrl.replace(\"/api/v1\", \"/api\")\n const token = getToken()\n\n const headers: HeadersInit = {\n \"Content-Type\": \"application/json\",\n }\n if (token) {\n headers.Authorization = `Bearer ${token}`\n }\n\n try {\n const response = await fetch(`${rootApiUrl}/lightning/webhook?payment_hash=${paymentHash}`, {\n headers,\n })\n\n const json = (await response.json()) as {\n success: boolean\n paid?: boolean\n delivered?: boolean\n status?: string\n state?: string\n pendingEmailId?: string\n error?: { code: string; message: string }\n }\n\n if (!response.ok || json.success === false) {\n return {\n ok: false,\n error: json.error || {\n code: \"UNKNOWN_ERROR\",\n message: `Request failed with status ${response.status}`,\n },\n }\n }\n\n return {\n ok: true,\n data: {\n paid: json.paid || false,\n delivered: json.delivered,\n status: json.status || json.state,\n pendingEmailId: json.pendingEmailId,\n },\n }\n } catch (error) {\n return {\n ok: false,\n error: {\n code: \"NETWORK_ERROR\",\n message: error instanceof Error ? error.message : \"Network request failed\",\n },\n }\n }\n}\n\n// Settings API\n\nexport type UserSettings = {\n username: string\n usernames: string[]\n settings: {\n default_price_sats: number\n auto_whitelist_on_payment: boolean\n require_payment_from_unknown: boolean\n custom_auto_reply_body: string | null\n }\n}\n\nexport async function getSettings(username?: string) {\n const params = username ? `?username=${username}` : \"\"\n return apiRequest<UserSettings>(`/settings${params}`)\n}\n\nexport async function updateSettings(\n settings: {\n default_price_sats?: number\n auto_whitelist_on_payment?: boolean\n require_payment_from_unknown?: boolean\n custom_auto_reply_body?: string | null\n },\n username?: string\n) {\n const params = username ? `?username=${username}` : \"\"\n return apiRequest<{ username: string; settings: UserSettings[\"settings\"] }>(\n `/settings${params}`,\n {\n method: \"POST\",\n body: JSON.stringify(settings),\n }\n )\n}\n\n// Whitelist API\n\nexport type WhitelistEntry = {\n id: string\n sender_email: string | null\n sender_domain: string | null\n added_via: string\n note: string | null\n added_at: string\n}\n\nexport async function getWhitelist(username?: string) {\n const params = username ? `?username=${username}` : \"\"\n return apiRequest<{ username: string; entries: WhitelistEntry[] }>(`/whitelist${params}`)\n}\n\nexport async function addToWhitelist(\n entry: { email?: string; domain?: string; note?: string },\n username?: string\n) {\n const params = username ? `?username=${username}` : \"\"\n return apiRequest<{ entry: WhitelistEntry }>(`/whitelist${params}`, {\n method: \"POST\",\n body: JSON.stringify(entry),\n })\n}\n\nexport async function removeFromWhitelist(id: string) {\n return apiRequest<{ success: boolean }>(`/whitelist/${id}`, {\n method: \"DELETE\",\n })\n}\n\n// Blocklist API\n\nexport type BlocklistEntry = {\n id: string\n sender_email: string | null\n sender_domain: string | null\n reason: string | null\n blocked_at: string\n}\n\nexport async function getBlocklist(username?: string) {\n const params = username ? `?username=${username}` : \"\"\n return apiRequest<{ username: string; entries: BlocklistEntry[] }>(`/blocklist${params}`)\n}\n\nexport async function addToBlocklist(\n entry: { email?: string; domain?: string; reason?: string },\n username?: string\n) {\n const params = username ? `?username=${username}` : \"\"\n return apiRequest<{ entry: BlocklistEntry }>(`/blocklist${params}`, {\n method: \"POST\",\n body: JSON.stringify(entry),\n })\n}\n\nexport async function removeFromBlocklist(id: string) {\n return apiRequest<{ success: boolean }>(`/blocklist/${id}`, {\n method: \"DELETE\",\n })\n}\n\n// Network API\n\nexport type NetworkInfo = {\n network_mode: \"testnet\" | \"mainnet\"\n networks: {\n testnet: { available: boolean }\n mainnet: { available: boolean }\n }\n}\n\nexport async function getNetwork() {\n return apiRequest<NetworkInfo>(\"/network\")\n}\n\nexport async function setNetwork(network: \"testnet\" | \"mainnet\") {\n return apiRequest<{ network_mode: string; message: string }>(\"/network\", {\n method: \"POST\",\n body: JSON.stringify({ network }),\n })\n}\n\n// Stats API\n\nexport type DashboardStats = {\n totalReceived: number\n totalSent: number\n pendingCount: number\n addressCount: number\n usernames: string[]\n}\n\nexport async function getStats() {\n return apiRequest<DashboardStats>(\"/stats\")\n}\n\n// Get purchase options (hardcoded since they match server)\nexport function getCreditPurchaseOptions(): CreditPurchaseOption[] {\n return [\n {\n amountSats: 1000,\n priceSats: 1000,\n bonusSats: 0,\n label: \"1,000 sats\",\n description: \"Good for ~10 emails\",\n },\n {\n amountSats: 5000,\n priceSats: 4500,\n bonusSats: 500,\n label: \"5,000 sats\",\n description: \"Good for ~50 emails (+10% bonus)\",\n },\n {\n amountSats: 10000,\n priceSats: 8500,\n bonusSats: 1500,\n label: \"10,000 sats\",\n description: \"Good for ~100 emails (+15% bonus)\",\n },\n {\n amountSats: 50000,\n priceSats: 40000,\n bonusSats: 10000,\n label: \"50,000 sats\",\n description: \"Good for ~500 emails (+20% bonus)\",\n },\n ]\n}\n","/**\n * Credits Command\n *\n * Shows credit balance, transaction history, and purchase options.\n */\n\nimport ora from \"ora\"\nimport pc from \"picocolors\"\nimport qrcode from \"qrcode-terminal\"\nimport {\n checkPaymentStatus,\n getCreditPurchaseOptions,\n getCreditsBalance,\n getCreditTransactions,\n purchaseCredits,\n} from \"../api.js\"\nimport { isAuthenticated } from \"../config.js\"\nimport { pollForPayment } from \"../utils/payment-polling.js\"\n\nexport async function creditsBalanceCommand(): Promise<void> {\n if (!isAuthenticated()) {\n console.log(pc.yellow(\"Not logged in.\"))\n console.log(pc.dim(\"Run `btcemail login` to authenticate.\"))\n process.exit(1)\n }\n\n const spinner = ora(\"Fetching balance...\").start()\n\n const result = await getCreditsBalance()\n\n if (!result.ok) {\n spinner.fail(`Error: ${result.error.message}`)\n process.exit(1)\n }\n\n spinner.stop()\n\n const { balanceSats, lifetimePurchasedSats, lifetimeSpentSats } = result.data\n\n console.log()\n console.log(pc.bold(\"Credit Balance\"))\n console.log()\n console.log(` ${pc.green(formatSats(balanceSats))} sats`)\n console.log()\n\n if (lifetimePurchasedSats > 0 || lifetimeSpentSats > 0) {\n console.log(pc.dim(` Purchased: ${formatSats(lifetimePurchasedSats)} sats`))\n console.log(pc.dim(` Spent: ${formatSats(lifetimeSpentSats)} sats`))\n console.log()\n }\n\n if (balanceSats === 0) {\n console.log(pc.dim(\" No credits available.\"))\n console.log(pc.dim(\" Run `btcemail credits purchase` to buy credits.\"))\n console.log()\n }\n}\n\nexport type CreditsHistoryOptions = {\n limit?: number\n type?: string\n json?: boolean\n}\n\nexport async function creditsHistoryCommand(options: CreditsHistoryOptions): Promise<void> {\n if (!isAuthenticated()) {\n console.log(pc.yellow(\"Not logged in.\"))\n console.log(pc.dim(\"Run `btcemail login` to authenticate.\"))\n process.exit(1)\n }\n\n const spinner = ora(\"Loading transaction history...\").start()\n\n const result = await getCreditTransactions({\n limit: options.limit || 20,\n type: options.type,\n })\n\n if (!result.ok) {\n spinner.fail(`Error: ${result.error.message}`)\n process.exit(1)\n }\n\n const { data: transactions, pagination } = result.data\n\n spinner.stop()\n\n // JSON output mode\n if (options.json) {\n console.log(JSON.stringify({ transactions, pagination }, null, 2))\n return\n }\n\n // Table output\n console.log()\n console.log(pc.bold(\"Transaction History\"))\n console.log()\n\n if (transactions.length === 0) {\n console.log(pc.dim(\" No transactions found.\"))\n console.log()\n return\n }\n\n // Header\n console.log(\n ` ${pc.dim(\"Date\".padEnd(12))} ${pc.dim(\"Type\".padEnd(15))} ${pc.dim(\"Amount\".padEnd(12))} ${pc.dim(\"Balance\")}`\n )\n console.log(pc.dim(` ${\"-\".repeat(55)}`))\n\n // Rows\n for (const tx of transactions) {\n const date = formatDate(tx.createdAt)\n const type = formatTransactionType(tx.transactionType).padEnd(15)\n const amount = formatAmount(tx.amountSats).padEnd(12)\n const balance = formatSats(tx.balanceAfter)\n\n console.log(` ${date.padEnd(12)} ${type} ${amount} ${pc.dim(balance)}`)\n }\n\n console.log()\n\n if (pagination.hasMore) {\n console.log(pc.dim(` Use --limit to see more transactions.`))\n console.log()\n }\n}\n\nexport type CreditsPurchaseOptions = {\n option?: number\n json?: boolean\n wait?: boolean\n}\n\nexport async function creditsPurchaseCommand(options: CreditsPurchaseOptions): Promise<void> {\n if (!isAuthenticated()) {\n console.log(pc.yellow(\"Not logged in.\"))\n console.log(pc.dim(\"Run `btcemail login` to authenticate.\"))\n process.exit(1)\n }\n\n const purchaseOptions = getCreditPurchaseOptions()\n\n // If no option specified, show available options\n if (options.option === undefined) {\n console.log()\n console.log(pc.bold(\"Purchase Options\"))\n console.log()\n\n purchaseOptions.forEach((opt, index) => {\n console.log(` ${pc.cyan(`[${index}]`)} ${opt.label}`)\n console.log(` ${pc.dim(opt.description)}`)\n console.log(` ${pc.dim(`Price: ${formatSats(opt.priceSats)} sats`)}`)\n if (opt.bonusSats > 0) {\n console.log(` ${pc.green(`+${formatSats(opt.bonusSats)} bonus sats`)}`)\n }\n console.log()\n })\n\n console.log(pc.dim(\" Usage: btcemail credits purchase --option <index>\"))\n console.log(pc.dim(\" Add --wait to wait for payment confirmation.\"))\n console.log()\n return\n }\n\n // Validate option index\n if (options.option < 0 || options.option >= purchaseOptions.length) {\n console.error(pc.red(`Error: Invalid option. Choose 0-${purchaseOptions.length - 1}.`))\n process.exit(1)\n }\n\n const _selectedOption = purchaseOptions[options.option]\n\n const spinner = ora(\"Creating invoice...\").start()\n\n const result = await purchaseCredits(options.option)\n\n if (!result.ok) {\n spinner.fail(`Error: ${result.error.message}`)\n process.exit(1)\n }\n\n spinner.stop()\n\n const purchase = result.data\n\n // JSON output mode\n if (options.json) {\n console.log(JSON.stringify(purchase, null, 2))\n return\n }\n\n console.log()\n console.log(pc.bold(\"Lightning Invoice\"))\n console.log()\n console.log(` ${pc.dim(\"Amount:\")} ${formatSats(purchase.amountSats)} sats`)\n console.log(` ${pc.dim(\"Credits:\")} ${formatSats(purchase.creditsToReceive)} sats`)\n if (purchase.bonusSats > 0) {\n console.log(` ${pc.dim(\"Bonus:\")} ${pc.green(`+${formatSats(purchase.bonusSats)} sats`)}`)\n }\n console.log()\n\n // Display QR code\n console.log(pc.bold(\"Scan to pay:\"))\n console.log()\n qrcode.generate(purchase.invoice, { small: true }, (qr) => {\n // Indent the QR code\n const indentedQr = qr\n .split(\"\\n\")\n .map((line) => ` ${line}`)\n .join(\"\\n\")\n console.log(indentedQr)\n })\n console.log()\n\n console.log(pc.bold(\"Invoice:\"))\n console.log()\n console.log(` ${purchase.invoice}`)\n console.log()\n console.log(pc.dim(` Payment hash: ${purchase.paymentHash}`))\n console.log(pc.dim(` Expires: ${new Date(purchase.expiresAt).toLocaleString()}`))\n console.log()\n\n // If --wait flag is set, poll for payment\n if (options.wait) {\n console.log()\n const status = await pollForPayment({\n paymentHash: purchase.paymentHash,\n checkFn: async (hash) => {\n const result = await checkPaymentStatus(hash)\n if (result.ok) {\n return { paid: result.data.paid }\n }\n return { paid: false }\n },\n onPaid: async () => {\n // Check updated balance\n const balanceResult = await getCreditsBalance()\n if (balanceResult.ok) {\n console.log()\n console.log(\n `${pc.dim(\"New balance:\")} ${pc.green(formatSats(balanceResult.data.balanceSats))} sats`\n )\n }\n },\n })\n\n if (!status.paid) {\n console.log(pc.dim(\" You can still pay the invoice and credits will be added.\"))\n }\n console.log()\n } else {\n console.log(pc.dim(\" Scan the QR code or copy the invoice above to pay.\"))\n console.log(pc.dim(\" Use --wait to wait for payment confirmation.\"))\n console.log()\n }\n}\n\nfunction formatSats(sats: number): string {\n return sats.toLocaleString()\n}\n\nfunction formatAmount(sats: number): string {\n if (sats >= 0) {\n return pc.green(`+${formatSats(sats)}`)\n }\n return pc.red(formatSats(sats))\n}\n\nfunction formatTransactionType(type: string): string {\n const types: Record<string, string> = {\n topup: \"Top-up\",\n email_sent: \"Email Sent\",\n email_received: \"Email Received\",\n refund: \"Refund\",\n bonus: \"Bonus\",\n }\n return types[type] || type\n}\n\nfunction formatDate(dateString: string): string {\n const date = new Date(dateString)\n return date.toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n })\n}\n","/**\n * Payment Polling Utility\n *\n * Polls for payment status and shows a progress indicator.\n */\n\nimport pc from \"picocolors\"\n\nexport type PaymentStatus = {\n paid: boolean\n delivered?: boolean\n status?: string\n}\n\nexport type PollOptions = {\n paymentHash: string\n checkFn: (paymentHash: string) => Promise<PaymentStatus>\n maxAttempts?: number\n intervalMs?: number\n onPaid?: () => void\n}\n\nconst SPINNER_FRAMES = [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"]\n\n/**\n * Poll for payment status with a spinner\n */\nexport async function pollForPayment(options: PollOptions): Promise<PaymentStatus> {\n const { paymentHash, checkFn, maxAttempts = 120, intervalMs = 2500, onPaid } = options\n\n let frame = 0\n let attempts = 0\n\n // Print initial status\n process.stdout.write(`${pc.cyan(SPINNER_FRAMES[0])} Waiting for payment...`)\n\n while (attempts < maxAttempts) {\n try {\n const status = await checkFn(paymentHash)\n\n if (status.paid) {\n // Clear the spinner line\n process.stdout.write(`\\r${\" \".repeat(50)}\\r`)\n console.log(`${pc.green(\"✓\")} Payment received!`)\n if (onPaid) onPaid()\n return status\n }\n } catch {\n // Ignore errors, keep polling\n }\n\n // Update spinner\n frame = (frame + 1) % SPINNER_FRAMES.length\n const timeLeft = Math.ceil(((maxAttempts - attempts) * intervalMs) / 1000 / 60)\n process.stdout.write(\n `\\r${pc.cyan(SPINNER_FRAMES[frame])} Waiting for payment... (${timeLeft}m remaining)`\n )\n\n // Wait before next check\n await sleep(intervalMs)\n attempts++\n }\n\n // Clear the spinner line\n process.stdout.write(`\\r${\" \".repeat(60)}\\r`)\n console.log(`${pc.yellow(\"⚠\")} Timed out waiting for payment.`)\n\n return { paid: false }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\n/**\n * Create a simple progress indicator (non-polling)\n */\nexport function createSpinner(message: string): { stop: (success?: boolean) => void } {\n let frame = 0\n let running = true\n\n const interval = setInterval(() => {\n if (!running) return\n frame = (frame + 1) % SPINNER_FRAMES.length\n process.stdout.write(`\\r${pc.cyan(SPINNER_FRAMES[frame])} ${message}`)\n }, 80)\n\n return {\n stop: (success = true) => {\n running = false\n clearInterval(interval)\n process.stdout.write(`\\r${\" \".repeat(message.length + 5)}\\r`)\n if (success) {\n console.log(`${pc.green(\"✓\")} ${message}`)\n } else {\n console.log(`${pc.red(\"✗\")} ${message}`)\n }\n },\n }\n}\n","/**\n * Inbound Commands\n *\n * View and pay for pending emails that require payment.\n */\n\nimport ora from \"ora\"\nimport pc from \"picocolors\"\nimport { getDeliveredEmails, getPendingEmail, getPendingEmails, payForEmail } from \"../api.js\"\nimport { isAuthenticated } from \"../config.js\"\n\nexport type InboundListOptions = {\n limit?: number\n json?: boolean\n}\n\nexport async function inboundDeliveredCommand(options: InboundListOptions): Promise<void> {\n if (!isAuthenticated()) {\n console.log(pc.yellow(\"Not logged in.\"))\n console.log(pc.dim(\"Run `btcemail login` to authenticate.\"))\n process.exit(1)\n }\n\n const spinner = ora(\"Loading delivered emails...\").start()\n\n const result = await getDeliveredEmails({\n limit: options.limit || 20,\n })\n\n if (!result.ok) {\n spinner.fail(`Error: ${result.error.message}`)\n process.exit(1)\n }\n\n const { data: emails, pagination } = result.data\n\n spinner.stop()\n\n // JSON output mode\n if (options.json) {\n console.log(JSON.stringify({ emails, pagination }, null, 2))\n return\n }\n\n console.log()\n console.log(pc.bold(`Delivered (${pagination.total} paid emails received)`))\n console.log()\n\n if (emails.length === 0) {\n console.log(pc.dim(\" No delivered emails yet.\"))\n console.log()\n return\n }\n\n // Header\n console.log(\n ` ${pc.dim(\"#\".padEnd(4))} ${pc.dim(\"From\".padEnd(28))} ${pc.dim(\"Subject\".padEnd(40))} ${pc.dim(\"Date\")}`\n )\n console.log(pc.dim(` ${\"-\".repeat(85)}`))\n\n // Rows\n emails.forEach((email, index) => {\n const num = pc.cyan(String(index + 1).padEnd(4))\n const from = truncate(email.from.name || email.from.email, 26).padEnd(28)\n const subject = truncate(email.subject, 38).padEnd(40)\n const date = formatDate(email.date)\n\n console.log(` ${num}${from} ${subject} ${pc.dim(date)}`)\n })\n\n console.log()\n\n if (pagination.hasMore) {\n console.log(\n pc.dim(` Showing ${emails.length} of ${pagination.total}. Use --limit to see more.`)\n )\n console.log()\n }\n\n console.log(pc.dim(\" Read email: btcemail read <id>\"))\n console.log()\n}\n\nexport async function inboundPendingCommand(options: InboundListOptions): Promise<void> {\n if (!isAuthenticated()) {\n console.log(pc.yellow(\"Not logged in.\"))\n console.log(pc.dim(\"Run `btcemail login` to authenticate.\"))\n process.exit(1)\n }\n\n const spinner = ora(\"Loading pending emails...\").start()\n\n const result = await getPendingEmails({\n limit: options.limit || 20,\n })\n\n if (!result.ok) {\n spinner.fail(`Error: ${result.error.message}`)\n process.exit(1)\n }\n\n const { data: emails, pagination } = result.data\n\n spinner.stop()\n\n // JSON output mode\n if (options.json) {\n console.log(JSON.stringify({ emails, pagination }, null, 2))\n return\n }\n\n console.log()\n console.log(pc.bold(`Pending (${pagination.total} awaiting payment)`))\n console.log()\n\n if (emails.length === 0) {\n console.log(pc.dim(\" No pending emails.\"))\n console.log()\n return\n }\n\n // Header\n console.log(\n ` ${pc.dim(\"#\".padEnd(4))} ${pc.dim(\"From\".padEnd(28))} ${pc.dim(\"Subject\".padEnd(35))} ${pc.dim(\"Sats\")}`\n )\n console.log(pc.dim(` ${\"-\".repeat(80)}`))\n\n // Rows\n emails.forEach((email, index) => {\n const num = pc.cyan(String(index + 1).padEnd(4))\n const from = truncate(email.from.name || email.from.email, 26).padEnd(28)\n const subject = truncate(email.subject, 33).padEnd(35)\n const sats = pc.yellow(String(email.amountSats))\n\n console.log(` ${num}${from} ${subject} ${sats}`)\n })\n\n console.log()\n\n if (pagination.hasMore) {\n console.log(\n pc.dim(` Showing ${emails.length} of ${pagination.total}. Use --limit to see more.`)\n )\n console.log()\n }\n\n console.log(pc.dim(\" View details: btcemail inbound view <id>\"))\n console.log()\n}\n\nexport type InboundViewOptions = {\n json?: boolean\n}\n\nexport async function inboundViewCommand(id: string, options: InboundViewOptions): Promise<void> {\n if (!isAuthenticated()) {\n console.log(pc.yellow(\"Not logged in.\"))\n console.log(pc.dim(\"Run `btcemail login` to authenticate.\"))\n process.exit(1)\n }\n\n const spinner = ora(\"Loading email details...\").start()\n\n const result = await getPendingEmail(id)\n\n if (!result.ok) {\n if (result.error.code === \"NOT_FOUND\") {\n spinner.fail(`Pending email not found: ${id}`)\n } else {\n spinner.fail(`Error: ${result.error.message}`)\n }\n process.exit(1)\n }\n\n spinner.stop()\n\n const email = result.data\n\n // JSON output mode\n if (options.json) {\n console.log(JSON.stringify(email, null, 2))\n return\n }\n\n // Formatted output\n console.log()\n console.log(pc.bold(email.subject || \"(No subject)\"))\n console.log()\n console.log(`${pc.dim(\"From:\")} ${formatAddress(email.from)}`)\n console.log(`${pc.dim(\"Date:\")} ${formatFullDate(email.createdAt)}`)\n console.log(`${pc.dim(\"ID:\")} ${email.id}`)\n console.log()\n console.log(pc.yellow(`Payment Required: ${email.amountSats} sats`))\n console.log()\n\n if (email.paymentHash) {\n console.log(pc.dim(\"To receive this email, pay the invoice and run:\"))\n console.log(pc.cyan(` btcemail inbound pay ${email.id} --payment-hash <preimage>`))\n } else {\n console.log(pc.dim(\"Payment information not available.\"))\n }\n\n console.log()\n console.log(pc.dim(\"-\".repeat(60)))\n console.log()\n console.log(pc.dim(\"Preview (full content available after payment):\"))\n console.log()\n console.log(truncate(email.bodyText || email.body, 200))\n console.log()\n}\n\nexport type InboundPayOptions = {\n paymentHash: string\n}\n\nexport async function inboundPayCommand(id: string, options: InboundPayOptions): Promise<void> {\n if (!isAuthenticated()) {\n console.log(pc.yellow(\"Not logged in.\"))\n console.log(pc.dim(\"Run `btcemail login` to authenticate.\"))\n process.exit(1)\n }\n\n if (!options.paymentHash) {\n console.error(pc.red(\"Payment hash is required. Use --payment-hash <preimage>\"))\n process.exit(1)\n }\n\n const spinner = ora(\"Verifying payment...\").start()\n\n const result = await payForEmail(id, options.paymentHash)\n\n if (!result.ok) {\n if (result.error.code === \"PAYMENT_INVALID\") {\n spinner.fail(\"Payment verification failed.\")\n console.log(pc.dim(\"Make sure you paid the correct invoice and provided the preimage.\"))\n } else if (result.error.code === \"NOT_FOUND\") {\n spinner.fail(`Pending email not found or already delivered: ${id}`)\n } else {\n spinner.fail(`Error: ${result.error.message}`)\n }\n process.exit(1)\n }\n\n spinner.succeed(\"Payment verified! Email delivered.\")\n console.log()\n console.log(`${pc.dim(\"Email ID:\")} ${result.data.emailId}`)\n console.log(`${pc.dim(\"Status:\")} ${result.data.status}`)\n console.log()\n console.log(pc.dim(`Read email: btcemail read ${result.data.emailId}`))\n console.log()\n}\n\nfunction truncate(str: string, maxLength: number): string {\n if (str.length <= maxLength) return str\n return `${str.slice(0, maxLength - 1)}…`\n}\n\nfunction formatAddress(addr: { email: string; name?: string }): string {\n if (addr.name) {\n return `${addr.name} <${addr.email}>`\n }\n return addr.email\n}\n\nfunction formatFullDate(dateString: string): string {\n const date = new Date(dateString)\n return date.toLocaleString(\"en-US\", {\n weekday: \"short\",\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n })\n}\n\nfunction formatDate(dateString: string): string {\n const date = new Date(dateString)\n const now = new Date()\n const diffMs = now.getTime() - date.getTime()\n const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24))\n\n if (diffDays === 0) {\n return date.toLocaleTimeString(\"en-US\", {\n hour: \"numeric\",\n minute: \"2-digit\",\n })\n }\n\n if (diffDays < 7) {\n return date.toLocaleDateString(\"en-US\", { weekday: \"short\" })\n }\n\n return date.toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n })\n}\n","/**\n * List Command\n *\n * Lists emails with pagination, numbering, and caching.\n * Cached list enables number-based access: `btcemail read 3`\n */\n\nimport ora from \"ora\"\nimport pc from \"picocolors\"\nimport { getEmails } from \"../api.js\"\nimport { isAuthenticated } from \"../config.js\"\nimport { type CachedEmail, cacheEmailList } from \"../utils/cache.js\"\n\nexport type ListOptions = {\n folder?: string\n limit?: number\n page?: number\n json?: boolean\n}\n\nexport async function listCommand(options: ListOptions): Promise<void> {\n if (!isAuthenticated()) {\n console.log(pc.yellow(\"Not logged in.\"))\n console.log(pc.dim(\"Run `btcemail login` to authenticate.\"))\n process.exit(1)\n }\n\n const folder = options.folder || \"inbox\"\n const limit = options.limit || 20\n const page = options.page || 1\n const offset = (page - 1) * limit\n\n const spinner = ora(\"Loading emails...\").start()\n\n const result = await getEmails({\n folder,\n limit,\n offset,\n })\n\n if (!result.ok) {\n spinner.fail(`Error: ${result.error.message}`)\n process.exit(1)\n }\n\n const { data: emails, pagination } = result.data\n\n spinner.stop()\n\n // Cache emails for number-based access\n const cachedEmails: CachedEmail[] = emails.map((e) => ({\n id: e.id,\n subject: e.subject,\n from: e.from.name || e.from.email,\n }))\n cacheEmailList(folder, cachedEmails)\n\n // JSON output mode\n if (options.json) {\n console.log(JSON.stringify({ emails, pagination }, null, 2))\n return\n }\n\n // Table output\n console.log()\n console.log(pc.bold(`${capitalize(folder)} (${pagination.total} emails)`))\n console.log()\n\n if (emails.length === 0) {\n console.log(pc.dim(\" No emails found.\"))\n console.log()\n return\n }\n\n // Header with # column\n console.log(\n ` ${pc.dim(\"#\".padEnd(4))} ${pc.dim(\"From\".padEnd(25))} ${pc.dim(\"Subject\".padEnd(45))} ${pc.dim(\"Date\")}`\n )\n console.log(pc.dim(` ${\"-\".repeat(85)}`))\n\n // Rows with numbering\n emails.forEach((email, index) => {\n const num = pc.cyan(String(index + 1).padEnd(4))\n const unreadMarker = email.unread ? pc.cyan(\"●\") : \" \"\n const from = truncate(email.from.name || email.from.email, 23).padEnd(25)\n const subject = truncate(email.subject, 43).padEnd(45)\n const date = formatDate(email.date)\n\n console.log(`${unreadMarker} ${num}${from} ${subject} ${pc.dim(date)}`)\n })\n\n console.log()\n\n // Pagination info\n const totalPages = Math.ceil(pagination.total / limit)\n const currentPage = page\n\n if (totalPages > 1) {\n console.log(\n pc.dim(` Page ${currentPage} of ${totalPages} (${emails.length} of ${pagination.total})`)\n )\n\n if (currentPage < totalPages) {\n console.log(pc.dim(` Next page: btcemail list --page ${currentPage + 1}`))\n }\n console.log()\n }\n\n // Hint for reading\n console.log(pc.dim(\" Read email: btcemail read <#> or btcemail read <id>\"))\n console.log()\n}\n\nfunction capitalize(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1)\n}\n\nfunction truncate(str: string, maxLength: number): string {\n if (str.length <= maxLength) return str\n return `${str.slice(0, maxLength - 1)}…`\n}\n\nfunction formatDate(dateString: string): string {\n const date = new Date(dateString)\n const now = new Date()\n const diffMs = now.getTime() - date.getTime()\n const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24))\n\n if (diffDays === 0) {\n return date.toLocaleTimeString(\"en-US\", {\n hour: \"numeric\",\n minute: \"2-digit\",\n })\n }\n\n if (diffDays < 7) {\n return date.toLocaleDateString(\"en-US\", { weekday: \"short\" })\n }\n\n return date.toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n })\n}\n","/**\n * Email Cache Utility\n *\n * Caches email lists for number-based selection (btcemail read 3).\n * Cache is per-folder and cleared on each new list command.\n */\n\nimport { config } from \"../config.js\"\n\nexport type CachedEmail = {\n id: string\n subject: string\n from: string\n}\n\nexport type EmailCache = {\n folder: string\n emails: CachedEmail[]\n timestamp: number\n}\n\nconst CACHE_KEY = \"emailCache\"\nconst CACHE_TTL_MS = 30 * 60 * 1000 // 30 minutes\n\n/**\n * Store email list for number-based access\n */\nexport function cacheEmailList(folder: string, emails: CachedEmail[]): void {\n config.set(CACHE_KEY, {\n folder,\n emails,\n timestamp: Date.now(),\n })\n}\n\n/**\n * Get cached email list if valid\n */\nexport function getCachedEmailList(folder?: string): EmailCache | null {\n const cache = config.get(CACHE_KEY) as EmailCache | undefined\n if (!cache) return null\n\n // Check if expired\n if (Date.now() - cache.timestamp > CACHE_TTL_MS) {\n config.delete(CACHE_KEY)\n return null\n }\n\n // Check folder match if specified\n if (folder && cache.folder !== folder) {\n return null\n }\n\n return cache\n}\n\n/**\n * Get email ID by index (1-based)\n * Returns null if not found or cache is invalid\n */\nexport function getEmailIdByIndex(index: number): string | null {\n const cache = getCachedEmailList()\n if (!cache) return null\n\n // Convert to 0-based index\n const idx = index - 1\n if (idx < 0 || idx >= cache.emails.length) {\n return null\n }\n\n return cache.emails[idx].id\n}\n\n/**\n * Check if ID is a number (for index-based access)\n */\nexport function isNumericId(id: string): boolean {\n return /^\\d+$/.test(id)\n}\n\n/**\n * Clear the email cache\n */\nexport function clearEmailCache(): void {\n config.delete(CACHE_KEY)\n}\n","/**\n * Login Command\n *\n * Implements polling-based browser authentication:\n * 1. Generate session_id\n * 2. Open browser to auth page\n * 3. Poll for tokens\n * 4. Store tokens in config\n */\n\nimport { randomUUID } from \"node:crypto\"\nimport open from \"open\"\nimport ora from \"ora\"\nimport pc from \"picocolors\"\nimport { getApiBaseUrl, setAuth } from \"../config.js\"\n\nconst POLL_INTERVAL_MS = 2000\nconst POLL_TIMEOUT_MS = 300000 // 5 minutes\n\ntype CLISessionResponse =\n | { status: \"pending\" }\n | {\n status: \"complete\"\n data: {\n token: string\n expiresAt: string\n userId: string\n email: string\n }\n }\n\nexport async function loginCommand(): Promise<void> {\n const sessionId = randomUUID()\n const baseUrl = getApiBaseUrl().replace(\"/api/v1\", \"\")\n const authUrl = `${baseUrl}/auth/cli?session_id=${sessionId}`\n const pollUrl = `${baseUrl}/api/auth/cli-session?session_id=${sessionId}`\n\n console.log()\n console.log(pc.bold(\"btc.email CLI Login\"))\n console.log()\n\n // Create pending session first\n try {\n const createResponse = await fetch(`${baseUrl}/api/auth/cli-session`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ session_id: sessionId }),\n })\n\n if (!createResponse.ok) {\n console.error(pc.red(\"Failed to initialize login session\"))\n process.exit(1)\n }\n } catch (error) {\n console.error(pc.red(\"Failed to connect to btc.email server\"))\n console.error(pc.dim(error instanceof Error ? error.message : \"Unknown error\"))\n process.exit(1)\n }\n\n // Open browser\n console.log(pc.dim(\"Opening browser for authentication...\"))\n console.log()\n console.log(pc.dim(\"If the browser doesn't open, visit:\"))\n console.log(pc.cyan(authUrl))\n console.log()\n\n try {\n await open(authUrl)\n } catch {\n // Browser open failed, user can use the URL\n }\n\n // Poll for tokens\n const spinner = ora(\"Waiting for authentication...\").start()\n const startTime = Date.now()\n\n while (Date.now() - startTime < POLL_TIMEOUT_MS) {\n try {\n const response = await fetch(pollUrl)\n\n if (response.status === 202) {\n // Still pending, continue polling\n await sleep(POLL_INTERVAL_MS)\n continue\n }\n\n if (response.status === 410) {\n spinner.fail(\"Session expired. Please try again.\")\n process.exit(1)\n }\n\n if (response.ok) {\n const data: CLISessionResponse = await response.json()\n\n if (data.status === \"complete\") {\n // Store tokens\n setAuth({\n token: data.data.token,\n expiresAt: data.data.expiresAt,\n userId: data.data.userId,\n email: data.data.email,\n })\n\n spinner.succeed(pc.green(\"Successfully logged in!\"))\n console.log()\n console.log(` ${pc.dim(\"Email:\")} ${data.data.email}`)\n console.log()\n console.log(pc.dim(\"You can now use btcemail commands.\"))\n console.log(pc.dim(\"Run `btcemail --help` to see available commands.\"))\n return\n }\n }\n\n await sleep(POLL_INTERVAL_MS)\n } catch (_error) {\n // Network error, continue polling\n await sleep(POLL_INTERVAL_MS)\n }\n }\n\n spinner.fail(\"Authentication timed out. Please try again.\")\n process.exit(1)\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n","/**\n * Logout Command\n *\n * Clears stored authentication tokens.\n */\n\nimport pc from \"picocolors\"\nimport { clearAuth, isAuthenticated } from \"../config.js\"\n\nexport async function logoutCommand(): Promise<void> {\n if (!isAuthenticated()) {\n console.log(pc.yellow(\"You are not logged in.\"))\n return\n }\n\n clearAuth()\n console.log(pc.green(\"Successfully logged out.\"))\n}\n","/**\n * Network command for btc.email CLI\n *\n * Switch between testnet and mainnet Lightning networks.\n */\n\nimport pc from \"picocolors\"\nimport { getNetwork, setNetwork } from \"../api.js\"\nimport { getToken } from \"../config.js\"\n\nexport interface NetworkShowOptions {\n json?: boolean\n}\n\nexport interface NetworkSwitchOptions {\n json?: boolean\n}\n\n/**\n * Show current network mode\n */\nexport async function networkShowCommand(options: NetworkShowOptions = {}) {\n const token = getToken()\n if (!token) {\n console.error(pc.red(\"Not logged in. Run 'btcemail login' first.\"))\n process.exit(1)\n }\n\n const result = await getNetwork()\n\n if (!result.ok) {\n console.error(pc.red(`Error: ${result.error.message}`))\n process.exit(1)\n }\n\n const { network_mode, networks } = result.data\n\n if (options.json) {\n console.log(JSON.stringify({ network_mode, networks }, null, 2))\n return\n }\n\n console.log()\n console.log(pc.bold(\"Network Mode\"))\n console.log()\n\n const isTestnet = network_mode === \"testnet\"\n const currentLabel = isTestnet\n ? pc.blue(\"testnet\") + pc.dim(\" (fake Bitcoin)\")\n : pc.red(\"mainnet\") + pc.dim(\" (real Bitcoin)\")\n\n console.log(` Current: ${currentLabel}`)\n console.log()\n console.log(pc.dim(\" Available networks:\"))\n console.log(\n ` testnet: ${networks.testnet.available ? pc.green(\"available\") : pc.red(\"unavailable\")}`\n )\n console.log(\n ` mainnet: ${networks.mainnet.available ? pc.green(\"available\") : pc.red(\"unavailable\")}`\n )\n console.log()\n\n if (!isTestnet) {\n console.log(pc.yellow(\" Warning: You are on mainnet. Payments use real Bitcoin!\"))\n console.log()\n }\n}\n\n/**\n * Switch network mode\n */\nexport async function networkSwitchCommand(network: string, options: NetworkSwitchOptions = {}) {\n const token = getToken()\n if (!token) {\n console.error(pc.red(\"Not logged in. Run 'btcemail login' first.\"))\n process.exit(1)\n }\n\n if (network !== \"testnet\" && network !== \"mainnet\") {\n console.error(pc.red(\"Invalid network. Use 'testnet' or 'mainnet'.\"))\n process.exit(1)\n }\n\n // Show warning for mainnet\n if (network === \"mainnet\") {\n console.log()\n console.log(pc.yellow(\"Warning: You are switching to mainnet.\"))\n console.log(pc.yellow(\"All payments will use real Bitcoin!\"))\n console.log()\n }\n\n const result = await setNetwork(network)\n\n if (!result.ok) {\n console.error(pc.red(`Error: ${result.error.message}`))\n process.exit(1)\n }\n\n if (options.json) {\n console.log(JSON.stringify({ success: true, network_mode: result.data.network_mode }, null, 2))\n return\n }\n\n const label = network === \"testnet\" ? pc.blue(\"testnet\") : pc.red(\"mainnet\")\n\n console.log(pc.green(`Switched to ${label}`))\n}\n","/**\n * Read Command\n *\n * Display a single email by ID or number (from cached list).\n * Supports: btcemail read 3 (number) or btcemail read abc123 (ID)\n */\n\nimport ora from \"ora\"\nimport pc from \"picocolors\"\nimport { getEmail } from \"../api.js\"\nimport { isAuthenticated } from \"../config.js\"\nimport { getCachedEmailList, getEmailIdByIndex, isNumericId } from \"../utils/cache.js\"\n\nexport type ReadOptions = {\n json?: boolean\n}\n\nexport async function readCommand(idOrNumber: string, options: ReadOptions): Promise<void> {\n if (!isAuthenticated()) {\n console.log(pc.yellow(\"Not logged in.\"))\n console.log(pc.dim(\"Run `btcemail login` to authenticate.\"))\n process.exit(1)\n }\n\n let emailId = idOrNumber\n\n // Check if this is a number reference\n if (isNumericId(idOrNumber)) {\n const index = parseInt(idOrNumber, 10)\n const cachedId = getEmailIdByIndex(index)\n\n if (cachedId) {\n emailId = cachedId\n } else {\n // Check if cache exists but index is out of range\n const cache = getCachedEmailList()\n if (cache) {\n console.error(pc.red(`Email #${index} not found in list.`))\n console.log(\n pc.dim(`List has ${cache.emails.length} emails. Run 'btcemail list' to refresh.`)\n )\n } else {\n console.error(pc.red(`No email list cached.`))\n console.log(pc.dim(`Run 'btcemail list' first, then use 'btcemail read <#>'.`))\n }\n process.exit(1)\n }\n }\n\n const spinner = ora(\"Loading email...\").start()\n\n const result = await getEmail(emailId)\n\n if (!result.ok) {\n if (result.error.code === \"NOT_FOUND\") {\n spinner.fail(`Email not found: ${emailId}`)\n } else {\n spinner.fail(`Error: ${result.error.message}`)\n }\n process.exit(1)\n }\n\n spinner.stop()\n\n const email = result.data\n\n // JSON output mode\n if (options.json) {\n console.log(JSON.stringify(email, null, 2))\n return\n }\n\n // Formatted output\n console.log()\n console.log(pc.bold(email.subject || \"(No subject)\"))\n console.log()\n console.log(`${pc.dim(\"From:\")} ${formatAddress(email.from)}`)\n console.log(`${pc.dim(\"To:\")} ${email.to.map(formatAddress).join(\", \")}`)\n console.log(`${pc.dim(\"Date:\")} ${formatFullDate(email.date)}`)\n console.log(`${pc.dim(\"ID:\")} ${email.id}`)\n\n if (email.labels.length > 0) {\n console.log(`${pc.dim(\"Labels:\")} ${email.labels.join(\", \")}`)\n }\n\n console.log()\n console.log(pc.dim(\"-\".repeat(60)))\n console.log()\n\n // Show full body if available, otherwise fall back to snippet\n const content = email.bodyText || email.body || email.snippet\n if (content) {\n // Strip HTML tags for plain text display if showing HTML body\n const displayContent = email.bodyText || stripHtml(email.body || email.snippet)\n console.log(displayContent)\n } else {\n console.log(pc.dim(\"(No content)\"))\n }\n console.log()\n}\n\nfunction stripHtml(html: string): string {\n // Basic HTML stripping for terminal display\n return html\n .replace(/<br\\s*\\/?>/gi, \"\\n\")\n .replace(/<\\/p>/gi, \"\\n\\n\")\n .replace(/<\\/div>/gi, \"\\n\")\n .replace(/<[^>]*>/g, \"\")\n .replace(/ /g, \" \")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/&/g, \"&\")\n .replace(/"/g, '\"')\n .trim()\n}\n\nfunction formatAddress(addr: { email: string; name?: string }): string {\n if (addr.name) {\n return `${addr.name} <${addr.email}>`\n }\n return addr.email\n}\n\nfunction formatFullDate(dateString: string): string {\n const date = new Date(dateString)\n return date.toLocaleString(\"en-US\", {\n weekday: \"short\",\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n })\n}\n","/**\n * Search Command\n *\n * Searches emails by subject, body, or sender.\n */\n\nimport ora from \"ora\"\nimport pc from \"picocolors\"\nimport { getEmails } from \"../api.js\"\nimport { isAuthenticated } from \"../config.js\"\nimport { type CachedEmail, cacheEmailList } from \"../utils/cache.js\"\n\nexport type SearchOptions = {\n limit?: number\n json?: boolean\n}\n\nexport async function searchCommand(query: string, options: SearchOptions): Promise<void> {\n if (!isAuthenticated()) {\n console.log(pc.yellow(\"Not logged in.\"))\n console.log(pc.dim(\"Run `btcemail login` to authenticate.\"))\n process.exit(1)\n }\n\n if (!query || query.trim().length === 0) {\n console.error(pc.red(\"Error: Search query is required\"))\n process.exit(1)\n }\n\n const spinner = ora(`Searching for \"${query}\"...`).start()\n\n const result = await getEmails({\n search: query.trim(),\n limit: options.limit || 20,\n })\n\n if (!result.ok) {\n spinner.fail(`Error: ${result.error.message}`)\n process.exit(1)\n }\n\n const { data: emails, pagination } = result.data\n\n spinner.stop()\n\n // Cache results for number-based access\n const cachedEmails: CachedEmail[] = emails.map((e) => ({\n id: e.id,\n subject: e.subject,\n from: e.from.name || e.from.email,\n }))\n cacheEmailList(\"search\", cachedEmails)\n\n // JSON output mode\n if (options.json) {\n console.log(JSON.stringify({ query, emails, pagination }, null, 2))\n return\n }\n\n // Table output\n console.log()\n console.log(pc.bold(`Search: \"${query}\" (${pagination.total} found)`))\n console.log()\n\n if (emails.length === 0) {\n console.log(pc.dim(\" No emails found matching your search.\"))\n console.log()\n return\n }\n\n // Header with # column\n console.log(\n ` ${pc.dim(\"#\".padEnd(4))} ${pc.dim(\"From\".padEnd(25))} ${pc.dim(\"Subject\".padEnd(45))} ${pc.dim(\"Date\")}`\n )\n console.log(pc.dim(` ${\"-\".repeat(85)}`))\n\n // Rows with numbering\n emails.forEach((email, index) => {\n const num = pc.cyan(String(index + 1).padEnd(4))\n const unreadMarker = email.unread ? pc.cyan(\"●\") : \" \"\n const from = truncate(email.from.name || email.from.email, 23).padEnd(25)\n const subject = truncate(email.subject, 43).padEnd(45)\n const date = formatDate(email.date)\n\n console.log(`${unreadMarker} ${num}${from} ${subject} ${pc.dim(date)}`)\n })\n\n console.log()\n\n if (pagination.hasMore) {\n console.log(\n pc.dim(` Showing ${emails.length} of ${pagination.total}. Use --limit to see more.`)\n )\n console.log()\n }\n\n console.log(pc.dim(\" Read email: btcemail read <#> or btcemail read <id>\"))\n console.log()\n}\n\nfunction truncate(str: string, maxLength: number): string {\n if (str.length <= maxLength) return str\n return `${str.slice(0, maxLength - 1)}…`\n}\n\nfunction formatDate(dateString: string): string {\n const date = new Date(dateString)\n const now = new Date()\n const diffMs = now.getTime() - date.getTime()\n const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24))\n\n if (diffDays === 0) {\n return date.toLocaleTimeString(\"en-US\", {\n hour: \"numeric\",\n minute: \"2-digit\",\n })\n }\n\n if (diffDays < 7) {\n return date.toLocaleDateString(\"en-US\", { weekday: \"short\" })\n }\n\n return date.toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n })\n}\n","/**\n * Send Command\n *\n * Compose and send an email with L402 payment flow.\n * Supports --wait to poll for payment confirmation.\n */\n\nimport ora from \"ora\"\nimport pc from \"picocolors\"\nimport qrcode from \"qrcode-terminal\"\nimport { checkPaymentStatus, getL402Invoice, getWhoami, sendEmail } from \"../api.js\"\nimport { getAuth, isAuthenticated } from \"../config.js\"\nimport { pollForPayment } from \"../utils/payment-polling.js\"\n\nexport type SendOptions = {\n to?: string\n subject?: string\n body?: string\n fromEmail?: string\n paymentHash?: string\n wait?: boolean\n}\n\nexport async function sendCommand(options: SendOptions): Promise<void> {\n if (!isAuthenticated()) {\n console.log(pc.yellow(\"Not logged in.\"))\n console.log(pc.dim(\"Run `btcemail login` to authenticate.\"))\n process.exit(1)\n }\n\n // Get user's email address\n let fromEmail = options.fromEmail\n if (!fromEmail) {\n const spinner = ora(\"Fetching account info...\").start()\n const whoamiResult = await getWhoami()\n spinner.stop()\n\n if (whoamiResult.ok && whoamiResult.data.username) {\n fromEmail = `${whoamiResult.data.username}@btc.email`\n } else {\n const auth = getAuth()\n if (auth?.email?.endsWith(\"@btc.email\")) {\n fromEmail = auth.email\n }\n }\n }\n\n if (!fromEmail || !fromEmail.endsWith(\"@btc.email\")) {\n console.error(pc.red(\"No @btc.email address found.\"))\n console.log(pc.dim(\"Register a username at https://btc.email\"))\n process.exit(1)\n }\n\n // Validate required fields\n if (!options.to) {\n console.error(pc.red(\"Recipient is required. Use --to <email>\"))\n process.exit(1)\n }\n\n if (!options.subject) {\n console.error(pc.red(\"Subject is required. Use --subject <text>\"))\n process.exit(1)\n }\n\n if (!options.body) {\n console.error(pc.red(\"Body is required. Use --body <text>\"))\n process.exit(1)\n }\n\n const toEmails = options.to.split(\",\").map((e) => e.trim())\n\n console.log()\n console.log(pc.bold(\"Sending Email\"))\n console.log()\n console.log(`${pc.dim(\"From:\")} ${fromEmail}`)\n console.log(`${pc.dim(\"To:\")} ${toEmails.join(\", \")}`)\n console.log(`${pc.dim(\"Subject:\")} ${options.subject}`)\n console.log()\n\n // If no payment hash provided, check if payment is required\n if (!options.paymentHash) {\n const spinner = ora(\"Getting invoice...\").start()\n const invoiceResult = await getL402Invoice({\n fromEmail,\n toEmails,\n })\n spinner.stop()\n\n if (invoiceResult.ok && invoiceResult.data.amountSats > 0) {\n // Payment required\n const invoice = invoiceResult.data\n console.log(pc.yellow(`Payment required: ${invoice.amountSats} sats`))\n console.log()\n\n // Display QR code\n console.log(pc.bold(\"Scan to pay:\"))\n console.log()\n qrcode.generate(invoice.invoice, { small: true }, (qr) => {\n const indentedQr = qr\n .split(\"\\n\")\n .map((line) => ` ${line}`)\n .join(\"\\n\")\n console.log(indentedQr)\n })\n console.log()\n\n console.log(pc.dim(\"Lightning Invoice:\"))\n console.log(pc.cyan(invoice.invoice))\n console.log()\n\n // If --wait flag is set, poll for payment\n if (options.wait) {\n const status = await pollForPayment({\n paymentHash: invoice.paymentHash,\n checkFn: async (hash) => {\n const result = await checkPaymentStatus(hash)\n if (result.ok) {\n return { paid: result.data.paid }\n }\n return { paid: false }\n },\n })\n\n if (status.paid) {\n // Payment received, now send the email\n const sendSpinner = ora(\"Sending email...\").start()\n const result = await sendEmail({\n to: toEmails,\n subject: options.subject,\n body: options.body,\n fromEmail,\n paymentHash: invoice.paymentHash,\n })\n\n if (!result.ok) {\n sendSpinner.fail(`Error: ${result.error.message}`)\n process.exit(1)\n }\n\n sendSpinner.succeed(\"Email sent!\")\n console.log()\n console.log(`${pc.dim(\"Email ID:\")} ${result.data.emailId}`)\n if (result.data.messageId) {\n console.log(`${pc.dim(\"Message ID:\")} ${result.data.messageId}`)\n }\n console.log()\n } else {\n console.log(\n pc.dim(\"Payment not confirmed. You can still pay and resend with --payment-hash.\")\n )\n }\n return\n }\n\n console.log(pc.dim(\"Pay this invoice with your Lightning wallet, then run:\"))\n console.log(\n pc.cyan(\n ` btcemail send --to \"${options.to}\" --subject \"${options.subject}\" --body \"${options.body}\" --payment-hash ${invoice.paymentHash}`\n )\n )\n console.log()\n console.log(pc.dim(\"Or use --wait to automatically wait for payment.\"))\n console.log()\n return\n }\n }\n\n // Send email (with payment hash if provided)\n const spinner = ora(\"Sending email...\").start()\n const result = await sendEmail({\n to: toEmails,\n subject: options.subject,\n body: options.body,\n fromEmail,\n paymentHash: options.paymentHash,\n })\n\n if (!result.ok) {\n if (result.error.code === \"PAYMENT_REQUIRED\") {\n spinner.fail(\"Payment required to send this email.\")\n console.log(pc.dim(\"Use the invoice above to pay, then include --payment-hash\"))\n } else {\n spinner.fail(`Error: ${result.error.message}`)\n }\n process.exit(1)\n }\n\n spinner.succeed(\"Email sent!\")\n console.log()\n console.log(`${pc.dim(\"Email ID:\")} ${result.data.emailId}`)\n if (result.data.messageId) {\n console.log(`${pc.dim(\"Message ID:\")} ${result.data.messageId}`)\n }\n console.log()\n}\n\nexport type SendWithPaymentOptions = SendOptions & {\n paymentHash?: string\n}\n\nexport async function sendWithPaymentCommand(options: SendWithPaymentOptions): Promise<void> {\n if (!isAuthenticated()) {\n console.log(pc.yellow(\"Not logged in.\"))\n console.log(pc.dim(\"Run `btcemail login` to authenticate.\"))\n process.exit(1)\n }\n\n // Get user's email address\n let fromEmail = options.fromEmail\n if (!fromEmail) {\n const whoamiResult = await getWhoami()\n if (whoamiResult.ok && whoamiResult.data.username) {\n fromEmail = `${whoamiResult.data.username}@btc.email`\n }\n }\n\n if (!fromEmail || !fromEmail.endsWith(\"@btc.email\")) {\n console.error(pc.red(\"No @btc.email address found.\"))\n process.exit(1)\n }\n\n if (!options.to || !options.subject || !options.body) {\n console.error(pc.red(\"Missing required fields: --to, --subject, --body\"))\n process.exit(1)\n }\n\n const toEmails = options.to.split(\",\").map((e) => e.trim())\n\n const result = await sendEmail({\n to: toEmails,\n subject: options.subject,\n body: options.body,\n fromEmail,\n paymentHash: options.paymentHash,\n })\n\n if (!result.ok) {\n console.error(pc.red(`Error: ${result.error.message}`))\n process.exit(1)\n }\n\n console.log()\n console.log(pc.green(\"Email sent successfully!\"))\n console.log()\n console.log(`${pc.dim(\"Email ID:\")} ${result.data.emailId}`)\n console.log()\n}\n","/**\n * Settings command for btc.email CLI\n *\n * Manage email pricing, toggles, and auto-reply settings.\n */\n\nimport pc from \"picocolors\"\nimport { getSettings, updateSettings } from \"../api.js\"\nimport { getToken } from \"../config.js\"\n\nexport interface SettingsOptions {\n username?: string\n json?: boolean\n}\n\nexport interface SettingsPricingOptions {\n username?: string\n json?: boolean\n}\n\nexport interface SettingsToggleOptions {\n username?: string\n}\n\nexport interface SettingsAutoReplyOptions {\n username?: string\n clear?: boolean\n}\n\n/**\n * Show current settings\n */\nexport async function settingsShowCommand(options: SettingsOptions = {}) {\n const token = getToken()\n if (!token) {\n console.error(pc.red(\"Not logged in. Run 'btcemail login' first.\"))\n process.exit(1)\n }\n\n const result = await getSettings(options.username)\n\n if (!result.ok) {\n console.error(pc.red(`Error: ${result.error.message}`))\n process.exit(1)\n }\n\n const { username, usernames, settings } = result.data\n\n if (options.json) {\n console.log(JSON.stringify({ username, usernames, settings }, null, 2))\n return\n }\n\n console.log()\n console.log(pc.bold(\"Settings for \") + pc.cyan(`${username}@btc.email`))\n if (usernames.length > 1) {\n console.log(pc.dim(`(You have ${usernames.length} addresses: ${usernames.join(\", \")})`))\n }\n console.log()\n console.log(pc.dim(\"Pricing:\"))\n console.log(` Email price: ${pc.yellow(settings.default_price_sats.toLocaleString())} sats`)\n console.log()\n console.log(pc.dim(\"Toggles:\"))\n console.log(\n ` Require payment: ${settings.require_payment_from_unknown ? pc.green(\"on\") : pc.red(\"off\")}`\n )\n console.log(\n ` Auto-whitelist: ${settings.auto_whitelist_on_payment ? pc.green(\"on\") : pc.red(\"off\")}`\n )\n console.log()\n console.log(pc.dim(\"Auto-reply:\"))\n if (settings.custom_auto_reply_body) {\n console.log(` ${pc.italic(settings.custom_auto_reply_body)}`)\n } else {\n console.log(` ${pc.dim(\"(default message)\")}`)\n }\n console.log()\n}\n\n/**\n * Set email pricing\n */\nexport async function settingsPricingCommand(sats: string, options: SettingsPricingOptions = {}) {\n const token = getToken()\n if (!token) {\n console.error(pc.red(\"Not logged in. Run 'btcemail login' first.\"))\n process.exit(1)\n }\n\n const price = parseInt(sats, 10)\n if (Number.isNaN(price) || price < 0) {\n console.error(pc.red(\"Invalid price. Must be a non-negative number.\"))\n process.exit(1)\n }\n\n const result = await updateSettings({ default_price_sats: price }, options.username)\n\n if (!result.ok) {\n console.error(pc.red(`Error: ${result.error.message}`))\n process.exit(1)\n }\n\n if (options.json) {\n console.log(JSON.stringify({ success: true, price }, null, 2))\n return\n }\n\n console.log(pc.green(`Email price set to ${pc.yellow(price.toLocaleString())} sats`))\n}\n\n/**\n * Toggle require-payment setting\n */\nexport async function settingsRequirePaymentCommand(\n value: string,\n options: SettingsToggleOptions = {}\n) {\n const token = getToken()\n if (!token) {\n console.error(pc.red(\"Not logged in. Run 'btcemail login' first.\"))\n process.exit(1)\n }\n\n const enabled = value.toLowerCase() === \"on\" || value === \"true\" || value === \"1\"\n const disabled = value.toLowerCase() === \"off\" || value === \"false\" || value === \"0\"\n\n if (!enabled && !disabled) {\n console.error(pc.red(\"Invalid value. Use 'on' or 'off'.\"))\n process.exit(1)\n }\n\n const result = await updateSettings({ require_payment_from_unknown: enabled }, options.username)\n\n if (!result.ok) {\n console.error(pc.red(`Error: ${result.error.message}`))\n process.exit(1)\n }\n\n console.log(pc.green(`Require payment: ${enabled ? pc.green(\"on\") : pc.red(\"off\")}`))\n}\n\n/**\n * Toggle auto-whitelist setting\n */\nexport async function settingsAutoWhitelistCommand(\n value: string,\n options: SettingsToggleOptions = {}\n) {\n const token = getToken()\n if (!token) {\n console.error(pc.red(\"Not logged in. Run 'btcemail login' first.\"))\n process.exit(1)\n }\n\n const enabled = value.toLowerCase() === \"on\" || value === \"true\" || value === \"1\"\n const disabled = value.toLowerCase() === \"off\" || value === \"false\" || value === \"0\"\n\n if (!enabled && !disabled) {\n console.error(pc.red(\"Invalid value. Use 'on' or 'off'.\"))\n process.exit(1)\n }\n\n const result = await updateSettings({ auto_whitelist_on_payment: enabled }, options.username)\n\n if (!result.ok) {\n console.error(pc.red(`Error: ${result.error.message}`))\n process.exit(1)\n }\n\n console.log(pc.green(`Auto-whitelist: ${enabled ? pc.green(\"on\") : pc.red(\"off\")}`))\n}\n\n/**\n * Set auto-reply message\n */\nexport async function settingsAutoReplyCommand(\n message: string | undefined,\n options: SettingsAutoReplyOptions = {}\n) {\n const token = getToken()\n if (!token) {\n console.error(pc.red(\"Not logged in. Run 'btcemail login' first.\"))\n process.exit(1)\n }\n\n const newMessage = options.clear ? null : message || null\n\n const result = await updateSettings({ custom_auto_reply_body: newMessage }, options.username)\n\n if (!result.ok) {\n console.error(pc.red(`Error: ${result.error.message}`))\n process.exit(1)\n }\n\n if (options.clear) {\n console.log(pc.green(\"Auto-reply reset to default message\"))\n } else if (newMessage) {\n console.log(pc.green(\"Auto-reply message updated\"))\n } else {\n console.log(pc.yellow(\"No message provided. Use --clear to reset to default.\"))\n }\n}\n","/**\n * Stats command for btc.email CLI\n *\n * Show dashboard overview statistics.\n */\n\nimport pc from \"picocolors\"\nimport { getStats } from \"../api.js\"\nimport { getToken } from \"../config.js\"\n\nexport interface StatsOptions {\n json?: boolean\n}\n\n/**\n * Show dashboard statistics\n */\nexport async function statsCommand(options: StatsOptions = {}) {\n const token = getToken()\n if (!token) {\n console.error(pc.red(\"Not logged in. Run 'btcemail login' first.\"))\n process.exit(1)\n }\n\n const result = await getStats()\n\n if (!result.ok) {\n console.error(pc.red(`Error: ${result.error.message}`))\n process.exit(1)\n }\n\n const { totalReceived, totalSent, pendingCount, addressCount, usernames } = result.data\n\n if (options.json) {\n console.log(JSON.stringify(result.data, null, 2))\n return\n }\n\n console.log()\n console.log(pc.bold(\"Dashboard Statistics\"))\n console.log()\n console.log(` Total Received: ${pc.green(`+${totalReceived.toLocaleString()}`)} sats`)\n console.log(` Total Sent: ${pc.yellow(`-${totalSent.toLocaleString()}`)} sats`)\n console.log(` Pending Emails: ${pendingCount > 0 ? pc.yellow(pendingCount) : pc.dim(\"0\")}`)\n console.log(` Active Addresses: ${addressCount}`)\n console.log()\n\n if (usernames.length > 0) {\n console.log(pc.dim(\" Your addresses:\"))\n for (const username of usernames) {\n console.log(` ${pc.cyan(username)}@btc.email`)\n }\n console.log()\n }\n\n if (pendingCount > 0) {\n console.log(pc.dim(\" View pending emails: btcemail inbound pending\"))\n console.log()\n }\n}\n","/**\n * Whitelist command for btc.email CLI\n *\n * Manage senders who can email you for free.\n */\n\nimport pc from \"picocolors\"\nimport { addToWhitelist, getWhitelist, removeFromWhitelist } from \"../api.js\"\nimport { getToken } from \"../config.js\"\n\nexport interface WhitelistListOptions {\n username?: string\n json?: boolean\n}\n\nexport interface WhitelistAddOptions {\n username?: string\n note?: string\n json?: boolean\n}\n\nexport interface WhitelistRemoveOptions {\n json?: boolean\n}\n\n/**\n * List whitelist entries\n */\nexport async function whitelistListCommand(options: WhitelistListOptions = {}) {\n const token = getToken()\n if (!token) {\n console.error(pc.red(\"Not logged in. Run 'btcemail login' first.\"))\n process.exit(1)\n }\n\n const result = await getWhitelist(options.username)\n\n if (!result.ok) {\n console.error(pc.red(`Error: ${result.error.message}`))\n process.exit(1)\n }\n\n const { username, entries } = result.data\n\n if (options.json) {\n console.log(JSON.stringify({ username, entries }, null, 2))\n return\n }\n\n console.log()\n console.log(pc.bold(\"Whitelist for \") + pc.cyan(`${username}@btc.email`))\n console.log()\n\n if (entries.length === 0) {\n console.log(pc.dim(\" No entries in whitelist.\"))\n console.log()\n console.log(pc.dim(\" Add entries with: btcemail whitelist add <email>\"))\n console.log(pc.dim(\" Or for domains: btcemail whitelist add @domain.com\"))\n console.log()\n return\n }\n\n console.log(pc.dim(` ${entries.length} ${entries.length === 1 ? \"entry\" : \"entries\"}:`))\n console.log()\n\n for (const entry of entries) {\n const value = entry.sender_email || `@${entry.sender_domain}`\n const via = entry.added_via !== \"manual\" ? pc.dim(` (via ${entry.added_via})`) : \"\"\n const note = entry.note ? pc.dim(` - ${entry.note}`) : \"\"\n console.log(` ${pc.green(value)}${via}${note}`)\n console.log(pc.dim(` ID: ${entry.id}`))\n }\n console.log()\n}\n\n/**\n * Add entry to whitelist\n */\nexport async function whitelistAddCommand(entry: string, options: WhitelistAddOptions = {}) {\n const token = getToken()\n if (!token) {\n console.error(pc.red(\"Not logged in. Run 'btcemail login' first.\"))\n process.exit(1)\n }\n\n // Check if it's a domain (starts with @)\n const isDomain = entry.startsWith(\"@\")\n const payload = isDomain\n ? { domain: entry.slice(1), note: options.note }\n : { email: entry, note: options.note }\n\n const result = await addToWhitelist(payload, options.username)\n\n if (!result.ok) {\n console.error(pc.red(`Error: ${result.error.message}`))\n process.exit(1)\n }\n\n if (options.json) {\n console.log(JSON.stringify({ success: true, entry: result.data.entry }, null, 2))\n return\n }\n\n console.log(pc.green(`Added to whitelist: ${pc.cyan(entry)}`))\n}\n\n/**\n * Remove entry from whitelist\n */\nexport async function whitelistRemoveCommand(id: string, options: WhitelistRemoveOptions = {}) {\n const token = getToken()\n if (!token) {\n console.error(pc.red(\"Not logged in. Run 'btcemail login' first.\"))\n process.exit(1)\n }\n\n const result = await removeFromWhitelist(id)\n\n if (!result.ok) {\n console.error(pc.red(`Error: ${result.error.message}`))\n process.exit(1)\n }\n\n if (options.json) {\n console.log(JSON.stringify({ success: true }, null, 2))\n return\n }\n\n console.log(pc.green(\"Removed from whitelist\"))\n}\n","/**\n * Whoami Command\n *\n * Shows current authenticated user info.\n */\n\nimport ora from \"ora\"\nimport pc from \"picocolors\"\nimport { getWhoami } from \"../api.js\"\nimport { getAuth, getTokenExpiryInfo, isAuthenticated, isTokenExpiringSoon } from \"../config.js\"\n\nexport async function whoamiCommand(): Promise<void> {\n if (!isAuthenticated()) {\n console.log(pc.yellow(\"Not logged in.\"))\n console.log(pc.dim(\"Run `btcemail login` to authenticate.\"))\n process.exit(1)\n }\n\n const auth = getAuth()\n if (!auth) {\n console.log(pc.yellow(\"Not logged in.\"))\n process.exit(1)\n }\n\n const spinner = ora(\"Fetching account info...\").start()\n\n // Try to get fresh info from API\n const result = await getWhoami()\n\n spinner.stop()\n\n if (result.ok) {\n console.log()\n console.log(pc.bold(\"Current User\"))\n console.log()\n console.log(` ${pc.dim(\"Email:\")} ${result.data.email}`)\n if (result.data.username) {\n console.log(` ${pc.dim(\"Username:\")} ${result.data.username}@btc.email`)\n }\n console.log(` ${pc.dim(\"User ID:\")} ${result.data.id}`)\n\n // Show token expiry info\n const expiryInfo = getTokenExpiryInfo()\n if (expiryInfo.expiresIn) {\n const expiryColor = isTokenExpiringSoon() ? pc.yellow : pc.dim\n console.log(` ${pc.dim(\"Session:\")} ${expiryColor(`expires in ${expiryInfo.expiresIn}`)}`)\n }\n console.log()\n\n if (isTokenExpiringSoon()) {\n console.log(pc.yellow(\"Session expiring soon. Run `btcemail login` to refresh.\"))\n console.log()\n }\n } else {\n // Fall back to cached info\n console.log()\n console.log(pc.bold(\"Current User\") + pc.dim(\" (cached)\"))\n console.log()\n console.log(` ${pc.dim(\"Email:\")} ${auth.email}`)\n console.log(` ${pc.dim(\"User ID:\")} ${auth.userId}`)\n console.log()\n\n if (result.error.code === \"UNAUTHENTICATED\" || result.error.code === \"UNAUTHORIZED\") {\n console.log(pc.yellow(\"Session expired. Run `btcemail login` to re-authenticate.\"))\n }\n }\n}\n"],"mappings":"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","names":["pc","settings","network","pc","pc","pc","result","ora","pc","pc","ora","formatDate","ora","pc","pc","ora","truncate","formatDate","ora","pc","pc","ora","sleep","pc","pc","pc","pc","network","ora","pc","pc","ora","formatAddress","formatFullDate","ora","pc","pc","ora","truncate","formatDate","ora","pc","qrcode","pc","spinner","ora","qrcode","result","pc","pc","settings","pc","pc","pc","pc","ora","pc","pc","ora","pc"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/commands/blocklist.ts","../src/config.ts","../src/api.ts","../src/commands/credits.ts","../src/utils/payment-polling.ts","../src/commands/inbound.ts","../src/commands/list.ts","../src/utils/cache.ts","../src/commands/login.ts","../src/commands/logout.ts","../src/commands/network.ts","../src/commands/read.ts","../src/commands/search.ts","../src/commands/send.ts","../src/commands/settings.ts","../src/commands/stats.ts","../src/commands/whitelist.ts","../src/commands/whoami.ts"],"sourcesContent":["/**\n * btc.email CLI\n *\n * Spam-free email powered by Bitcoin Lightning.\n *\n * Pattern from Claude Code:\n * - No args → Show help (TUI coming later)\n * - btcemail <command> → Execute and exit\n */\n\nimport { Command } from \"commander\"\nimport pc from \"picocolors\"\nimport {\n blocklistAddCommand,\n blocklistListCommand,\n blocklistRemoveCommand,\n creditsBalanceCommand,\n creditsHistoryCommand,\n creditsPurchaseCommand,\n inboundAcceptCommand,\n inboundDeliveredCommand,\n inboundPayCommand,\n inboundPendingCommand,\n inboundViewCommand,\n listCommand,\n loginCommand,\n logoutCommand,\n networkShowCommand,\n networkSwitchCommand,\n readCommand,\n searchCommand,\n sendCommand,\n settingsAutoReplyCommand,\n settingsAutoWhitelistCommand,\n settingsPricingCommand,\n settingsRequirePaymentCommand,\n settingsShowCommand,\n statsCommand,\n whitelistAddCommand,\n whitelistListCommand,\n whitelistRemoveCommand,\n whoamiCommand,\n} from \"./commands/index.js\"\n\nconst program = new Command()\n\nprogram\n .name(\"btcemail\")\n .description(\"btc.email CLI - Spam-free email powered by Bitcoin Lightning\")\n .version(\"0.4.0\")\n\n// Authentication commands\nprogram\n .command(\"login\")\n .description(\"Authenticate with btc.email (opens browser)\")\n .action(loginCommand)\n\nprogram.command(\"logout\").description(\"Clear stored credentials\").action(logoutCommand)\n\nprogram.command(\"whoami\").description(\"Show current authenticated user\").action(whoamiCommand)\n\n// Email commands\nprogram\n .command(\"list\")\n .alias(\"ls\")\n .description(\"List emails (numbered for quick access)\")\n .option(\"-f, --folder <folder>\", \"Folder to list (inbox, sent, drafts)\", \"inbox\")\n .option(\"-l, --limit <number>\", \"Number of emails to show\", \"20\")\n .option(\"-p, --page <number>\", \"Page number\", \"1\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (options) => {\n await listCommand({\n folder: options.folder,\n limit: parseInt(options.limit, 10),\n page: parseInt(options.page, 10),\n json: options.json,\n })\n })\n\nprogram\n .command(\"read <id>\")\n .alias(\"r\")\n .description(\"Read an email by # (from list) or ID\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (id, options) => {\n await readCommand(id, { json: options.json })\n })\n\nprogram\n .command(\"search <query>\")\n .alias(\"s\")\n .description(\"Search emails by subject, body, or sender\")\n .option(\"-l, --limit <number>\", \"Number of results to show\", \"20\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (query, options) => {\n await searchCommand(query, {\n limit: parseInt(options.limit, 10),\n json: options.json,\n })\n })\n\nprogram\n .command(\"send\")\n .description(\"Send an email (with Lightning payment)\")\n .option(\"-t, --to <emails>\", \"Recipient email(s), comma-separated\")\n .option(\"-s, --subject <subject>\", \"Email subject\")\n .option(\"-b, --body <body>\", \"Email body\")\n .option(\"-f, --from <email>\", \"From email (@btc.email address)\")\n .option(\"--payment-hash <hash>\", \"Payment preimage for L402\")\n .option(\"-w, --wait\", \"Wait for payment confirmation\")\n .action(async (options) => {\n await sendCommand({\n to: options.to,\n subject: options.subject,\n body: options.body,\n fromEmail: options.from,\n paymentHash: options.paymentHash,\n wait: options.wait,\n })\n })\n\n// Top-level alias: bin = inbound pending\nprogram\n .command(\"bin\")\n .description(\"List pending inbound emails (alias for 'inbound pending')\")\n .option(\"-l, --limit <number>\", \"Number of emails to show\", \"20\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (options) => {\n await inboundPendingCommand({\n limit: parseInt(options.limit, 10),\n json: options.json,\n })\n })\n\n// Inbound commands (pending and delivered emails)\nconst inbound = program\n .command(\"inbound\")\n .alias(\"in\")\n .description(\"Manage inbound emails (pending and delivered)\")\n\ninbound\n .command(\"pending\")\n .alias(\"p\")\n .description(\"List pending emails awaiting payment\")\n .option(\"-l, --limit <number>\", \"Number of emails to show\", \"20\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (options) => {\n await inboundPendingCommand({\n limit: parseInt(options.limit, 10),\n json: options.json,\n })\n })\n\ninbound\n .command(\"delivered\")\n .alias(\"d\")\n .description(\"List delivered emails (paid by senders)\")\n .option(\"-l, --limit <number>\", \"Number of emails to show\", \"20\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (options) => {\n await inboundDeliveredCommand({\n limit: parseInt(options.limit, 10),\n json: options.json,\n })\n })\n\ninbound\n .command(\"view <id>\")\n .description(\"View pending email details and payment info\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (id, options) => {\n await inboundViewCommand(id, { json: options.json })\n })\n\ninbound\n .command(\"pay <id>\")\n .description(\"Pay for a pending email\")\n .requiredOption(\"--payment-hash <hash>\", \"Payment preimage from Lightning invoice\")\n .action(async (id, options) => {\n await inboundPayCommand(id, { paymentHash: options.paymentHash })\n })\n\ninbound\n .command(\"accept <id>\")\n .alias(\"a\")\n .description(\"Accept email without payment and whitelist sender\")\n .option(\"--no-whitelist\", \"Don't add sender to whitelist\")\n .action(async (id, options) => {\n await inboundAcceptCommand(id, { noWhitelist: options.whitelist === false })\n })\n\n// Credits commands\nconst credits = program.command(\"credits\").description(\"Manage credits\")\n\ncredits\n .command(\"balance\")\n .alias(\"bal\")\n .description(\"Show credit balance\")\n .action(creditsBalanceCommand)\n\ncredits\n .command(\"history\")\n .description(\"Show transaction history\")\n .option(\"-l, --limit <number>\", \"Number of transactions to show\", \"20\")\n .option(\"-t, --type <type>\", \"Filter by type (topup, email_sent, email_received, refund, bonus)\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (options) => {\n await creditsHistoryCommand({\n limit: parseInt(options.limit, 10),\n type: options.type,\n json: options.json,\n })\n })\n\ncredits\n .command(\"purchase\")\n .alias(\"buy\")\n .description(\"Purchase credits with Lightning\")\n .option(\"-o, --option <index>\", \"Purchase option index (0-3)\")\n .option(\"-w, --wait\", \"Wait for payment confirmation\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (options) => {\n await creditsPurchaseCommand({\n option: options.option !== undefined ? parseInt(options.option, 10) : undefined,\n json: options.json,\n wait: options.wait,\n })\n })\n\n// Settings commands\nconst settings = program.command(\"settings\").description(\"Manage email pricing and preferences\")\n\nsettings\n .command(\"show\")\n .description(\"Show current settings\")\n .option(\"-u, --username <name>\", \"Specific @btc.email address\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (options) => {\n await settingsShowCommand({ username: options.username, json: options.json })\n })\n\nsettings\n .command(\"pricing <sats>\")\n .description(\"Set email price in sats\")\n .option(\"-u, --username <name>\", \"Specific @btc.email address\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (sats, options) => {\n await settingsPricingCommand(sats, { username: options.username, json: options.json })\n })\n\nsettings\n .command(\"require-payment <on|off>\")\n .description(\"Toggle payment requirement for unknown senders\")\n .option(\"-u, --username <name>\", \"Specific @btc.email address\")\n .action(async (value, options) => {\n await settingsRequirePaymentCommand(value, { username: options.username })\n })\n\nsettings\n .command(\"auto-whitelist <on|off>\")\n .description(\"Toggle auto-whitelist after payment\")\n .option(\"-u, --username <name>\", \"Specific @btc.email address\")\n .action(async (value, options) => {\n await settingsAutoWhitelistCommand(value, { username: options.username })\n })\n\nsettings\n .command(\"auto-reply [message]\")\n .description(\"Set custom auto-reply message\")\n .option(\"-u, --username <name>\", \"Specific @btc.email address\")\n .option(\"--clear\", \"Reset to default message\")\n .action(async (message, options) => {\n await settingsAutoReplyCommand(message, { username: options.username, clear: options.clear })\n })\n\n// Default action for settings (show)\nsettings.action(async () => {\n await settingsShowCommand({})\n})\n\n// Whitelist commands\nconst whitelist = program\n .command(\"whitelist\")\n .alias(\"wl\")\n .description(\"Manage senders who can email you for free\")\n\nwhitelist\n .command(\"list\")\n .description(\"List whitelist entries\")\n .option(\"-u, --username <name>\", \"Specific @btc.email address\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (options) => {\n await whitelistListCommand({ username: options.username, json: options.json })\n })\n\nwhitelist\n .command(\"add <entry>\")\n .description(\"Add email or @domain to whitelist\")\n .option(\"-u, --username <name>\", \"Specific @btc.email address\")\n .option(\"-n, --note <note>\", \"Optional note\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (entry, options) => {\n await whitelistAddCommand(entry, {\n username: options.username,\n note: options.note,\n json: options.json,\n })\n })\n\nwhitelist\n .command(\"remove <id>\")\n .description(\"Remove entry from whitelist by ID\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (id, options) => {\n await whitelistRemoveCommand(id, { json: options.json })\n })\n\n// Default action for whitelist (list)\nwhitelist.action(async () => {\n await whitelistListCommand({})\n})\n\n// Blocklist commands\nconst blocklist = program.command(\"blocklist\").alias(\"bl\").description(\"Manage blocked senders\")\n\nblocklist\n .command(\"list\")\n .description(\"List blocklist entries\")\n .option(\"-u, --username <name>\", \"Specific @btc.email address\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (options) => {\n await blocklistListCommand({ username: options.username, json: options.json })\n })\n\nblocklist\n .command(\"add <entry>\")\n .description(\"Add email or @domain to blocklist\")\n .option(\"-u, --username <name>\", \"Specific @btc.email address\")\n .option(\"-r, --reason <reason>\", \"Optional reason\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (entry, options) => {\n await blocklistAddCommand(entry, {\n username: options.username,\n reason: options.reason,\n json: options.json,\n })\n })\n\nblocklist\n .command(\"remove <id>\")\n .description(\"Remove entry from blocklist by ID\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (id, options) => {\n await blocklistRemoveCommand(id, { json: options.json })\n })\n\n// Default action for blocklist (list)\nblocklist.action(async () => {\n await blocklistListCommand({})\n})\n\n// Network commands\nconst network = program.command(\"network\").description(\"Manage Lightning network mode\")\n\nnetwork\n .command(\"show\")\n .description(\"Show current network mode\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (options) => {\n await networkShowCommand({ json: options.json })\n })\n\nnetwork\n .command(\"testnet\")\n .description(\"Switch to testnet (fake Bitcoin)\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (options) => {\n await networkSwitchCommand(\"testnet\", { json: options.json })\n })\n\nnetwork\n .command(\"mainnet\")\n .description(\"Switch to mainnet (real Bitcoin)\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (options) => {\n await networkSwitchCommand(\"mainnet\", { json: options.json })\n })\n\n// Default action for network (show)\nnetwork.action(async () => {\n await networkShowCommand({})\n})\n\n// Stats command\nprogram\n .command(\"stats\")\n .description(\"Show dashboard statistics\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (options) => {\n await statsCommand({ json: options.json })\n })\n\n// Default action (no command specified)\nprogram.action(() => {\n console.log()\n console.log(pc.bold(\"btc.email CLI\") + pc.dim(\" - Spam-free email powered by Bitcoin Lightning\"))\n console.log()\n program.outputHelp()\n})\n\n// Parse and run\nprogram.parse()\n","/**\n * Blocklist command for btc.email CLI\n *\n * Manage blocked senders who are silently rejected.\n */\n\nimport pc from \"picocolors\"\nimport { addToBlocklist, getBlocklist, removeFromBlocklist } from \"../api.js\"\nimport { getToken } from \"../config.js\"\n\nexport interface BlocklistListOptions {\n username?: string\n json?: boolean\n}\n\nexport interface BlocklistAddOptions {\n username?: string\n reason?: string\n json?: boolean\n}\n\nexport interface BlocklistRemoveOptions {\n json?: boolean\n}\n\n/**\n * List blocklist entries\n */\nexport async function blocklistListCommand(options: BlocklistListOptions = {}) {\n const token = getToken()\n if (!token) {\n console.error(pc.red(\"Not logged in. Run 'btcemail login' first.\"))\n process.exit(1)\n }\n\n const result = await getBlocklist(options.username)\n\n if (!result.ok) {\n console.error(pc.red(`Error: ${result.error.message}`))\n process.exit(1)\n }\n\n const { username, entries } = result.data\n\n if (options.json) {\n console.log(JSON.stringify({ username, entries }, null, 2))\n return\n }\n\n console.log()\n console.log(pc.bold(\"Blocklist for \") + pc.cyan(`${username}@btc.email`))\n console.log()\n\n if (entries.length === 0) {\n console.log(pc.dim(\" No entries in blocklist.\"))\n console.log()\n console.log(pc.dim(\" Add entries with: btcemail blocklist add <email>\"))\n console.log(pc.dim(\" Or for domains: btcemail blocklist add @domain.com\"))\n console.log()\n return\n }\n\n console.log(pc.dim(` ${entries.length} ${entries.length === 1 ? \"entry\" : \"entries\"}:`))\n console.log()\n\n for (const entry of entries) {\n const value = entry.sender_email || `@${entry.sender_domain}`\n const reason = entry.reason ? pc.dim(` - ${entry.reason}`) : \"\"\n console.log(` ${pc.red(value)}${reason}`)\n console.log(pc.dim(` ID: ${entry.id}`))\n }\n console.log()\n}\n\n/**\n * Add entry to blocklist\n */\nexport async function blocklistAddCommand(entry: string, options: BlocklistAddOptions = {}) {\n const token = getToken()\n if (!token) {\n console.error(pc.red(\"Not logged in. Run 'btcemail login' first.\"))\n process.exit(1)\n }\n\n // Check if it's a domain (starts with @)\n const isDomain = entry.startsWith(\"@\")\n const payload = isDomain\n ? { domain: entry.slice(1), reason: options.reason }\n : { email: entry, reason: options.reason }\n\n const result = await addToBlocklist(payload, options.username)\n\n if (!result.ok) {\n console.error(pc.red(`Error: ${result.error.message}`))\n process.exit(1)\n }\n\n if (options.json) {\n console.log(JSON.stringify({ success: true, entry: result.data.entry }, null, 2))\n return\n }\n\n console.log(pc.green(`Added to blocklist: ${pc.red(entry)}`))\n}\n\n/**\n * Remove entry from blocklist\n */\nexport async function blocklistRemoveCommand(id: string, options: BlocklistRemoveOptions = {}) {\n const token = getToken()\n if (!token) {\n console.error(pc.red(\"Not logged in. Run 'btcemail login' first.\"))\n process.exit(1)\n }\n\n const result = await removeFromBlocklist(id)\n\n if (!result.ok) {\n console.error(pc.red(`Error: ${result.error.message}`))\n process.exit(1)\n }\n\n if (options.json) {\n console.log(JSON.stringify({ success: true }, null, 2))\n return\n }\n\n console.log(pc.green(\"Removed from blocklist\"))\n}\n","/**\n * CLI Configuration Management\n *\n * Stores auth tokens and user preferences in ~/.btcemail/config.json\n */\n\nimport Conf from \"conf\"\n\nexport type CLIConfig = {\n auth?: {\n token: string\n expiresAt: string\n userId: string\n email: string\n }\n api?: {\n baseUrl: string\n }\n preferences?: {\n useCredits: boolean\n defaultEditor: string\n }\n}\n\nconst config = new Conf<CLIConfig>({\n projectName: \"btcemail\",\n schema: {\n auth: {\n type: \"object\",\n properties: {\n token: { type: \"string\" },\n expiresAt: { type: \"string\" },\n userId: { type: \"string\" },\n email: { type: \"string\" },\n },\n },\n api: {\n type: \"object\",\n properties: {\n baseUrl: { type: \"string\" },\n },\n default: {\n baseUrl: \"https://btc.email/api/v1\",\n },\n },\n preferences: {\n type: \"object\",\n properties: {\n useCredits: { type: \"boolean\" },\n defaultEditor: { type: \"string\" },\n },\n default: {\n useCredits: true,\n defaultEditor: \"vim\",\n },\n },\n },\n})\n\nexport function getConfig(): CLIConfig {\n return config.store\n}\n\nexport function getAuth(): CLIConfig[\"auth\"] | undefined {\n return config.get(\"auth\")\n}\n\nexport function setAuth(auth: CLIConfig[\"auth\"]): void {\n config.set(\"auth\", auth)\n}\n\nexport function clearAuth(): void {\n config.delete(\"auth\")\n}\n\nexport function getApiBaseUrl(): string {\n return process.env.BTCEMAIL_API_URL || config.get(\"api.baseUrl\") || \"https://btc.email/api/v1\"\n}\n\nexport function isAuthenticated(): boolean {\n const auth = getAuth()\n if (!auth?.token || !auth?.expiresAt) {\n return false\n }\n\n // Check if token is expired\n const expiresAt = new Date(auth.expiresAt)\n return expiresAt > new Date()\n}\n\n/**\n * Check if token is expiring soon (within 5 minutes)\n */\nexport function isTokenExpiringSoon(): boolean {\n const auth = getAuth()\n if (!auth?.token || !auth?.expiresAt) {\n return false\n }\n\n const expiresAt = new Date(auth.expiresAt)\n const fiveMinutesFromNow = new Date(Date.now() + 5 * 60 * 1000)\n return expiresAt <= fiveMinutesFromNow && expiresAt > new Date()\n}\n\n/**\n * Get time until token expires in human-readable format\n */\nexport function getTokenExpiryInfo(): { expired: boolean; expiresIn?: string } {\n const auth = getAuth()\n if (!auth?.token || !auth?.expiresAt) {\n return { expired: true }\n }\n\n const expiresAt = new Date(auth.expiresAt)\n const now = new Date()\n\n if (expiresAt <= now) {\n return { expired: true }\n }\n\n const diffMs = expiresAt.getTime() - now.getTime()\n const diffMins = Math.floor(diffMs / 60000)\n const diffHours = Math.floor(diffMins / 60)\n\n if (diffHours > 0) {\n return { expired: false, expiresIn: `${diffHours}h ${diffMins % 60}m` }\n }\n return { expired: false, expiresIn: `${diffMins}m` }\n}\n\nexport function getToken(): string | null {\n const auth = getAuth()\n if (!auth?.token) return null\n\n // Check if token is expired\n const expiresAt = new Date(auth.expiresAt)\n if (expiresAt <= new Date()) {\n clearAuth()\n return null\n }\n\n return auth.token\n}\n\nexport { config }\n","/**\n * API Client for btc.email CLI\n *\n * Handles all HTTP requests to the btc.email API.\n * v1 API returns: { success: true, data: {...}, meta: {...} }\n */\n\nimport { getApiBaseUrl, getToken } from \"./config.js\"\n\nexport type ApiResponse<T> =\n | { ok: true; data: T }\n | { ok: false; error: { code: string; message: string; details?: unknown } }\n\nexport type PaginatedResponse<T> = {\n data: T[]\n pagination: {\n total: number\n limit: number\n offset: number\n hasMore: boolean\n }\n}\n\n/**\n * v1 API response format\n */\ntype V1ApiResponse<T> = {\n success: boolean\n data?: T\n error?: { code: string; message: string; details?: unknown }\n meta?: { requestId: string; timestamp: string }\n pagination?: {\n total: number\n limit: number\n offset: number\n hasMore: boolean\n }\n}\n\n/**\n * Make an authenticated API request\n */\nexport async function apiRequest<T>(\n endpoint: string,\n options: RequestInit = {}\n): Promise<ApiResponse<T>> {\n const token = getToken()\n const baseUrl = getApiBaseUrl()\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n }\n\n if (token) {\n headers.Authorization = `Bearer ${token}`\n }\n\n try {\n const response = await fetch(`${baseUrl}${endpoint}`, {\n ...options,\n headers,\n })\n\n const json = (await response.json()) as V1ApiResponse<T>\n\n // Handle v1 API format: { success: boolean, data?: T, error?: {...} }\n if (!response.ok || json.success === false) {\n return {\n ok: false,\n error: json.error || {\n code: \"UNKNOWN_ERROR\",\n message: `Request failed with status ${response.status}`,\n },\n }\n }\n\n // For paginated responses, include pagination in the result\n if (json.pagination) {\n return {\n ok: true,\n data: { data: json.data, pagination: json.pagination } as T,\n }\n }\n\n // Extract data from v1 response format\n return { ok: true, data: json.data as T }\n } catch (error) {\n return {\n ok: false,\n error: {\n code: \"NETWORK_ERROR\",\n message: error instanceof Error ? error.message : \"Network request failed\",\n },\n }\n }\n}\n\n/**\n * Make an unauthenticated API request (for login, etc.)\n */\nexport async function publicRequest<T>(\n endpoint: string,\n options: RequestInit = {}\n): Promise<ApiResponse<T>> {\n const baseUrl = getApiBaseUrl()\n\n try {\n const response = await fetch(`${baseUrl}${endpoint}`, {\n ...options,\n headers: {\n \"Content-Type\": \"application/json\",\n ...options.headers,\n },\n })\n\n const json = (await response.json()) as V1ApiResponse<T>\n\n if (!response.ok || json.success === false) {\n return {\n ok: false,\n error: json.error || {\n code: \"UNKNOWN_ERROR\",\n message: `Request failed with status ${response.status}`,\n },\n }\n }\n\n return { ok: true, data: json.data as T }\n } catch (error) {\n return {\n ok: false,\n error: {\n code: \"NETWORK_ERROR\",\n message: error instanceof Error ? error.message : \"Network request failed\",\n },\n }\n }\n}\n\n// API endpoint helpers\n\nexport async function getEmails(options: {\n folder?: string\n limit?: number\n offset?: number\n search?: string\n}) {\n const params = new URLSearchParams()\n if (options.folder) params.set(\"folder\", options.folder)\n if (options.limit) params.set(\"limit\", String(options.limit))\n if (options.offset) params.set(\"offset\", String(options.offset))\n if (options.search) params.set(\"search\", options.search)\n\n return apiRequest<PaginatedResponse<Email>>(`/email?${params}`)\n}\n\nexport async function getEmail(id: string) {\n return apiRequest<Email>(`/email/${id}`)\n}\n\nexport async function getCreditsBalance() {\n return apiRequest<CreditBalance>(\"/credits/balance\")\n}\n\nexport type CreditBalance = {\n balanceSats: number\n lifetimePurchasedSats: number\n lifetimeSpentSats: number\n lastPurchaseAt: string | null\n}\n\nexport async function getWhoami() {\n return apiRequest<{ id: string; email: string; username?: string }>(\"/auth/whoami\")\n}\n\n// Pending/Inbound email functions\n\nexport async function getPendingEmails(options: { limit?: number; offset?: number } = {}) {\n const params = new URLSearchParams()\n if (options.limit) params.set(\"limit\", String(options.limit))\n if (options.offset) params.set(\"offset\", String(options.offset))\n\n return apiRequest<PaginatedResponse<PendingEmail>>(`/inbound/pending?${params}`)\n}\n\nexport async function getPendingEmail(id: string) {\n return apiRequest<PendingEmailDetail>(`/inbound/${id}`)\n}\n\nexport async function payForEmail(id: string, paymentHash: string) {\n return apiRequest<{ emailId: string; status: string }>(`/inbound/${id}/pay`, {\n method: \"POST\",\n body: JSON.stringify({ paymentHash }),\n })\n}\n\nexport async function acceptPendingEmail(id: string, whitelist = true) {\n return apiRequest<{ emailId: string; status: string; whitelisted: boolean; senderEmail: string }>(\n `/inbound/${id}/accept`,\n {\n method: \"POST\",\n body: JSON.stringify({ whitelist }),\n }\n )\n}\n\n// Send email functions\n\nexport async function sendEmail(options: {\n to: string[]\n subject: string\n body: string\n bodyText?: string\n fromEmail: string\n paymentHash?: string\n}) {\n return apiRequest<{ emailId: string; status: string; messageId?: string }>(\"/email/send\", {\n method: \"POST\",\n body: JSON.stringify(options),\n })\n}\n\nexport async function getL402Invoice(options: {\n fromEmail: string\n toEmails: string[]\n amountSats?: number\n}) {\n // L402 endpoint is at /api/l402, not /api/v1/l402\n // Derive root API URL from v1 base URL\n const v1BaseUrl = getApiBaseUrl()\n const rootApiUrl = v1BaseUrl.replace(\"/api/v1\", \"/api\")\n const token = getToken()\n\n const headers: HeadersInit = {\n \"Content-Type\": \"application/json\",\n }\n if (token) {\n headers.Authorization = `Bearer ${token}`\n }\n\n try {\n const response = await fetch(`${rootApiUrl}/l402/invoice`, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n sender_email: options.fromEmail,\n recipient_emails: options.toEmails,\n amount_sats: options.amountSats,\n }),\n })\n\n const json = (await response.json()) as {\n success: boolean\n data?: L402Invoice\n error?: { code: string; message: string; details?: unknown }\n }\n\n if (!response.ok || json.success === false) {\n return {\n ok: false as const,\n error: json.error || {\n code: \"UNKNOWN_ERROR\",\n message: `Request failed with status ${response.status}`,\n },\n }\n }\n\n return { ok: true as const, data: json.data as L402Invoice }\n } catch (error) {\n return {\n ok: false as const,\n error: {\n code: \"NETWORK_ERROR\",\n message: error instanceof Error ? error.message : \"Network request failed\",\n },\n }\n }\n}\n\n// Types\n\nexport type Email = {\n id: string\n subject: string\n from: { email: string; name?: string }\n to: { email: string; name?: string }[]\n snippet: string\n body?: string\n bodyText?: string\n date: string\n unread: boolean\n labels: string[]\n}\n\nexport type PendingEmail = {\n id: string\n subject: string\n from: { email: string; name?: string }\n amountSats: number\n createdAt: string\n}\n\nexport type PendingEmailDetail = {\n id: string\n subject: string\n from: { email: string; name?: string }\n body: string\n bodyText: string\n amountSats: number\n createdAt: string\n paymentHash: string | null\n}\n\nexport type L402Invoice = {\n invoice: string\n paymentHash: string\n amountSats: number\n expiresAt: string\n}\n\n// Delivered emails (paid inbound emails)\n\nexport type DeliveredEmail = {\n id: string\n subject: string\n from: { email: string; name?: string }\n snippet: string\n date: string\n}\n\nexport async function getDeliveredEmails(options: { limit?: number; offset?: number } = {}) {\n const params = new URLSearchParams()\n if (options.limit) params.set(\"limit\", String(options.limit))\n if (options.offset) params.set(\"offset\", String(options.offset))\n\n return apiRequest<PaginatedResponse<DeliveredEmail>>(`/inbound/delivered?${params}`)\n}\n\n// Credit transactions\n\nexport type CreditTransaction = {\n id: string\n amountSats: number\n transactionType: string\n balanceAfter: number\n referenceId?: string\n createdAt: string\n}\n\nexport async function getCreditTransactions(\n options: { limit?: number; offset?: number; type?: string } = {}\n) {\n const params = new URLSearchParams()\n if (options.limit) params.set(\"limit\", String(options.limit))\n if (options.offset) params.set(\"offset\", String(options.offset))\n if (options.type) params.set(\"type\", options.type)\n\n return apiRequest<PaginatedResponse<CreditTransaction>>(`/credits/transactions?${params}`)\n}\n\n// Credit purchase\n\nexport type CreditPurchaseOption = {\n amountSats: number\n priceSats: number\n bonusSats: number\n label: string\n description: string\n}\n\nexport type CreditPurchaseResult = {\n paymentId: string\n invoice: string\n paymentHash: string\n amountSats: number\n creditsToReceive: number\n bonusSats: number\n expiresAt: string\n}\n\nexport async function purchaseCredits(optionIndex: number) {\n return apiRequest<CreditPurchaseResult>(\"/credits/purchase\", {\n method: \"POST\",\n body: JSON.stringify({ optionIndex }),\n })\n}\n\n// Check payment status\nexport type PaymentStatusResult = {\n paid: boolean\n delivered?: boolean\n status?: string\n pendingEmailId?: string\n}\n\nexport async function checkPaymentStatus(\n paymentHash: string\n): Promise<ApiResponse<PaymentStatusResult>> {\n // Payment status endpoint is at /api/lightning/webhook (GET)\n // Derive root API URL from v1 base URL\n const v1BaseUrl = getApiBaseUrl()\n const rootApiUrl = v1BaseUrl.replace(\"/api/v1\", \"/api\")\n const token = getToken()\n\n const headers: HeadersInit = {\n \"Content-Type\": \"application/json\",\n }\n if (token) {\n headers.Authorization = `Bearer ${token}`\n }\n\n try {\n const response = await fetch(`${rootApiUrl}/lightning/webhook?payment_hash=${paymentHash}`, {\n headers,\n })\n\n const json = (await response.json()) as {\n success: boolean\n paid?: boolean\n delivered?: boolean\n status?: string\n state?: string\n pendingEmailId?: string\n error?: { code: string; message: string }\n }\n\n if (!response.ok || json.success === false) {\n return {\n ok: false,\n error: json.error || {\n code: \"UNKNOWN_ERROR\",\n message: `Request failed with status ${response.status}`,\n },\n }\n }\n\n return {\n ok: true,\n data: {\n paid: json.paid || false,\n delivered: json.delivered,\n status: json.status || json.state,\n pendingEmailId: json.pendingEmailId,\n },\n }\n } catch (error) {\n return {\n ok: false,\n error: {\n code: \"NETWORK_ERROR\",\n message: error instanceof Error ? error.message : \"Network request failed\",\n },\n }\n }\n}\n\n// Settings API\n\nexport type UserSettings = {\n username: string\n usernames: string[]\n settings: {\n default_price_sats: number\n auto_whitelist_on_payment: boolean\n require_payment_from_unknown: boolean\n custom_auto_reply_body: string | null\n }\n}\n\nexport async function getSettings(username?: string) {\n const params = username ? `?username=${username}` : \"\"\n return apiRequest<UserSettings>(`/settings${params}`)\n}\n\nexport async function updateSettings(\n settings: {\n default_price_sats?: number\n auto_whitelist_on_payment?: boolean\n require_payment_from_unknown?: boolean\n custom_auto_reply_body?: string | null\n },\n username?: string\n) {\n const params = username ? `?username=${username}` : \"\"\n return apiRequest<{ username: string; settings: UserSettings[\"settings\"] }>(\n `/settings${params}`,\n {\n method: \"POST\",\n body: JSON.stringify(settings),\n }\n )\n}\n\n// Whitelist API\n\nexport type WhitelistEntry = {\n id: string\n sender_email: string | null\n sender_domain: string | null\n added_via: string\n note: string | null\n added_at: string\n}\n\nexport async function getWhitelist(username?: string) {\n const params = username ? `?username=${username}` : \"\"\n return apiRequest<{ username: string; entries: WhitelistEntry[] }>(`/whitelist${params}`)\n}\n\nexport async function addToWhitelist(\n entry: { email?: string; domain?: string; note?: string },\n username?: string\n) {\n const params = username ? `?username=${username}` : \"\"\n return apiRequest<{ entry: WhitelistEntry }>(`/whitelist${params}`, {\n method: \"POST\",\n body: JSON.stringify(entry),\n })\n}\n\nexport async function removeFromWhitelist(id: string) {\n return apiRequest<{ success: boolean }>(`/whitelist/${id}`, {\n method: \"DELETE\",\n })\n}\n\n// Blocklist API\n\nexport type BlocklistEntry = {\n id: string\n sender_email: string | null\n sender_domain: string | null\n reason: string | null\n blocked_at: string\n}\n\nexport async function getBlocklist(username?: string) {\n const params = username ? `?username=${username}` : \"\"\n return apiRequest<{ username: string; entries: BlocklistEntry[] }>(`/blocklist${params}`)\n}\n\nexport async function addToBlocklist(\n entry: { email?: string; domain?: string; reason?: string },\n username?: string\n) {\n const params = username ? `?username=${username}` : \"\"\n return apiRequest<{ entry: BlocklistEntry }>(`/blocklist${params}`, {\n method: \"POST\",\n body: JSON.stringify(entry),\n })\n}\n\nexport async function removeFromBlocklist(id: string) {\n return apiRequest<{ success: boolean }>(`/blocklist/${id}`, {\n method: \"DELETE\",\n })\n}\n\n// Network API\n\nexport type NetworkInfo = {\n network_mode: \"testnet\" | \"mainnet\"\n networks: {\n testnet: { available: boolean }\n mainnet: { available: boolean }\n }\n}\n\nexport async function getNetwork() {\n return apiRequest<NetworkInfo>(\"/network\")\n}\n\nexport async function setNetwork(network: \"testnet\" | \"mainnet\") {\n return apiRequest<{ network_mode: string; message: string }>(\"/network\", {\n method: \"POST\",\n body: JSON.stringify({ network }),\n })\n}\n\n// Stats API\n\nexport type DashboardStats = {\n totalReceived: number\n totalSent: number\n pendingCount: number\n addressCount: number\n usernames: string[]\n}\n\nexport async function getStats() {\n return apiRequest<DashboardStats>(\"/stats\")\n}\n\n// Get purchase options (hardcoded since they match server)\nexport function getCreditPurchaseOptions(): CreditPurchaseOption[] {\n return [\n {\n amountSats: 1000,\n priceSats: 1000,\n bonusSats: 0,\n label: \"1,000 sats\",\n description: \"Good for ~10 emails\",\n },\n {\n amountSats: 5000,\n priceSats: 4500,\n bonusSats: 500,\n label: \"5,000 sats\",\n description: \"Good for ~50 emails (+10% bonus)\",\n },\n {\n amountSats: 10000,\n priceSats: 8500,\n bonusSats: 1500,\n label: \"10,000 sats\",\n description: \"Good for ~100 emails (+15% bonus)\",\n },\n {\n amountSats: 50000,\n priceSats: 40000,\n bonusSats: 10000,\n label: \"50,000 sats\",\n description: \"Good for ~500 emails (+20% bonus)\",\n },\n ]\n}\n","/**\n * Credits Command\n *\n * Shows credit balance, transaction history, and purchase options.\n */\n\nimport ora from \"ora\"\nimport pc from \"picocolors\"\nimport qrcode from \"qrcode-terminal\"\nimport {\n checkPaymentStatus,\n getCreditPurchaseOptions,\n getCreditsBalance,\n getCreditTransactions,\n purchaseCredits,\n} from \"../api.js\"\nimport { isAuthenticated } from \"../config.js\"\nimport { pollForPayment } from \"../utils/payment-polling.js\"\n\nexport async function creditsBalanceCommand(): Promise<void> {\n if (!isAuthenticated()) {\n console.log(pc.yellow(\"Not logged in.\"))\n console.log(pc.dim(\"Run `btcemail login` to authenticate.\"))\n process.exit(1)\n }\n\n const spinner = ora(\"Fetching balance...\").start()\n\n const result = await getCreditsBalance()\n\n if (!result.ok) {\n spinner.fail(`Error: ${result.error.message}`)\n process.exit(1)\n }\n\n spinner.stop()\n\n const { balanceSats, lifetimePurchasedSats, lifetimeSpentSats } = result.data\n\n console.log()\n console.log(pc.bold(\"Credit Balance\"))\n console.log()\n console.log(` ${pc.green(formatSats(balanceSats))} sats`)\n console.log()\n\n if (lifetimePurchasedSats > 0 || lifetimeSpentSats > 0) {\n console.log(pc.dim(` Purchased: ${formatSats(lifetimePurchasedSats)} sats`))\n console.log(pc.dim(` Spent: ${formatSats(lifetimeSpentSats)} sats`))\n console.log()\n }\n\n if (balanceSats === 0) {\n console.log(pc.dim(\" No credits available.\"))\n console.log(pc.dim(\" Run `btcemail credits purchase` to buy credits.\"))\n console.log()\n }\n}\n\nexport type CreditsHistoryOptions = {\n limit?: number\n type?: string\n json?: boolean\n}\n\nexport async function creditsHistoryCommand(options: CreditsHistoryOptions): Promise<void> {\n if (!isAuthenticated()) {\n console.log(pc.yellow(\"Not logged in.\"))\n console.log(pc.dim(\"Run `btcemail login` to authenticate.\"))\n process.exit(1)\n }\n\n const spinner = ora(\"Loading transaction history...\").start()\n\n const result = await getCreditTransactions({\n limit: options.limit || 20,\n type: options.type,\n })\n\n if (!result.ok) {\n spinner.fail(`Error: ${result.error.message}`)\n process.exit(1)\n }\n\n const { data: transactions, pagination } = result.data\n\n spinner.stop()\n\n // JSON output mode\n if (options.json) {\n console.log(JSON.stringify({ transactions, pagination }, null, 2))\n return\n }\n\n // Table output\n console.log()\n console.log(pc.bold(\"Transaction History\"))\n console.log()\n\n if (transactions.length === 0) {\n console.log(pc.dim(\" No transactions found.\"))\n console.log()\n return\n }\n\n // Header\n console.log(\n ` ${pc.dim(\"Date\".padEnd(12))} ${pc.dim(\"Type\".padEnd(15))} ${pc.dim(\"Amount\".padEnd(12))} ${pc.dim(\"Balance\")}`\n )\n console.log(pc.dim(` ${\"-\".repeat(55)}`))\n\n // Rows\n for (const tx of transactions) {\n const date = formatDate(tx.createdAt)\n const type = formatTransactionType(tx.transactionType).padEnd(15)\n const amount = formatAmount(tx.amountSats).padEnd(12)\n const balance = formatSats(tx.balanceAfter)\n\n console.log(` ${date.padEnd(12)} ${type} ${amount} ${pc.dim(balance)}`)\n }\n\n console.log()\n\n if (pagination.hasMore) {\n console.log(pc.dim(` Use --limit to see more transactions.`))\n console.log()\n }\n}\n\nexport type CreditsPurchaseOptions = {\n option?: number\n json?: boolean\n wait?: boolean\n}\n\nexport async function creditsPurchaseCommand(options: CreditsPurchaseOptions): Promise<void> {\n if (!isAuthenticated()) {\n console.log(pc.yellow(\"Not logged in.\"))\n console.log(pc.dim(\"Run `btcemail login` to authenticate.\"))\n process.exit(1)\n }\n\n const purchaseOptions = getCreditPurchaseOptions()\n\n // If no option specified, show available options\n if (options.option === undefined) {\n console.log()\n console.log(pc.bold(\"Purchase Options\"))\n console.log()\n\n purchaseOptions.forEach((opt, index) => {\n console.log(` ${pc.cyan(`[${index}]`)} ${opt.label}`)\n console.log(` ${pc.dim(opt.description)}`)\n console.log(` ${pc.dim(`Price: ${formatSats(opt.priceSats)} sats`)}`)\n if (opt.bonusSats > 0) {\n console.log(` ${pc.green(`+${formatSats(opt.bonusSats)} bonus sats`)}`)\n }\n console.log()\n })\n\n console.log(pc.dim(\" Usage: btcemail credits purchase --option <index>\"))\n console.log(pc.dim(\" Add --wait to wait for payment confirmation.\"))\n console.log()\n return\n }\n\n // Validate option index\n if (options.option < 0 || options.option >= purchaseOptions.length) {\n console.error(pc.red(`Error: Invalid option. Choose 0-${purchaseOptions.length - 1}.`))\n process.exit(1)\n }\n\n const _selectedOption = purchaseOptions[options.option]\n\n const spinner = ora(\"Creating invoice...\").start()\n\n const result = await purchaseCredits(options.option)\n\n if (!result.ok) {\n spinner.fail(`Error: ${result.error.message}`)\n process.exit(1)\n }\n\n spinner.stop()\n\n const purchase = result.data\n\n // JSON output mode\n if (options.json) {\n console.log(JSON.stringify(purchase, null, 2))\n return\n }\n\n console.log()\n console.log(pc.bold(\"Lightning Invoice\"))\n console.log()\n console.log(` ${pc.dim(\"Amount:\")} ${formatSats(purchase.amountSats)} sats`)\n console.log(` ${pc.dim(\"Credits:\")} ${formatSats(purchase.creditsToReceive)} sats`)\n if (purchase.bonusSats > 0) {\n console.log(` ${pc.dim(\"Bonus:\")} ${pc.green(`+${formatSats(purchase.bonusSats)} sats`)}`)\n }\n console.log()\n\n // Display QR code\n console.log(pc.bold(\"Scan to pay:\"))\n console.log()\n qrcode.generate(purchase.invoice, { small: true }, (qr) => {\n // Indent the QR code\n const indentedQr = qr\n .split(\"\\n\")\n .map((line) => ` ${line}`)\n .join(\"\\n\")\n console.log(indentedQr)\n })\n console.log()\n\n console.log(pc.bold(\"Invoice:\"))\n console.log()\n console.log(` ${purchase.invoice}`)\n console.log()\n console.log(pc.dim(` Payment hash: ${purchase.paymentHash}`))\n console.log(pc.dim(` Expires: ${new Date(purchase.expiresAt).toLocaleString()}`))\n console.log()\n\n // If --wait flag is set, poll for payment\n if (options.wait) {\n console.log()\n const status = await pollForPayment({\n paymentHash: purchase.paymentHash,\n checkFn: async (hash) => {\n const result = await checkPaymentStatus(hash)\n if (result.ok) {\n return { paid: result.data.paid }\n }\n return { paid: false }\n },\n onPaid: async () => {\n // Check updated balance\n const balanceResult = await getCreditsBalance()\n if (balanceResult.ok) {\n console.log()\n console.log(\n `${pc.dim(\"New balance:\")} ${pc.green(formatSats(balanceResult.data.balanceSats))} sats`\n )\n }\n },\n })\n\n if (!status.paid) {\n console.log(pc.dim(\" You can still pay the invoice and credits will be added.\"))\n }\n console.log()\n } else {\n console.log(pc.dim(\" Scan the QR code or copy the invoice above to pay.\"))\n console.log(pc.dim(\" Use --wait to wait for payment confirmation.\"))\n console.log()\n }\n}\n\nfunction formatSats(sats: number): string {\n return sats.toLocaleString()\n}\n\nfunction formatAmount(sats: number): string {\n if (sats >= 0) {\n return pc.green(`+${formatSats(sats)}`)\n }\n return pc.red(formatSats(sats))\n}\n\nfunction formatTransactionType(type: string): string {\n const types: Record<string, string> = {\n topup: \"Top-up\",\n email_sent: \"Email Sent\",\n email_received: \"Email Received\",\n refund: \"Refund\",\n bonus: \"Bonus\",\n }\n return types[type] || type\n}\n\nfunction formatDate(dateString: string): string {\n const date = new Date(dateString)\n return date.toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n })\n}\n","/**\n * Payment Polling Utility\n *\n * Polls for payment status and shows a progress indicator.\n */\n\nimport pc from \"picocolors\"\n\nexport type PaymentStatus = {\n paid: boolean\n delivered?: boolean\n status?: string\n}\n\nexport type PollOptions = {\n paymentHash: string\n checkFn: (paymentHash: string) => Promise<PaymentStatus>\n maxAttempts?: number\n intervalMs?: number\n onPaid?: () => void\n}\n\nconst SPINNER_FRAMES = [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"]\n\n/**\n * Poll for payment status with a spinner\n */\nexport async function pollForPayment(options: PollOptions): Promise<PaymentStatus> {\n const { paymentHash, checkFn, maxAttempts = 120, intervalMs = 2500, onPaid } = options\n\n let frame = 0\n let attempts = 0\n\n // Print initial status\n process.stdout.write(`${pc.cyan(SPINNER_FRAMES[0])} Waiting for payment...`)\n\n while (attempts < maxAttempts) {\n try {\n const status = await checkFn(paymentHash)\n\n if (status.paid) {\n // Clear the spinner line\n process.stdout.write(`\\r${\" \".repeat(50)}\\r`)\n console.log(`${pc.green(\"✓\")} Payment received!`)\n if (onPaid) onPaid()\n return status\n }\n } catch {\n // Ignore errors, keep polling\n }\n\n // Update spinner\n frame = (frame + 1) % SPINNER_FRAMES.length\n const timeLeft = Math.ceil(((maxAttempts - attempts) * intervalMs) / 1000 / 60)\n process.stdout.write(\n `\\r${pc.cyan(SPINNER_FRAMES[frame])} Waiting for payment... (${timeLeft}m remaining)`\n )\n\n // Wait before next check\n await sleep(intervalMs)\n attempts++\n }\n\n // Clear the spinner line\n process.stdout.write(`\\r${\" \".repeat(60)}\\r`)\n console.log(`${pc.yellow(\"⚠\")} Timed out waiting for payment.`)\n\n return { paid: false }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\n/**\n * Create a simple progress indicator (non-polling)\n */\nexport function createSpinner(message: string): { stop: (success?: boolean) => void } {\n let frame = 0\n let running = true\n\n const interval = setInterval(() => {\n if (!running) return\n frame = (frame + 1) % SPINNER_FRAMES.length\n process.stdout.write(`\\r${pc.cyan(SPINNER_FRAMES[frame])} ${message}`)\n }, 80)\n\n return {\n stop: (success = true) => {\n running = false\n clearInterval(interval)\n process.stdout.write(`\\r${\" \".repeat(message.length + 5)}\\r`)\n if (success) {\n console.log(`${pc.green(\"✓\")} ${message}`)\n } else {\n console.log(`${pc.red(\"✗\")} ${message}`)\n }\n },\n }\n}\n","/**\n * Inbound Commands\n *\n * View and pay for pending emails that require payment.\n */\n\nimport ora from \"ora\"\nimport pc from \"picocolors\"\nimport {\n acceptPendingEmail,\n getDeliveredEmails,\n getPendingEmail,\n getPendingEmails,\n payForEmail,\n} from \"../api.js\"\nimport { isAuthenticated } from \"../config.js\"\n\nexport type InboundListOptions = {\n limit?: number\n json?: boolean\n}\n\nexport async function inboundDeliveredCommand(options: InboundListOptions): Promise<void> {\n if (!isAuthenticated()) {\n console.log(pc.yellow(\"Not logged in.\"))\n console.log(pc.dim(\"Run `btcemail login` to authenticate.\"))\n process.exit(1)\n }\n\n const spinner = ora(\"Loading delivered emails...\").start()\n\n const result = await getDeliveredEmails({\n limit: options.limit || 20,\n })\n\n if (!result.ok) {\n spinner.fail(`Error: ${result.error.message}`)\n process.exit(1)\n }\n\n const { data: emails, pagination } = result.data\n\n spinner.stop()\n\n // JSON output mode\n if (options.json) {\n console.log(JSON.stringify({ emails, pagination }, null, 2))\n return\n }\n\n console.log()\n console.log(pc.bold(`Delivered (${pagination.total} paid emails received)`))\n console.log()\n\n if (emails.length === 0) {\n console.log(pc.dim(\" No delivered emails yet.\"))\n console.log()\n return\n }\n\n // Header\n console.log(\n ` ${pc.dim(\"#\".padEnd(4))} ${pc.dim(\"From\".padEnd(28))} ${pc.dim(\"Subject\".padEnd(40))} ${pc.dim(\"Date\")}`\n )\n console.log(pc.dim(` ${\"-\".repeat(85)}`))\n\n // Rows\n emails.forEach((email, index) => {\n const num = pc.cyan(String(index + 1).padEnd(4))\n const from = truncate(email.from.name || email.from.email, 26).padEnd(28)\n const subject = truncate(email.subject, 38).padEnd(40)\n const date = formatDate(email.date)\n\n console.log(` ${num}${from} ${subject} ${pc.dim(date)}`)\n })\n\n console.log()\n\n if (pagination.hasMore) {\n console.log(\n pc.dim(` Showing ${emails.length} of ${pagination.total}. Use --limit to see more.`)\n )\n console.log()\n }\n\n console.log(pc.dim(\" Read email: btcemail read <id>\"))\n console.log()\n}\n\nexport async function inboundPendingCommand(options: InboundListOptions): Promise<void> {\n if (!isAuthenticated()) {\n console.log(pc.yellow(\"Not logged in.\"))\n console.log(pc.dim(\"Run `btcemail login` to authenticate.\"))\n process.exit(1)\n }\n\n const spinner = ora(\"Loading pending emails...\").start()\n\n const result = await getPendingEmails({\n limit: options.limit || 20,\n })\n\n if (!result.ok) {\n spinner.fail(`Error: ${result.error.message}`)\n process.exit(1)\n }\n\n const { data: emails, pagination } = result.data\n\n spinner.stop()\n\n // JSON output mode\n if (options.json) {\n console.log(JSON.stringify({ emails, pagination }, null, 2))\n return\n }\n\n console.log()\n console.log(pc.bold(`Pending (${pagination.total} awaiting payment)`))\n console.log()\n\n if (emails.length === 0) {\n console.log(pc.dim(\" No pending emails.\"))\n console.log()\n return\n }\n\n // Header\n console.log(\n ` ${pc.dim(\"#\".padEnd(4))} ${pc.dim(\"From\".padEnd(28))} ${pc.dim(\"Subject\".padEnd(35))} ${pc.dim(\"Sats\")}`\n )\n console.log(pc.dim(` ${\"-\".repeat(80)}`))\n\n // Rows\n emails.forEach((email, index) => {\n const num = pc.cyan(String(index + 1).padEnd(4))\n const from = truncate(email.from.name || email.from.email, 26).padEnd(28)\n const subject = truncate(email.subject, 33).padEnd(35)\n const sats = pc.yellow(String(email.amountSats))\n\n console.log(` ${num}${from} ${subject} ${sats}`)\n })\n\n console.log()\n\n if (pagination.hasMore) {\n console.log(\n pc.dim(` Showing ${emails.length} of ${pagination.total}. Use --limit to see more.`)\n )\n console.log()\n }\n\n console.log(pc.dim(\" View details: btcemail inbound view <id>\"))\n console.log()\n}\n\nexport type InboundViewOptions = {\n json?: boolean\n}\n\nexport async function inboundViewCommand(id: string, options: InboundViewOptions): Promise<void> {\n if (!isAuthenticated()) {\n console.log(pc.yellow(\"Not logged in.\"))\n console.log(pc.dim(\"Run `btcemail login` to authenticate.\"))\n process.exit(1)\n }\n\n const spinner = ora(\"Loading email details...\").start()\n\n const result = await getPendingEmail(id)\n\n if (!result.ok) {\n if (result.error.code === \"NOT_FOUND\") {\n spinner.fail(`Pending email not found: ${id}`)\n } else {\n spinner.fail(`Error: ${result.error.message}`)\n }\n process.exit(1)\n }\n\n spinner.stop()\n\n const email = result.data\n\n // JSON output mode\n if (options.json) {\n console.log(JSON.stringify(email, null, 2))\n return\n }\n\n // Formatted output\n console.log()\n console.log(pc.bold(email.subject || \"(No subject)\"))\n console.log()\n console.log(`${pc.dim(\"From:\")} ${formatAddress(email.from)}`)\n console.log(`${pc.dim(\"Date:\")} ${formatFullDate(email.createdAt)}`)\n console.log(`${pc.dim(\"ID:\")} ${email.id}`)\n console.log()\n console.log(pc.yellow(`Payment Required: ${email.amountSats} sats`))\n console.log()\n\n if (email.paymentHash) {\n console.log(pc.dim(\"To receive this email, pay the invoice and run:\"))\n console.log(pc.cyan(` btcemail inbound pay ${email.id} --payment-hash <preimage>`))\n } else {\n console.log(pc.dim(\"Payment information not available.\"))\n }\n\n console.log()\n console.log(pc.dim(\"-\".repeat(60)))\n console.log()\n console.log(pc.dim(\"Preview (full content available after payment):\"))\n console.log()\n console.log(truncate(email.bodyText || email.body, 200))\n console.log()\n}\n\nexport type InboundPayOptions = {\n paymentHash: string\n}\n\nexport async function inboundPayCommand(id: string, options: InboundPayOptions): Promise<void> {\n if (!isAuthenticated()) {\n console.log(pc.yellow(\"Not logged in.\"))\n console.log(pc.dim(\"Run `btcemail login` to authenticate.\"))\n process.exit(1)\n }\n\n if (!options.paymentHash) {\n console.error(pc.red(\"Payment hash is required. Use --payment-hash <preimage>\"))\n process.exit(1)\n }\n\n const spinner = ora(\"Verifying payment...\").start()\n\n const result = await payForEmail(id, options.paymentHash)\n\n if (!result.ok) {\n if (result.error.code === \"PAYMENT_INVALID\") {\n spinner.fail(\"Payment verification failed.\")\n console.log(pc.dim(\"Make sure you paid the correct invoice and provided the preimage.\"))\n } else if (result.error.code === \"NOT_FOUND\") {\n spinner.fail(`Pending email not found or already delivered: ${id}`)\n } else {\n spinner.fail(`Error: ${result.error.message}`)\n }\n process.exit(1)\n }\n\n spinner.succeed(\"Payment verified! Email delivered.\")\n console.log()\n console.log(`${pc.dim(\"Email ID:\")} ${result.data.emailId}`)\n console.log(`${pc.dim(\"Status:\")} ${result.data.status}`)\n console.log()\n console.log(pc.dim(`Read email: btcemail read ${result.data.emailId}`))\n console.log()\n}\n\nexport type InboundAcceptOptions = {\n noWhitelist?: boolean\n}\n\nexport async function inboundAcceptCommand(id: string, options: InboundAcceptOptions): Promise<void> {\n if (!isAuthenticated()) {\n console.log(pc.yellow(\"Not logged in.\"))\n console.log(pc.dim(\"Run `btcemail login` to authenticate.\"))\n process.exit(1)\n }\n\n const spinner = ora(\"Accepting email...\").start()\n\n const shouldWhitelist = !options.noWhitelist\n\n const result = await acceptPendingEmail(id, shouldWhitelist)\n\n if (!result.ok) {\n if (result.error.code === \"NOT_FOUND\") {\n spinner.fail(`Pending email not found: ${id}`)\n } else {\n spinner.fail(`Error: ${result.error.message}`)\n }\n process.exit(1)\n }\n\n spinner.succeed(\"Email accepted and delivered!\")\n console.log()\n console.log(`${pc.dim(\"Email ID:\")} ${result.data.emailId}`)\n console.log(`${pc.dim(\"Status:\")} ${result.data.status}`)\n\n if (result.data.whitelisted) {\n console.log(`${pc.dim(\"Sender:\")} ${pc.green(result.data.senderEmail)} ${pc.dim(\"(whitelisted)\")}`)\n }\n\n console.log()\n console.log(pc.dim(`Read email: btcemail read ${result.data.emailId}`))\n console.log()\n}\n\nfunction truncate(str: string, maxLength: number): string {\n if (str.length <= maxLength) return str\n return `${str.slice(0, maxLength - 1)}…`\n}\n\nfunction formatAddress(addr: { email: string; name?: string }): string {\n if (addr.name) {\n return `${addr.name} <${addr.email}>`\n }\n return addr.email\n}\n\nfunction formatFullDate(dateString: string): string {\n const date = new Date(dateString)\n return date.toLocaleString(\"en-US\", {\n weekday: \"short\",\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n })\n}\n\nfunction formatDate(dateString: string): string {\n const date = new Date(dateString)\n const now = new Date()\n const diffMs = now.getTime() - date.getTime()\n const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24))\n\n if (diffDays === 0) {\n return date.toLocaleTimeString(\"en-US\", {\n hour: \"numeric\",\n minute: \"2-digit\",\n })\n }\n\n if (diffDays < 7) {\n return date.toLocaleDateString(\"en-US\", { weekday: \"short\" })\n }\n\n return date.toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n })\n}\n","/**\n * List Command\n *\n * Lists emails with pagination, numbering, and caching.\n * Cached list enables number-based access: `btcemail read 3`\n */\n\nimport ora from \"ora\"\nimport pc from \"picocolors\"\nimport { getEmails } from \"../api.js\"\nimport { isAuthenticated } from \"../config.js\"\nimport { type CachedEmail, cacheEmailList } from \"../utils/cache.js\"\n\nexport type ListOptions = {\n folder?: string\n limit?: number\n page?: number\n json?: boolean\n}\n\nexport async function listCommand(options: ListOptions): Promise<void> {\n if (!isAuthenticated()) {\n console.log(pc.yellow(\"Not logged in.\"))\n console.log(pc.dim(\"Run `btcemail login` to authenticate.\"))\n process.exit(1)\n }\n\n const folder = options.folder || \"inbox\"\n const limit = options.limit || 20\n const page = options.page || 1\n const offset = (page - 1) * limit\n\n const spinner = ora(\"Loading emails...\").start()\n\n const result = await getEmails({\n folder,\n limit,\n offset,\n })\n\n if (!result.ok) {\n spinner.fail(`Error: ${result.error.message}`)\n process.exit(1)\n }\n\n const { data: emails, pagination } = result.data\n\n spinner.stop()\n\n // Cache emails for number-based access\n const cachedEmails: CachedEmail[] = emails.map((e) => ({\n id: e.id,\n subject: e.subject,\n from: e.from.name || e.from.email,\n }))\n cacheEmailList(folder, cachedEmails)\n\n // JSON output mode\n if (options.json) {\n console.log(JSON.stringify({ emails, pagination }, null, 2))\n return\n }\n\n // Table output\n console.log()\n console.log(pc.bold(`${capitalize(folder)} (${pagination.total} emails)`))\n console.log()\n\n if (emails.length === 0) {\n console.log(pc.dim(\" No emails found.\"))\n console.log()\n return\n }\n\n // Header with # column\n console.log(\n ` ${pc.dim(\"#\".padEnd(4))} ${pc.dim(\"From\".padEnd(25))} ${pc.dim(\"Subject\".padEnd(45))} ${pc.dim(\"Date\")}`\n )\n console.log(pc.dim(` ${\"-\".repeat(85)}`))\n\n // Rows with numbering\n emails.forEach((email, index) => {\n const num = pc.cyan(String(index + 1).padEnd(4))\n const unreadMarker = email.unread ? pc.cyan(\"●\") : \" \"\n const from = truncate(email.from.name || email.from.email, 23).padEnd(25)\n const subject = truncate(email.subject, 43).padEnd(45)\n const date = formatDate(email.date)\n\n console.log(`${unreadMarker} ${num}${from} ${subject} ${pc.dim(date)}`)\n })\n\n console.log()\n\n // Pagination info\n const totalPages = Math.ceil(pagination.total / limit)\n const currentPage = page\n\n if (totalPages > 1) {\n console.log(\n pc.dim(` Page ${currentPage} of ${totalPages} (${emails.length} of ${pagination.total})`)\n )\n\n if (currentPage < totalPages) {\n console.log(pc.dim(` Next page: btcemail list --page ${currentPage + 1}`))\n }\n console.log()\n }\n\n // Hint for reading\n console.log(pc.dim(\" Read email: btcemail read <#> or btcemail read <id>\"))\n console.log()\n}\n\nfunction capitalize(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1)\n}\n\nfunction truncate(str: string, maxLength: number): string {\n if (str.length <= maxLength) return str\n return `${str.slice(0, maxLength - 1)}…`\n}\n\nfunction formatDate(dateString: string): string {\n const date = new Date(dateString)\n const now = new Date()\n const diffMs = now.getTime() - date.getTime()\n const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24))\n\n if (diffDays === 0) {\n return date.toLocaleTimeString(\"en-US\", {\n hour: \"numeric\",\n minute: \"2-digit\",\n })\n }\n\n if (diffDays < 7) {\n return date.toLocaleDateString(\"en-US\", { weekday: \"short\" })\n }\n\n return date.toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n })\n}\n","/**\n * Email Cache Utility\n *\n * Caches email lists for number-based selection (btcemail read 3).\n * Cache is per-folder and cleared on each new list command.\n */\n\nimport { config } from \"../config.js\"\n\nexport type CachedEmail = {\n id: string\n subject: string\n from: string\n}\n\nexport type EmailCache = {\n folder: string\n emails: CachedEmail[]\n timestamp: number\n}\n\nconst CACHE_KEY = \"emailCache\"\nconst CACHE_TTL_MS = 30 * 60 * 1000 // 30 minutes\n\n/**\n * Store email list for number-based access\n */\nexport function cacheEmailList(folder: string, emails: CachedEmail[]): void {\n config.set(CACHE_KEY, {\n folder,\n emails,\n timestamp: Date.now(),\n })\n}\n\n/**\n * Get cached email list if valid\n */\nexport function getCachedEmailList(folder?: string): EmailCache | null {\n const cache = config.get(CACHE_KEY) as EmailCache | undefined\n if (!cache) return null\n\n // Check if expired\n if (Date.now() - cache.timestamp > CACHE_TTL_MS) {\n config.delete(CACHE_KEY)\n return null\n }\n\n // Check folder match if specified\n if (folder && cache.folder !== folder) {\n return null\n }\n\n return cache\n}\n\n/**\n * Get email ID by index (1-based)\n * Returns null if not found or cache is invalid\n */\nexport function getEmailIdByIndex(index: number): string | null {\n const cache = getCachedEmailList()\n if (!cache) return null\n\n // Convert to 0-based index\n const idx = index - 1\n if (idx < 0 || idx >= cache.emails.length) {\n return null\n }\n\n return cache.emails[idx].id\n}\n\n/**\n * Check if ID is a number (for index-based access)\n */\nexport function isNumericId(id: string): boolean {\n return /^\\d+$/.test(id)\n}\n\n/**\n * Clear the email cache\n */\nexport function clearEmailCache(): void {\n config.delete(CACHE_KEY)\n}\n","/**\n * Login Command\n *\n * Implements polling-based browser authentication:\n * 1. Generate session_id\n * 2. Open browser to auth page\n * 3. Poll for tokens\n * 4. Store tokens in config\n */\n\nimport { randomUUID } from \"node:crypto\"\nimport open from \"open\"\nimport ora from \"ora\"\nimport pc from \"picocolors\"\nimport { getApiBaseUrl, setAuth } from \"../config.js\"\n\nconst POLL_INTERVAL_MS = 2000\nconst POLL_TIMEOUT_MS = 300000 // 5 minutes\n\ntype CLISessionResponse =\n | { status: \"pending\" }\n | {\n status: \"complete\"\n data: {\n token: string\n expiresAt: string\n userId: string\n email: string\n }\n }\n\nexport async function loginCommand(): Promise<void> {\n const sessionId = randomUUID()\n const baseUrl = getApiBaseUrl().replace(\"/api/v1\", \"\")\n const authUrl = `${baseUrl}/auth/cli?session_id=${sessionId}`\n const pollUrl = `${baseUrl}/api/auth/cli-session?session_id=${sessionId}`\n\n console.log()\n console.log(pc.bold(\"btc.email CLI Login\"))\n console.log()\n\n // Create pending session first\n try {\n const createResponse = await fetch(`${baseUrl}/api/auth/cli-session`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ session_id: sessionId }),\n })\n\n if (!createResponse.ok) {\n console.error(pc.red(\"Failed to initialize login session\"))\n process.exit(1)\n }\n } catch (error) {\n console.error(pc.red(\"Failed to connect to btc.email server\"))\n console.error(pc.dim(error instanceof Error ? error.message : \"Unknown error\"))\n process.exit(1)\n }\n\n // Open browser\n console.log(pc.dim(\"Opening browser for authentication...\"))\n console.log()\n console.log(pc.dim(\"If the browser doesn't open, visit:\"))\n console.log(pc.cyan(authUrl))\n console.log()\n\n try {\n await open(authUrl)\n } catch {\n // Browser open failed, user can use the URL\n }\n\n // Poll for tokens\n const spinner = ora(\"Waiting for authentication...\").start()\n const startTime = Date.now()\n\n while (Date.now() - startTime < POLL_TIMEOUT_MS) {\n try {\n const response = await fetch(pollUrl)\n\n if (response.status === 202) {\n // Still pending, continue polling\n await sleep(POLL_INTERVAL_MS)\n continue\n }\n\n if (response.status === 410) {\n spinner.fail(\"Session expired. Please try again.\")\n process.exit(1)\n }\n\n if (response.ok) {\n const data: CLISessionResponse = await response.json()\n\n if (data.status === \"complete\") {\n // Store tokens\n setAuth({\n token: data.data.token,\n expiresAt: data.data.expiresAt,\n userId: data.data.userId,\n email: data.data.email,\n })\n\n spinner.succeed(pc.green(\"Successfully logged in!\"))\n console.log()\n console.log(` ${pc.dim(\"Email:\")} ${data.data.email}`)\n console.log()\n console.log(pc.dim(\"You can now use btcemail commands.\"))\n console.log(pc.dim(\"Run `btcemail --help` to see available commands.\"))\n return\n }\n }\n\n await sleep(POLL_INTERVAL_MS)\n } catch (_error) {\n // Network error, continue polling\n await sleep(POLL_INTERVAL_MS)\n }\n }\n\n spinner.fail(\"Authentication timed out. Please try again.\")\n process.exit(1)\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n","/**\n * Logout Command\n *\n * Clears stored authentication tokens.\n */\n\nimport pc from \"picocolors\"\nimport { clearAuth, isAuthenticated } from \"../config.js\"\n\nexport async function logoutCommand(): Promise<void> {\n if (!isAuthenticated()) {\n console.log(pc.yellow(\"You are not logged in.\"))\n return\n }\n\n clearAuth()\n console.log(pc.green(\"Successfully logged out.\"))\n}\n","/**\n * Network command for btc.email CLI\n *\n * Switch between testnet and mainnet Lightning networks.\n */\n\nimport pc from \"picocolors\"\nimport { getNetwork, setNetwork } from \"../api.js\"\nimport { getToken } from \"../config.js\"\n\nexport interface NetworkShowOptions {\n json?: boolean\n}\n\nexport interface NetworkSwitchOptions {\n json?: boolean\n}\n\n/**\n * Show current network mode\n */\nexport async function networkShowCommand(options: NetworkShowOptions = {}) {\n const token = getToken()\n if (!token) {\n console.error(pc.red(\"Not logged in. Run 'btcemail login' first.\"))\n process.exit(1)\n }\n\n const result = await getNetwork()\n\n if (!result.ok) {\n console.error(pc.red(`Error: ${result.error.message}`))\n process.exit(1)\n }\n\n const { network_mode, networks } = result.data\n\n if (options.json) {\n console.log(JSON.stringify({ network_mode, networks }, null, 2))\n return\n }\n\n console.log()\n console.log(pc.bold(\"Network Mode\"))\n console.log()\n\n const isTestnet = network_mode === \"testnet\"\n const currentLabel = isTestnet\n ? pc.blue(\"testnet\") + pc.dim(\" (fake Bitcoin)\")\n : pc.red(\"mainnet\") + pc.dim(\" (real Bitcoin)\")\n\n console.log(` Current: ${currentLabel}`)\n console.log()\n console.log(pc.dim(\" Available networks:\"))\n console.log(\n ` testnet: ${networks.testnet.available ? pc.green(\"available\") : pc.red(\"unavailable\")}`\n )\n console.log(\n ` mainnet: ${networks.mainnet.available ? pc.green(\"available\") : pc.red(\"unavailable\")}`\n )\n console.log()\n\n if (!isTestnet) {\n console.log(pc.yellow(\" Warning: You are on mainnet. Payments use real Bitcoin!\"))\n console.log()\n }\n}\n\n/**\n * Switch network mode\n */\nexport async function networkSwitchCommand(network: string, options: NetworkSwitchOptions = {}) {\n const token = getToken()\n if (!token) {\n console.error(pc.red(\"Not logged in. Run 'btcemail login' first.\"))\n process.exit(1)\n }\n\n if (network !== \"testnet\" && network !== \"mainnet\") {\n console.error(pc.red(\"Invalid network. Use 'testnet' or 'mainnet'.\"))\n process.exit(1)\n }\n\n // Show warning for mainnet\n if (network === \"mainnet\") {\n console.log()\n console.log(pc.yellow(\"Warning: You are switching to mainnet.\"))\n console.log(pc.yellow(\"All payments will use real Bitcoin!\"))\n console.log()\n }\n\n const result = await setNetwork(network)\n\n if (!result.ok) {\n console.error(pc.red(`Error: ${result.error.message}`))\n process.exit(1)\n }\n\n if (options.json) {\n console.log(JSON.stringify({ success: true, network_mode: result.data.network_mode }, null, 2))\n return\n }\n\n const label = network === \"testnet\" ? pc.blue(\"testnet\") : pc.red(\"mainnet\")\n\n console.log(pc.green(`Switched to ${label}`))\n}\n","/**\n * Read Command\n *\n * Display a single email by ID or number (from cached list).\n * Supports: btcemail read 3 (number) or btcemail read abc123 (ID)\n */\n\nimport ora from \"ora\"\nimport pc from \"picocolors\"\nimport { getEmail } from \"../api.js\"\nimport { isAuthenticated } from \"../config.js\"\nimport { getCachedEmailList, getEmailIdByIndex, isNumericId } from \"../utils/cache.js\"\n\nexport type ReadOptions = {\n json?: boolean\n}\n\nexport async function readCommand(idOrNumber: string, options: ReadOptions): Promise<void> {\n if (!isAuthenticated()) {\n console.log(pc.yellow(\"Not logged in.\"))\n console.log(pc.dim(\"Run `btcemail login` to authenticate.\"))\n process.exit(1)\n }\n\n let emailId = idOrNumber\n\n // Check if this is a number reference\n if (isNumericId(idOrNumber)) {\n const index = parseInt(idOrNumber, 10)\n const cachedId = getEmailIdByIndex(index)\n\n if (cachedId) {\n emailId = cachedId\n } else {\n // Check if cache exists but index is out of range\n const cache = getCachedEmailList()\n if (cache) {\n console.error(pc.red(`Email #${index} not found in list.`))\n console.log(\n pc.dim(`List has ${cache.emails.length} emails. Run 'btcemail list' to refresh.`)\n )\n } else {\n console.error(pc.red(`No email list cached.`))\n console.log(pc.dim(`Run 'btcemail list' first, then use 'btcemail read <#>'.`))\n }\n process.exit(1)\n }\n }\n\n const spinner = ora(\"Loading email...\").start()\n\n const result = await getEmail(emailId)\n\n if (!result.ok) {\n if (result.error.code === \"NOT_FOUND\") {\n spinner.fail(`Email not found: ${emailId}`)\n } else {\n spinner.fail(`Error: ${result.error.message}`)\n }\n process.exit(1)\n }\n\n spinner.stop()\n\n const email = result.data\n\n // JSON output mode\n if (options.json) {\n console.log(JSON.stringify(email, null, 2))\n return\n }\n\n // Formatted output\n console.log()\n console.log(pc.bold(email.subject || \"(No subject)\"))\n console.log()\n console.log(`${pc.dim(\"From:\")} ${formatAddress(email.from)}`)\n console.log(`${pc.dim(\"To:\")} ${email.to.map(formatAddress).join(\", \")}`)\n console.log(`${pc.dim(\"Date:\")} ${formatFullDate(email.date)}`)\n console.log(`${pc.dim(\"ID:\")} ${email.id}`)\n\n if (email.labels.length > 0) {\n console.log(`${pc.dim(\"Labels:\")} ${email.labels.join(\", \")}`)\n }\n\n console.log()\n console.log(pc.dim(\"-\".repeat(60)))\n console.log()\n\n // Show full body if available, otherwise fall back to snippet\n const content = email.bodyText || email.body || email.snippet\n if (content) {\n // Strip HTML tags for plain text display if showing HTML body\n const displayContent = email.bodyText || stripHtml(email.body || email.snippet)\n console.log(displayContent)\n } else {\n console.log(pc.dim(\"(No content)\"))\n }\n console.log()\n}\n\nfunction stripHtml(html: string): string {\n // Basic HTML stripping for terminal display\n return html\n .replace(/<br\\s*\\/?>/gi, \"\\n\")\n .replace(/<\\/p>/gi, \"\\n\\n\")\n .replace(/<\\/div>/gi, \"\\n\")\n .replace(/<[^>]*>/g, \"\")\n .replace(/ /g, \" \")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/&/g, \"&\")\n .replace(/"/g, '\"')\n .trim()\n}\n\nfunction formatAddress(addr: { email: string; name?: string }): string {\n if (addr.name) {\n return `${addr.name} <${addr.email}>`\n }\n return addr.email\n}\n\nfunction formatFullDate(dateString: string): string {\n const date = new Date(dateString)\n return date.toLocaleString(\"en-US\", {\n weekday: \"short\",\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n })\n}\n","/**\n * Search Command\n *\n * Searches emails by subject, body, or sender.\n */\n\nimport ora from \"ora\"\nimport pc from \"picocolors\"\nimport { getEmails } from \"../api.js\"\nimport { isAuthenticated } from \"../config.js\"\nimport { type CachedEmail, cacheEmailList } from \"../utils/cache.js\"\n\nexport type SearchOptions = {\n limit?: number\n json?: boolean\n}\n\nexport async function searchCommand(query: string, options: SearchOptions): Promise<void> {\n if (!isAuthenticated()) {\n console.log(pc.yellow(\"Not logged in.\"))\n console.log(pc.dim(\"Run `btcemail login` to authenticate.\"))\n process.exit(1)\n }\n\n if (!query || query.trim().length === 0) {\n console.error(pc.red(\"Error: Search query is required\"))\n process.exit(1)\n }\n\n const spinner = ora(`Searching for \"${query}\"...`).start()\n\n const result = await getEmails({\n search: query.trim(),\n limit: options.limit || 20,\n })\n\n if (!result.ok) {\n spinner.fail(`Error: ${result.error.message}`)\n process.exit(1)\n }\n\n const { data: emails, pagination } = result.data\n\n spinner.stop()\n\n // Cache results for number-based access\n const cachedEmails: CachedEmail[] = emails.map((e) => ({\n id: e.id,\n subject: e.subject,\n from: e.from.name || e.from.email,\n }))\n cacheEmailList(\"search\", cachedEmails)\n\n // JSON output mode\n if (options.json) {\n console.log(JSON.stringify({ query, emails, pagination }, null, 2))\n return\n }\n\n // Table output\n console.log()\n console.log(pc.bold(`Search: \"${query}\" (${pagination.total} found)`))\n console.log()\n\n if (emails.length === 0) {\n console.log(pc.dim(\" No emails found matching your search.\"))\n console.log()\n return\n }\n\n // Header with # column\n console.log(\n ` ${pc.dim(\"#\".padEnd(4))} ${pc.dim(\"From\".padEnd(25))} ${pc.dim(\"Subject\".padEnd(45))} ${pc.dim(\"Date\")}`\n )\n console.log(pc.dim(` ${\"-\".repeat(85)}`))\n\n // Rows with numbering\n emails.forEach((email, index) => {\n const num = pc.cyan(String(index + 1).padEnd(4))\n const unreadMarker = email.unread ? pc.cyan(\"●\") : \" \"\n const from = truncate(email.from.name || email.from.email, 23).padEnd(25)\n const subject = truncate(email.subject, 43).padEnd(45)\n const date = formatDate(email.date)\n\n console.log(`${unreadMarker} ${num}${from} ${subject} ${pc.dim(date)}`)\n })\n\n console.log()\n\n if (pagination.hasMore) {\n console.log(\n pc.dim(` Showing ${emails.length} of ${pagination.total}. Use --limit to see more.`)\n )\n console.log()\n }\n\n console.log(pc.dim(\" Read email: btcemail read <#> or btcemail read <id>\"))\n console.log()\n}\n\nfunction truncate(str: string, maxLength: number): string {\n if (str.length <= maxLength) return str\n return `${str.slice(0, maxLength - 1)}…`\n}\n\nfunction formatDate(dateString: string): string {\n const date = new Date(dateString)\n const now = new Date()\n const diffMs = now.getTime() - date.getTime()\n const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24))\n\n if (diffDays === 0) {\n return date.toLocaleTimeString(\"en-US\", {\n hour: \"numeric\",\n minute: \"2-digit\",\n })\n }\n\n if (diffDays < 7) {\n return date.toLocaleDateString(\"en-US\", { weekday: \"short\" })\n }\n\n return date.toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n })\n}\n","/**\n * Send Command\n *\n * Compose and send an email with L402 payment flow.\n * Supports --wait to poll for payment confirmation.\n */\n\nimport ora from \"ora\"\nimport pc from \"picocolors\"\nimport qrcode from \"qrcode-terminal\"\nimport { checkPaymentStatus, getL402Invoice, getWhoami, sendEmail } from \"../api.js\"\nimport { getAuth, isAuthenticated } from \"../config.js\"\nimport { pollForPayment } from \"../utils/payment-polling.js\"\n\nexport type SendOptions = {\n to?: string\n subject?: string\n body?: string\n fromEmail?: string\n paymentHash?: string\n wait?: boolean\n}\n\nexport async function sendCommand(options: SendOptions): Promise<void> {\n if (!isAuthenticated()) {\n console.log(pc.yellow(\"Not logged in.\"))\n console.log(pc.dim(\"Run `btcemail login` to authenticate.\"))\n process.exit(1)\n }\n\n // Get user's email address\n let fromEmail = options.fromEmail\n if (!fromEmail) {\n const spinner = ora(\"Fetching account info...\").start()\n const whoamiResult = await getWhoami()\n spinner.stop()\n\n if (whoamiResult.ok && whoamiResult.data.username) {\n // API returns username with @btc.email suffix already\n fromEmail = whoamiResult.data.username\n } else {\n const auth = getAuth()\n if (auth?.email?.endsWith(\"@btc.email\")) {\n fromEmail = auth.email\n }\n }\n }\n\n if (!fromEmail || !fromEmail.endsWith(\"@btc.email\")) {\n console.error(pc.red(\"No @btc.email address found.\"))\n console.log(pc.dim(\"Register a username at https://btc.email\"))\n process.exit(1)\n }\n\n // Validate required fields\n if (!options.to) {\n console.error(pc.red(\"Recipient is required. Use --to <email>\"))\n process.exit(1)\n }\n\n if (!options.subject) {\n console.error(pc.red(\"Subject is required. Use --subject <text>\"))\n process.exit(1)\n }\n\n if (!options.body) {\n console.error(pc.red(\"Body is required. Use --body <text>\"))\n process.exit(1)\n }\n\n const toEmails = options.to.split(\",\").map((e) => e.trim())\n\n console.log()\n console.log(pc.bold(\"Sending Email\"))\n console.log()\n console.log(`${pc.dim(\"From:\")} ${fromEmail}`)\n console.log(`${pc.dim(\"To:\")} ${toEmails.join(\", \")}`)\n console.log(`${pc.dim(\"Subject:\")} ${options.subject}`)\n console.log()\n\n // If no payment hash provided, check if payment is required\n if (!options.paymentHash) {\n const spinner = ora(\"Getting invoice...\").start()\n const invoiceResult = await getL402Invoice({\n fromEmail,\n toEmails,\n })\n spinner.stop()\n\n if (invoiceResult.ok && invoiceResult.data.amountSats > 0) {\n // Payment required\n const invoice = invoiceResult.data\n console.log(pc.yellow(`Payment required: ${invoice.amountSats} sats`))\n console.log()\n\n // Display QR code\n console.log(pc.bold(\"Scan to pay:\"))\n console.log()\n qrcode.generate(invoice.invoice, { small: true }, (qr) => {\n const indentedQr = qr\n .split(\"\\n\")\n .map((line) => ` ${line}`)\n .join(\"\\n\")\n console.log(indentedQr)\n })\n console.log()\n\n console.log(pc.dim(\"Lightning Invoice:\"))\n console.log(pc.cyan(invoice.invoice))\n console.log()\n\n // If --wait flag is set, poll for payment\n if (options.wait) {\n const status = await pollForPayment({\n paymentHash: invoice.paymentHash,\n checkFn: async (hash) => {\n const result = await checkPaymentStatus(hash)\n if (result.ok) {\n return { paid: result.data.paid }\n }\n return { paid: false }\n },\n })\n\n if (status.paid) {\n // Payment received, now send the email\n const sendSpinner = ora(\"Sending email...\").start()\n const result = await sendEmail({\n to: toEmails,\n subject: options.subject,\n body: options.body,\n fromEmail,\n paymentHash: invoice.paymentHash,\n })\n\n if (!result.ok) {\n sendSpinner.fail(`Error: ${result.error.message}`)\n process.exit(1)\n }\n\n sendSpinner.succeed(\"Email sent!\")\n console.log()\n console.log(`${pc.dim(\"Email ID:\")} ${result.data.emailId}`)\n if (result.data.messageId) {\n console.log(`${pc.dim(\"Message ID:\")} ${result.data.messageId}`)\n }\n console.log()\n } else {\n console.log(\n pc.dim(\"Payment not confirmed. You can still pay and resend with --payment-hash.\")\n )\n }\n return\n }\n\n console.log(pc.dim(\"Pay this invoice with your Lightning wallet, then run:\"))\n console.log(\n pc.cyan(\n ` btcemail send --to \"${options.to}\" --subject \"${options.subject}\" --body \"${options.body}\" --payment-hash ${invoice.paymentHash}`\n )\n )\n console.log()\n console.log(pc.dim(\"Or use --wait to automatically wait for payment.\"))\n console.log()\n return\n }\n }\n\n // Send email (with payment hash if provided)\n const spinner = ora(\"Sending email...\").start()\n const result = await sendEmail({\n to: toEmails,\n subject: options.subject,\n body: options.body,\n fromEmail,\n paymentHash: options.paymentHash,\n })\n\n if (!result.ok) {\n if (result.error.code === \"PAYMENT_REQUIRED\") {\n spinner.fail(\"Payment required to send this email.\")\n console.log(pc.dim(\"Use the invoice above to pay, then include --payment-hash\"))\n } else {\n spinner.fail(`Error: ${result.error.message}`)\n }\n process.exit(1)\n }\n\n spinner.succeed(\"Email sent!\")\n console.log()\n console.log(`${pc.dim(\"Email ID:\")} ${result.data.emailId}`)\n if (result.data.messageId) {\n console.log(`${pc.dim(\"Message ID:\")} ${result.data.messageId}`)\n }\n console.log()\n}\n\nexport type SendWithPaymentOptions = SendOptions & {\n paymentHash?: string\n}\n\nexport async function sendWithPaymentCommand(options: SendWithPaymentOptions): Promise<void> {\n if (!isAuthenticated()) {\n console.log(pc.yellow(\"Not logged in.\"))\n console.log(pc.dim(\"Run `btcemail login` to authenticate.\"))\n process.exit(1)\n }\n\n // Get user's email address\n let fromEmail = options.fromEmail\n if (!fromEmail) {\n const whoamiResult = await getWhoami()\n if (whoamiResult.ok && whoamiResult.data.username) {\n // API returns username with @btc.email suffix already\n fromEmail = whoamiResult.data.username\n }\n }\n\n if (!fromEmail || !fromEmail.endsWith(\"@btc.email\")) {\n console.error(pc.red(\"No @btc.email address found.\"))\n process.exit(1)\n }\n\n if (!options.to || !options.subject || !options.body) {\n console.error(pc.red(\"Missing required fields: --to, --subject, --body\"))\n process.exit(1)\n }\n\n const toEmails = options.to.split(\",\").map((e) => e.trim())\n\n const result = await sendEmail({\n to: toEmails,\n subject: options.subject,\n body: options.body,\n fromEmail,\n paymentHash: options.paymentHash,\n })\n\n if (!result.ok) {\n console.error(pc.red(`Error: ${result.error.message}`))\n process.exit(1)\n }\n\n console.log()\n console.log(pc.green(\"Email sent successfully!\"))\n console.log()\n console.log(`${pc.dim(\"Email ID:\")} ${result.data.emailId}`)\n console.log()\n}\n","/**\n * Settings command for btc.email CLI\n *\n * Manage email pricing, toggles, and auto-reply settings.\n */\n\nimport pc from \"picocolors\"\nimport { getSettings, updateSettings } from \"../api.js\"\nimport { getToken } from \"../config.js\"\n\nexport interface SettingsOptions {\n username?: string\n json?: boolean\n}\n\nexport interface SettingsPricingOptions {\n username?: string\n json?: boolean\n}\n\nexport interface SettingsToggleOptions {\n username?: string\n}\n\nexport interface SettingsAutoReplyOptions {\n username?: string\n clear?: boolean\n}\n\n/**\n * Show current settings\n */\nexport async function settingsShowCommand(options: SettingsOptions = {}) {\n const token = getToken()\n if (!token) {\n console.error(pc.red(\"Not logged in. Run 'btcemail login' first.\"))\n process.exit(1)\n }\n\n const result = await getSettings(options.username)\n\n if (!result.ok) {\n console.error(pc.red(`Error: ${result.error.message}`))\n process.exit(1)\n }\n\n const { username, usernames, settings } = result.data\n\n if (options.json) {\n console.log(JSON.stringify({ username, usernames, settings }, null, 2))\n return\n }\n\n console.log()\n console.log(pc.bold(\"Settings for \") + pc.cyan(`${username}@btc.email`))\n if (usernames.length > 1) {\n console.log(pc.dim(`(You have ${usernames.length} addresses: ${usernames.join(\", \")})`))\n }\n console.log()\n console.log(pc.dim(\"Pricing:\"))\n console.log(` Email price: ${pc.yellow(settings.default_price_sats.toLocaleString())} sats`)\n console.log()\n console.log(pc.dim(\"Toggles:\"))\n console.log(\n ` Require payment: ${settings.require_payment_from_unknown ? pc.green(\"on\") : pc.red(\"off\")}`\n )\n console.log(\n ` Auto-whitelist: ${settings.auto_whitelist_on_payment ? pc.green(\"on\") : pc.red(\"off\")}`\n )\n console.log()\n console.log(pc.dim(\"Auto-reply:\"))\n if (settings.custom_auto_reply_body) {\n console.log(` ${pc.italic(settings.custom_auto_reply_body)}`)\n } else {\n console.log(` ${pc.dim(\"(default message)\")}`)\n }\n console.log()\n}\n\n/**\n * Set email pricing\n */\nexport async function settingsPricingCommand(sats: string, options: SettingsPricingOptions = {}) {\n const token = getToken()\n if (!token) {\n console.error(pc.red(\"Not logged in. Run 'btcemail login' first.\"))\n process.exit(1)\n }\n\n const price = parseInt(sats, 10)\n if (Number.isNaN(price) || price < 0) {\n console.error(pc.red(\"Invalid price. Must be a non-negative number.\"))\n process.exit(1)\n }\n\n const result = await updateSettings({ default_price_sats: price }, options.username)\n\n if (!result.ok) {\n console.error(pc.red(`Error: ${result.error.message}`))\n process.exit(1)\n }\n\n if (options.json) {\n console.log(JSON.stringify({ success: true, price }, null, 2))\n return\n }\n\n console.log(pc.green(`Email price set to ${pc.yellow(price.toLocaleString())} sats`))\n}\n\n/**\n * Toggle require-payment setting\n */\nexport async function settingsRequirePaymentCommand(\n value: string,\n options: SettingsToggleOptions = {}\n) {\n const token = getToken()\n if (!token) {\n console.error(pc.red(\"Not logged in. Run 'btcemail login' first.\"))\n process.exit(1)\n }\n\n const enabled = value.toLowerCase() === \"on\" || value === \"true\" || value === \"1\"\n const disabled = value.toLowerCase() === \"off\" || value === \"false\" || value === \"0\"\n\n if (!enabled && !disabled) {\n console.error(pc.red(\"Invalid value. Use 'on' or 'off'.\"))\n process.exit(1)\n }\n\n const result = await updateSettings({ require_payment_from_unknown: enabled }, options.username)\n\n if (!result.ok) {\n console.error(pc.red(`Error: ${result.error.message}`))\n process.exit(1)\n }\n\n console.log(pc.green(`Require payment: ${enabled ? pc.green(\"on\") : pc.red(\"off\")}`))\n}\n\n/**\n * Toggle auto-whitelist setting\n */\nexport async function settingsAutoWhitelistCommand(\n value: string,\n options: SettingsToggleOptions = {}\n) {\n const token = getToken()\n if (!token) {\n console.error(pc.red(\"Not logged in. Run 'btcemail login' first.\"))\n process.exit(1)\n }\n\n const enabled = value.toLowerCase() === \"on\" || value === \"true\" || value === \"1\"\n const disabled = value.toLowerCase() === \"off\" || value === \"false\" || value === \"0\"\n\n if (!enabled && !disabled) {\n console.error(pc.red(\"Invalid value. Use 'on' or 'off'.\"))\n process.exit(1)\n }\n\n const result = await updateSettings({ auto_whitelist_on_payment: enabled }, options.username)\n\n if (!result.ok) {\n console.error(pc.red(`Error: ${result.error.message}`))\n process.exit(1)\n }\n\n console.log(pc.green(`Auto-whitelist: ${enabled ? pc.green(\"on\") : pc.red(\"off\")}`))\n}\n\n/**\n * Set auto-reply message\n */\nexport async function settingsAutoReplyCommand(\n message: string | undefined,\n options: SettingsAutoReplyOptions = {}\n) {\n const token = getToken()\n if (!token) {\n console.error(pc.red(\"Not logged in. Run 'btcemail login' first.\"))\n process.exit(1)\n }\n\n const newMessage = options.clear ? null : message || null\n\n const result = await updateSettings({ custom_auto_reply_body: newMessage }, options.username)\n\n if (!result.ok) {\n console.error(pc.red(`Error: ${result.error.message}`))\n process.exit(1)\n }\n\n if (options.clear) {\n console.log(pc.green(\"Auto-reply reset to default message\"))\n } else if (newMessage) {\n console.log(pc.green(\"Auto-reply message updated\"))\n } else {\n console.log(pc.yellow(\"No message provided. Use --clear to reset to default.\"))\n }\n}\n","/**\n * Stats command for btc.email CLI\n *\n * Show dashboard overview statistics.\n */\n\nimport pc from \"picocolors\"\nimport { getStats } from \"../api.js\"\nimport { getToken } from \"../config.js\"\n\nexport interface StatsOptions {\n json?: boolean\n}\n\n/**\n * Show dashboard statistics\n */\nexport async function statsCommand(options: StatsOptions = {}) {\n const token = getToken()\n if (!token) {\n console.error(pc.red(\"Not logged in. Run 'btcemail login' first.\"))\n process.exit(1)\n }\n\n const result = await getStats()\n\n if (!result.ok) {\n console.error(pc.red(`Error: ${result.error.message}`))\n process.exit(1)\n }\n\n const { totalReceived, totalSent, pendingCount, addressCount, usernames } = result.data\n\n if (options.json) {\n console.log(JSON.stringify(result.data, null, 2))\n return\n }\n\n console.log()\n console.log(pc.bold(\"Dashboard Statistics\"))\n console.log()\n console.log(` Total Received: ${pc.green(`+${totalReceived.toLocaleString()}`)} sats`)\n console.log(` Total Sent: ${pc.yellow(`-${totalSent.toLocaleString()}`)} sats`)\n console.log(` Pending Emails: ${pendingCount > 0 ? pc.yellow(pendingCount) : pc.dim(\"0\")}`)\n console.log(` Active Addresses: ${addressCount}`)\n console.log()\n\n if (usernames.length > 0) {\n console.log(pc.dim(\" Your addresses:\"))\n for (const username of usernames) {\n console.log(` ${pc.cyan(username)}@btc.email`)\n }\n console.log()\n }\n\n if (pendingCount > 0) {\n console.log(pc.dim(\" View pending emails: btcemail inbound pending\"))\n console.log()\n }\n}\n","/**\n * Whitelist command for btc.email CLI\n *\n * Manage senders who can email you for free.\n */\n\nimport pc from \"picocolors\"\nimport { addToWhitelist, getWhitelist, removeFromWhitelist } from \"../api.js\"\nimport { getToken } from \"../config.js\"\n\nexport interface WhitelistListOptions {\n username?: string\n json?: boolean\n}\n\nexport interface WhitelistAddOptions {\n username?: string\n note?: string\n json?: boolean\n}\n\nexport interface WhitelistRemoveOptions {\n json?: boolean\n}\n\n/**\n * List whitelist entries\n */\nexport async function whitelistListCommand(options: WhitelistListOptions = {}) {\n const token = getToken()\n if (!token) {\n console.error(pc.red(\"Not logged in. Run 'btcemail login' first.\"))\n process.exit(1)\n }\n\n const result = await getWhitelist(options.username)\n\n if (!result.ok) {\n console.error(pc.red(`Error: ${result.error.message}`))\n process.exit(1)\n }\n\n const { username, entries } = result.data\n\n if (options.json) {\n console.log(JSON.stringify({ username, entries }, null, 2))\n return\n }\n\n console.log()\n console.log(pc.bold(\"Whitelist for \") + pc.cyan(`${username}@btc.email`))\n console.log()\n\n if (entries.length === 0) {\n console.log(pc.dim(\" No entries in whitelist.\"))\n console.log()\n console.log(pc.dim(\" Add entries with: btcemail whitelist add <email>\"))\n console.log(pc.dim(\" Or for domains: btcemail whitelist add @domain.com\"))\n console.log()\n return\n }\n\n console.log(pc.dim(` ${entries.length} ${entries.length === 1 ? \"entry\" : \"entries\"}:`))\n console.log()\n\n for (const entry of entries) {\n const value = entry.sender_email || `@${entry.sender_domain}`\n const via = entry.added_via !== \"manual\" ? pc.dim(` (via ${entry.added_via})`) : \"\"\n const note = entry.note ? pc.dim(` - ${entry.note}`) : \"\"\n console.log(` ${pc.green(value)}${via}${note}`)\n console.log(pc.dim(` ID: ${entry.id}`))\n }\n console.log()\n}\n\n/**\n * Add entry to whitelist\n */\nexport async function whitelistAddCommand(entry: string, options: WhitelistAddOptions = {}) {\n const token = getToken()\n if (!token) {\n console.error(pc.red(\"Not logged in. Run 'btcemail login' first.\"))\n process.exit(1)\n }\n\n // Check if it's a domain (starts with @)\n const isDomain = entry.startsWith(\"@\")\n const payload = isDomain\n ? { domain: entry.slice(1), note: options.note }\n : { email: entry, note: options.note }\n\n const result = await addToWhitelist(payload, options.username)\n\n if (!result.ok) {\n console.error(pc.red(`Error: ${result.error.message}`))\n process.exit(1)\n }\n\n if (options.json) {\n console.log(JSON.stringify({ success: true, entry: result.data.entry }, null, 2))\n return\n }\n\n console.log(pc.green(`Added to whitelist: ${pc.cyan(entry)}`))\n}\n\n/**\n * Remove entry from whitelist\n */\nexport async function whitelistRemoveCommand(id: string, options: WhitelistRemoveOptions = {}) {\n const token = getToken()\n if (!token) {\n console.error(pc.red(\"Not logged in. Run 'btcemail login' first.\"))\n process.exit(1)\n }\n\n const result = await removeFromWhitelist(id)\n\n if (!result.ok) {\n console.error(pc.red(`Error: ${result.error.message}`))\n process.exit(1)\n }\n\n if (options.json) {\n console.log(JSON.stringify({ success: true }, null, 2))\n return\n }\n\n console.log(pc.green(\"Removed from whitelist\"))\n}\n","/**\n * Whoami Command\n *\n * Shows current authenticated user info.\n */\n\nimport ora from \"ora\"\nimport pc from \"picocolors\"\nimport { getWhoami } from \"../api.js\"\nimport { getAuth, getTokenExpiryInfo, isAuthenticated, isTokenExpiringSoon } from \"../config.js\"\n\nexport async function whoamiCommand(): Promise<void> {\n if (!isAuthenticated()) {\n console.log(pc.yellow(\"Not logged in.\"))\n console.log(pc.dim(\"Run `btcemail login` to authenticate.\"))\n process.exit(1)\n }\n\n const auth = getAuth()\n if (!auth) {\n console.log(pc.yellow(\"Not logged in.\"))\n process.exit(1)\n }\n\n const spinner = ora(\"Fetching account info...\").start()\n\n // Try to get fresh info from API\n const result = await getWhoami()\n\n spinner.stop()\n\n if (result.ok) {\n console.log()\n console.log(pc.bold(\"Current User\"))\n console.log()\n console.log(` ${pc.dim(\"Email:\")} ${result.data.email}`)\n if (result.data.username) {\n console.log(` ${pc.dim(\"Username:\")} ${result.data.username}@btc.email`)\n }\n console.log(` ${pc.dim(\"User ID:\")} ${result.data.id}`)\n\n // Show token expiry info\n const expiryInfo = getTokenExpiryInfo()\n if (expiryInfo.expiresIn) {\n const expiryColor = isTokenExpiringSoon() ? pc.yellow : pc.dim\n console.log(` ${pc.dim(\"Session:\")} ${expiryColor(`expires in ${expiryInfo.expiresIn}`)}`)\n }\n console.log()\n\n if (isTokenExpiringSoon()) {\n console.log(pc.yellow(\"Session expiring soon. Run `btcemail login` to refresh.\"))\n console.log()\n }\n } else {\n // Fall back to cached info\n console.log()\n console.log(pc.bold(\"Current User\") + pc.dim(\" (cached)\"))\n console.log()\n console.log(` ${pc.dim(\"Email:\")} ${auth.email}`)\n console.log(` ${pc.dim(\"User ID:\")} ${auth.userId}`)\n console.log()\n\n if (result.error.code === \"UNAUTHENTICATED\" || result.error.code === \"UNAUTHORIZED\") {\n console.log(pc.yellow(\"Session expired. Run `btcemail login` to re-authenticate.\"))\n }\n }\n}\n"],"mappings":"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","names":["pc","whitelist","settings","network","pc","pc","pc","result","ora","pc","pc","ora","formatDate","ora","pc","pc","ora","truncate","formatDate","ora","pc","pc","ora","sleep","pc","pc","pc","pc","network","ora","pc","pc","ora","formatAddress","formatFullDate","ora","pc","pc","ora","truncate","formatDate","ora","pc","qrcode","pc","spinner","ora","qrcode","result","pc","pc","settings","pc","pc","pc","pc","ora","pc","pc","ora","pc"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@btcemail/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "btc.email CLI - Spam-free email powered by Bitcoin Lightning",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -17,7 +17,13 @@
|
|
|
17
17
|
"build": "tsup",
|
|
18
18
|
"dev": "tsup --watch",
|
|
19
19
|
"start": "node dist/index.js",
|
|
20
|
-
"typecheck": "tsc --noEmit"
|
|
20
|
+
"typecheck": "tsc --noEmit",
|
|
21
|
+
"compile": "bun run build && bun run compile:all",
|
|
22
|
+
"compile:all": "bun run compile:darwin-arm64 && bun run compile:darwin-x64 && bun run compile:linux-x64 && bun run compile:windows-x64",
|
|
23
|
+
"compile:darwin-arm64": "bun build --compile --target=bun-darwin-arm64 ./dist/index.js --outfile ./bin/btcemail-darwin-arm64",
|
|
24
|
+
"compile:darwin-x64": "bun build --compile --target=bun-darwin-x64 ./dist/index.js --outfile ./bin/btcemail-darwin-x64",
|
|
25
|
+
"compile:linux-x64": "bun build --compile --target=bun-linux-x64 ./dist/index.js --outfile ./bin/btcemail-linux-x64",
|
|
26
|
+
"compile:windows-x64": "bun build --compile --target=bun-windows-x64 ./dist/index.js --outfile ./bin/btcemail-windows-x64.exe"
|
|
21
27
|
},
|
|
22
28
|
"keywords": [
|
|
23
29
|
"btc.email",
|
|
@@ -38,15 +44,15 @@
|
|
|
38
44
|
"directory": "packages/cli"
|
|
39
45
|
},
|
|
40
46
|
"dependencies": {
|
|
41
|
-
"commander": "
|
|
42
|
-
"conf": "
|
|
43
|
-
"open": "
|
|
44
|
-
"ora": "
|
|
47
|
+
"commander": "14.0.2",
|
|
48
|
+
"conf": "15.0.2",
|
|
49
|
+
"open": "11.0.0",
|
|
50
|
+
"ora": "9.0.0",
|
|
45
51
|
"picocolors": "^1.1.1",
|
|
46
52
|
"qrcode-terminal": "0.12.0"
|
|
47
53
|
},
|
|
48
54
|
"devDependencies": {
|
|
49
|
-
"@types/node": "
|
|
55
|
+
"@types/node": "25.0.3",
|
|
50
56
|
"@types/qrcode-terminal": "0.12.2",
|
|
51
57
|
"tsup": "^8.3.5",
|
|
52
58
|
"typescript": "^5.7.2"
|