lightning-wallet-mcp 1.3.2 → 1.4.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 CHANGED
@@ -2,10 +2,24 @@
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/lightning-wallet-mcp.svg)](https://www.npmjs.com/package/lightning-wallet-mcp)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
- [![lightning-wallet-mcp MCP server](https://glama.ai/mcp/servers/lightningfaucet/lightning-wallet-mcp/badges/score.svg)](https://glama.ai/mcp/servers/lightningfaucet/lightning-wallet-mcp)
5
+ [![Glama MCP Server](https://img.shields.io/badge/glama.ai-MCP%20server-1ee495?logo=githubsponsors&logoColor=1ee495&labelColor=0a0a0a)](https://glama.ai/mcp/servers/lightningfaucet/lightning-wallet-mcp)
6
6
 
7
7
  **Give your AI agent a Bitcoin wallet.** MCP server + CLI. Works with Claude Code, OpenClaw, Cursor, and any agent framework.
8
8
 
9
+ ## What's New in v1.4
10
+
11
+ - **`update_operator` tool / `lw set-email`** - set your operator email from the MCP client or CLI; a verification link is emailed to you.
12
+ - **`claim_promo` tool / `lw claim-promo`** - claim the free-sats install promo directly from your agent. Requirements: verified email + operator account at least 24 hours old.
13
+ - **`get_info` works before registration** - service info no longer requires an API key.
14
+
15
+ ### Free 100 sats for new operators
16
+
17
+ 1. `lw register --email you@example.com` (or the `register_operator` MCP tool with an email)
18
+ 2. Click the verification link we email you
19
+ 3. After your account is 24 hours old: `lw claim-promo` (or the `claim_promo` MCP tool)
20
+
21
+ One bonus per operator, first 100 installs only, no deposit required.
22
+
9
23
  ## What's New in v1.3
10
24
 
11
25
  **v1.3.0** - L402 protocol v0 support per the latest Lightning Labs spec.
@@ -159,6 +173,9 @@ Then ask Claude: *"Register a new Lightning Wallet operator account"*
159
173
  | `withdraw` | Withdraw funds to external Lightning destination |
160
174
  | `set_operator_key` | Switch to operator credentials |
161
175
 
176
+ - `update_operator` - set operator email (sends verification link) and/or name
177
+ - `claim_promo` - claim the free-sats install promo (verified email + 24h account)
178
+
162
179
  ### Agent Management
163
180
 
164
181
  | Tool | Description |
package/dist/cli.js CHANGED
@@ -10,7 +10,7 @@
10
10
  */
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  const lightning_faucet_js_1 = require("./lightning-faucet.js");
13
- const VERSION = '1.1.0';
13
+ const VERSION = '1.4.0';
14
14
  // --- Helpers ---
15
15
  function getApiKey() {
16
16
  const key = process.env.LIGHTNING_WALLET_API_KEY;
@@ -256,9 +256,22 @@ async function cmdTransactions(flags) {
256
256
  has_more: result.has_more,
257
257
  };
258
258
  }
259
- async function cmdInfo() {
259
+ async function cmdSetEmail(positional) {
260
+ const email = positional[0];
261
+ if (!email)
262
+ error('Usage: lw set-email <email>');
263
+ const client = getClient();
264
+ return client.updateOperator({ email });
265
+ }
266
+ async function cmdClaimPromo() {
260
267
  const client = getClient();
261
- const result = await client.getInfo();
268
+ return client.claimPromo();
269
+ }
270
+ async function cmdInfo() {
271
+ // Service info is public - works with or without an API key
272
+ const result = process.env.LIGHTNING_WALLET_API_KEY
273
+ ? await getClient().getInfo()
274
+ : await (0, lightning_faucet_js_1.getPublicInfo)();
262
275
  return {
263
276
  version: result.version,
264
277
  api_version: result.apiVersion,
@@ -316,6 +329,9 @@ COMMANDS
316
329
  list-agents | agents List all agents
317
330
 
318
331
  transactions Recent transactions [--limit 10] [--offset 0]
332
+ set-email <email> Set operator email (verification link emailed)
333
+ claim-promo Claim the 100-sat install promo
334
+ (requires verified email + 24h account age)
319
335
  help Show this help
320
336
 
321
337
  WEBHOOKS
@@ -404,6 +420,12 @@ async function main() {
404
420
  case 'transactions':
405
421
  result = await cmdTransactions(flags);
406
422
  break;
423
+ case 'set-email':
424
+ result = await cmdSetEmail(positional);
425
+ break;
426
+ case 'claim-promo':
427
+ result = await cmdClaimPromo();
428
+ break;
407
429
  case 'info':
408
430
  result = await cmdInfo();
409
431
  break;
package/dist/index.js CHANGED
@@ -119,6 +119,13 @@ const FundAgentSchema = zod_1.z.object({
119
119
  amount_sats: zod_1.z.number().int().min(1).max(10_000_000).describe('Amount in satoshis to transfer'),
120
120
  });
121
121
  const ListAgentsSchema = zod_1.z.object({});
122
+ const UpdateOperatorSchema = zod_1.z.object({
123
+ email: zod_1.z.string().email().optional(),
124
+ name: zod_1.z.string().min(1).max(100).optional(),
125
+ });
126
+ const ClaimPromoSchema = zod_1.z.object({
127
+ promo_code: zod_1.z.string().optional(),
128
+ });
122
129
  const SetOperatorKeySchema = zod_1.z.object({
123
130
  api_key: zod_1.z.string().min(10, 'API key is too short').max(200, 'API key is too long')
124
131
  .describe('The operator API key to use for subsequent requests'),
@@ -343,6 +350,29 @@ server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => ({
343
350
  required: [],
344
351
  },
345
352
  },
353
+ {
354
+ name: 'update_operator',
355
+ description: 'Update operator profile: set your email (sends a verification link - required for the free-sats promo) and/or display name. REQUIRES OPERATOR KEY.',
356
+ inputSchema: {
357
+ type: 'object',
358
+ properties: {
359
+ email: { type: 'string', description: 'Email address to set. A verification link is emailed; click it to verify.' },
360
+ name: { type: 'string', description: 'Display name for the operator account' },
361
+ },
362
+ required: [],
363
+ },
364
+ },
365
+ {
366
+ name: 'claim_promo',
367
+ description: 'Claim the free-sats install promo (100 sats, first 100 installs). Requires a verified email (set one with update_operator, then click the emailed link) and an operator account at least 24 hours old. REQUIRES OPERATOR KEY.',
368
+ inputSchema: {
369
+ type: 'object',
370
+ properties: {
371
+ promo_code: { type: 'string', description: "Promo code (default: 'first_100_installs')" },
372
+ },
373
+ required: [],
374
+ },
375
+ },
346
376
  {
347
377
  name: 'get_deposit_invoice',
348
378
  description: 'Create a Lightning invoice to fund your operator account. Pay this invoice to add sats to your balance.',
@@ -943,6 +973,38 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
943
973
  ],
944
974
  };
945
975
  }
976
+ case 'update_operator': {
977
+ const parsed = UpdateOperatorSchema.parse(args);
978
+ if (parsed.email === undefined && parsed.name === undefined) {
979
+ throw new Error('Provide email and/or name to update.');
980
+ }
981
+ const result = await session.requireClient().updateOperator(parsed);
982
+ return {
983
+ content: [
984
+ {
985
+ type: 'text',
986
+ text: JSON.stringify({
987
+ success: result.success !== false,
988
+ message: result.message || 'Operator updated',
989
+ updated_fields: result.updated_fields,
990
+ email_verification: result.email_verification,
991
+ }, null, 2),
992
+ },
993
+ ],
994
+ };
995
+ }
996
+ case 'claim_promo': {
997
+ const parsed = ClaimPromoSchema.parse(args);
998
+ const result = await session.requireClient().claimPromo(parsed.promo_code);
999
+ return {
1000
+ content: [
1001
+ {
1002
+ type: 'text',
1003
+ text: JSON.stringify(result, null, 2),
1004
+ },
1005
+ ],
1006
+ };
1007
+ }
946
1008
  case 'get_deposit_invoice': {
947
1009
  const parsed = GetDepositInvoiceSchema.parse(args);
948
1010
  const result = await session.requireClient().getDepositInvoice(parsed.amount_sats);
@@ -1263,7 +1325,15 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
1263
1325
  // ==========================================
1264
1326
  case 'get_info': {
1265
1327
  GetInfoSchema.parse(args);
1266
- const result = await session.requireClient().getInfo();
1328
+ // Service info is public - fall back to an unauthenticated request so
1329
+ // first-run users can check the service before registering.
1330
+ let result;
1331
+ try {
1332
+ result = await session.requireClient().getInfo();
1333
+ }
1334
+ catch {
1335
+ result = await (0, lightning_faucet_js_1.getPublicInfo)();
1336
+ }
1267
1337
  return {
1268
1338
  content: [
1269
1339
  {
@@ -513,10 +513,40 @@ export declare class LightningFaucetClient {
513
513
  * Vote on a post
514
514
  */
515
515
  boardVote(postId: number, direction: string): Promise<Record<string, unknown>>;
516
+ /**
517
+ * Update operator profile (email and/or name). Setting an email sends a
518
+ * verification link - a verified email is required for the free-sats promo.
519
+ */
520
+ updateOperator(opts: {
521
+ email?: string;
522
+ name?: string;
523
+ }): Promise<ApiResponse & {
524
+ message?: string;
525
+ updated_fields?: string[];
526
+ email_verification?: string;
527
+ }>;
528
+ /**
529
+ * Claim a promo bonus (default: the first_100_installs free-sats promo).
530
+ * Requires a verified email and an operator account at least 24 hours old.
531
+ */
532
+ claimPromo(promoCode?: string): Promise<ApiResponse & {
533
+ promo?: string;
534
+ bonus_sats?: number;
535
+ message?: string;
536
+ }>;
516
537
  }
517
538
  export declare function registerOperator(name?: string, email?: string): Promise<{
518
539
  operatorId: number;
519
540
  apiKey: string;
520
541
  recoveryCode: string;
521
542
  }>;
543
+ export declare function getPublicInfo(): Promise<{
544
+ version: string;
545
+ apiVersion: string;
546
+ status: string;
547
+ maxPaymentSats: number;
548
+ minPaymentSats: number;
549
+ supportedFeatures: string[];
550
+ rawResponse: ApiResponse;
551
+ }>;
522
552
  export {};
@@ -7,6 +7,7 @@
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
8
  exports.LightningFaucetClient = void 0;
9
9
  exports.registerOperator = registerOperator;
10
+ exports.getPublicInfo = getPublicInfo;
10
11
  const API_BASE_URL = process.env.LIGHTNING_WALLET_API_URL || 'https://lightningfaucet.com/ai-agents/api';
11
12
  class LightningFaucetClient {
12
13
  apiKey;
@@ -774,6 +775,28 @@ class LightningFaucetClient {
774
775
  direction,
775
776
  });
776
777
  }
778
+ /**
779
+ * Update operator profile (email and/or name). Setting an email sends a
780
+ * verification link - a verified email is required for the free-sats promo.
781
+ */
782
+ async updateOperator(opts) {
783
+ const params = {};
784
+ if (opts.email !== undefined)
785
+ params.email = opts.email;
786
+ if (opts.name !== undefined)
787
+ params.name = opts.name;
788
+ return this.request('update_operator', params);
789
+ }
790
+ /**
791
+ * Claim a promo bonus (default: the first_100_installs free-sats promo).
792
+ * Requires a verified email and an operator account at least 24 hours old.
793
+ */
794
+ async claimPromo(promoCode) {
795
+ const params = {};
796
+ if (promoCode)
797
+ params.promo_code = promoCode;
798
+ return this.request('claim_promo', params);
799
+ }
777
800
  }
778
801
  exports.LightningFaucetClient = LightningFaucetClient;
779
802
  // Static method for registration (no API key needed)
@@ -808,3 +831,24 @@ async function registerOperator(name, email) {
808
831
  recoveryCode: result.recovery_code || '',
809
832
  };
810
833
  }
834
+ // Public service info (no API key needed)
835
+ async function getPublicInfo() {
836
+ const response = await fetch(API_BASE_URL, {
837
+ method: 'POST',
838
+ headers: { 'Content-Type': 'application/json' },
839
+ body: JSON.stringify({ action: 'get_info' }),
840
+ });
841
+ if (!response.ok) {
842
+ throw new Error(`Request failed (HTTP ${response.status})`);
843
+ }
844
+ const result = (await response.json());
845
+ return {
846
+ version: result.version || '2.0.0',
847
+ apiVersion: result.api_version || '1.0',
848
+ status: result.status || 'operational',
849
+ maxPaymentSats: result.max_payment_sats || 1000000,
850
+ minPaymentSats: result.min_payment_sats || 1,
851
+ supportedFeatures: result.supported_features || ['l402', 'webhooks', 'lightning_address'],
852
+ rawResponse: result,
853
+ };
854
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lightning-wallet-mcp",
3
- "version": "1.3.2",
3
+ "version": "1.4.0",
4
4
  "mcpName": "io.github.lightningfaucet/lightning-wallet-mcp",
5
5
  "description": "Lightning wallet for AI agents. MCP server + CLI. Works with Claude Code, OpenClaw, Cursor, and any agent framework.",
6
6
  "main": "dist/index.js",