clawdentials-mcp 0.1.0 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +310 -58
  2. package/dist/index.d.ts +1 -1
  3. package/dist/index.js +225 -18
  4. package/dist/schemas/index.d.ts +141 -0
  5. package/dist/schemas/index.js +54 -0
  6. package/dist/services/firestore.d.ts +45 -2
  7. package/dist/services/firestore.js +410 -6
  8. package/dist/services/payments/alby.d.ts +104 -0
  9. package/dist/services/payments/alby.js +239 -0
  10. package/dist/services/payments/breez.d.ts +91 -0
  11. package/dist/services/payments/breez.js +267 -0
  12. package/dist/services/payments/cashu.d.ts +127 -0
  13. package/dist/services/payments/cashu.js +248 -0
  14. package/dist/services/payments/coinremitter.d.ts +84 -0
  15. package/dist/services/payments/coinremitter.js +176 -0
  16. package/dist/services/payments/index.d.ts +132 -0
  17. package/dist/services/payments/index.js +180 -0
  18. package/dist/services/payments/oxapay.d.ts +89 -0
  19. package/dist/services/payments/oxapay.js +221 -0
  20. package/dist/services/payments/x402.d.ts +61 -0
  21. package/dist/services/payments/x402.js +94 -0
  22. package/dist/services/payments/zbd.d.ts +88 -0
  23. package/dist/services/payments/zbd.js +221 -0
  24. package/dist/tools/admin.d.ts +195 -0
  25. package/dist/tools/admin.js +210 -0
  26. package/dist/tools/agent.d.ts +197 -0
  27. package/dist/tools/agent.js +200 -0
  28. package/dist/tools/escrow.d.ts +74 -16
  29. package/dist/tools/escrow.js +139 -28
  30. package/dist/tools/index.d.ts +3 -0
  31. package/dist/tools/index.js +3 -0
  32. package/dist/tools/payment.d.ts +144 -0
  33. package/dist/tools/payment.js +376 -0
  34. package/dist/types/index.d.ts +44 -1
  35. package/package.json +18 -2
@@ -0,0 +1,239 @@
1
+ /**
2
+ * Alby Payment Service - Bitcoin on Lightning
3
+ *
4
+ * Uses Alby API with Nostr Wallet Connect (NWC) for self-custodial Lightning payments.
5
+ * Docs: https://guides.getalby.com/developer-guide
6
+ * Fee: ~0% (just Lightning network fees)
7
+ */
8
+ // Configuration
9
+ // NWC connection string format: nostr+walletconnect://pubkey?relay=wss://...&secret=...
10
+ const ALBY_NWC_URL = process.env.ALBY_NWC_URL || '';
11
+ const ALBY_WEBHOOK_URL = process.env.ALBY_WEBHOOK_URL || '';
12
+ // Alby API (for account-based operations)
13
+ const ALBY_API_KEY = process.env.ALBY_API_KEY || '';
14
+ const API_BASE = 'https://api.getalby.com';
15
+ // Exchange rate (sats per USD) - in production, fetch from API
16
+ const SATS_PER_USD = parseInt(process.env.ALBY_SATS_PER_USD || '1000', 10);
17
+ /**
18
+ * Convert USD to sats
19
+ */
20
+ function usdToSats(usd) {
21
+ return Math.floor(usd * SATS_PER_USD);
22
+ }
23
+ /**
24
+ * Convert sats to USD
25
+ */
26
+ function satsToUsd(sats) {
27
+ return sats / SATS_PER_USD;
28
+ }
29
+ /**
30
+ * Make API request to Alby
31
+ */
32
+ async function apiRequest(endpoint, method = 'POST', data) {
33
+ if (!ALBY_API_KEY) {
34
+ throw new Error('ALBY_API_KEY not configured');
35
+ }
36
+ const response = await fetch(`${API_BASE}${endpoint}`, {
37
+ method,
38
+ headers: {
39
+ 'Content-Type': 'application/json',
40
+ Authorization: `Bearer ${ALBY_API_KEY}`,
41
+ },
42
+ body: data ? JSON.stringify(data) : undefined,
43
+ });
44
+ if (!response.ok) {
45
+ const error = await response.text();
46
+ throw new Error(`Alby API error: ${error}`);
47
+ }
48
+ return response.json();
49
+ }
50
+ /**
51
+ * Create a Lightning invoice for BTC deposit
52
+ */
53
+ export async function createAlbyDeposit(request) {
54
+ if (!ALBY_API_KEY) {
55
+ return {
56
+ success: false,
57
+ error: 'ALBY_API_KEY not configured. Get one at https://getalby.com',
58
+ };
59
+ }
60
+ try {
61
+ const amountSats = usdToSats(request.amount);
62
+ const result = await apiRequest('/invoices', 'POST', {
63
+ amount: amountSats,
64
+ description: request.description || `Clawdentials deposit for ${request.agentId}`,
65
+ memo: request.agentId, // Store agentId in memo for webhook processing
66
+ });
67
+ // Alby invoices expire in 1 hour by default
68
+ const expiresAt = new Date(Date.now() + 60 * 60 * 1000);
69
+ return {
70
+ success: true,
71
+ deposit: {
72
+ id: `alby_${result.payment_hash}`,
73
+ agentId: request.agentId,
74
+ amount: request.amount,
75
+ currency: 'BTC',
76
+ network: 'lightning',
77
+ status: 'pending',
78
+ provider: 'alby',
79
+ externalId: result.payment_hash,
80
+ paymentAddress: result.payment_request, // bolt11 invoice
81
+ paymentUrl: null,
82
+ createdAt: new Date(),
83
+ expiresAt,
84
+ completedAt: null,
85
+ txHash: null,
86
+ },
87
+ invoice: {
88
+ paymentHash: result.payment_hash,
89
+ paymentRequest: result.payment_request,
90
+ amountSats,
91
+ expiresAt,
92
+ },
93
+ };
94
+ }
95
+ catch (error) {
96
+ return {
97
+ success: false,
98
+ error: error instanceof Error ? error.message : 'Failed to create Lightning invoice',
99
+ };
100
+ }
101
+ }
102
+ /**
103
+ * Check invoice status
104
+ */
105
+ export async function getInvoiceStatus(paymentHash) {
106
+ if (!ALBY_API_KEY) {
107
+ return { success: false, error: 'ALBY_API_KEY not configured' };
108
+ }
109
+ try {
110
+ const result = await apiRequest(`/invoices/${paymentHash}`, 'GET');
111
+ return {
112
+ success: true,
113
+ status: result.state, // CREATED, SETTLED, CANCELED
114
+ paid: result.state === 'SETTLED',
115
+ amountSats: result.amount,
116
+ amountUsd: satsToUsd(result.amount),
117
+ };
118
+ }
119
+ catch (error) {
120
+ return {
121
+ success: false,
122
+ error: error instanceof Error ? error.message : 'Failed to get invoice status',
123
+ };
124
+ }
125
+ }
126
+ /**
127
+ * Process webhook callback from Alby
128
+ */
129
+ export function parseWebhookPayload(body) {
130
+ return {
131
+ paymentHash: body.payment_hash,
132
+ status: body.state,
133
+ amountSats: body.amount,
134
+ amountUsd: satsToUsd(body.amount),
135
+ memo: body.memo || body.description || '',
136
+ };
137
+ }
138
+ /**
139
+ * Send Lightning payment (for withdrawals)
140
+ */
141
+ export async function sendAlbyPayment(destination, // Lightning invoice or Lightning Address
142
+ amountUsd) {
143
+ if (!ALBY_API_KEY) {
144
+ return { success: false, error: 'ALBY_API_KEY not configured' };
145
+ }
146
+ try {
147
+ // Check if it's a Lightning Address (contains @)
148
+ if (destination.includes('@')) {
149
+ // Pay to Lightning Address
150
+ const amountSats = usdToSats(amountUsd);
151
+ const result = await apiRequest('/payments/lnaddress', 'POST', {
152
+ lnaddress: destination,
153
+ amount: amountSats,
154
+ comment: 'Clawdentials withdrawal',
155
+ });
156
+ return {
157
+ success: true,
158
+ paymentHash: result.payment_hash,
159
+ };
160
+ }
161
+ else {
162
+ // Pay bolt11 invoice directly
163
+ const result = await apiRequest('/payments/bolt11', 'POST', {
164
+ invoice: destination,
165
+ });
166
+ return {
167
+ success: true,
168
+ paymentHash: result.payment_hash,
169
+ };
170
+ }
171
+ }
172
+ catch (error) {
173
+ return {
174
+ success: false,
175
+ error: error instanceof Error ? error.message : 'Failed to send payment',
176
+ };
177
+ }
178
+ }
179
+ /**
180
+ * Get wallet balance
181
+ */
182
+ export async function getWalletBalance() {
183
+ if (!ALBY_API_KEY) {
184
+ return { success: false, error: 'ALBY_API_KEY not configured' };
185
+ }
186
+ try {
187
+ const result = await apiRequest('/balance', 'GET');
188
+ return {
189
+ success: true,
190
+ balanceSats: result.balance,
191
+ balanceUsd: satsToUsd(result.balance),
192
+ };
193
+ }
194
+ catch (error) {
195
+ return {
196
+ success: false,
197
+ error: error instanceof Error ? error.message : 'Failed to get balance',
198
+ };
199
+ }
200
+ }
201
+ /**
202
+ * Decode a Lightning invoice to get amount and details
203
+ */
204
+ export async function decodeInvoice(invoice) {
205
+ try {
206
+ // Use Alby's decode endpoint or a local decoder
207
+ const result = await apiRequest('/decode/bolt11', 'POST', { invoice });
208
+ return {
209
+ success: true,
210
+ amountSats: result.amount,
211
+ amountUsd: satsToUsd(result.amount),
212
+ description: result.description,
213
+ paymentHash: result.payment_hash,
214
+ expiresAt: result.expires_at ? new Date(result.expires_at * 1000) : undefined,
215
+ };
216
+ }
217
+ catch (error) {
218
+ return {
219
+ success: false,
220
+ error: error instanceof Error ? error.message : 'Failed to decode invoice',
221
+ };
222
+ }
223
+ }
224
+ export const albyService = {
225
+ createDeposit: createAlbyDeposit,
226
+ getInvoiceStatus,
227
+ parseWebhookPayload,
228
+ sendPayment: sendAlbyPayment,
229
+ getWalletBalance,
230
+ decodeInvoice,
231
+ usdToSats,
232
+ satsToUsd,
233
+ config: {
234
+ configured: !!ALBY_API_KEY,
235
+ nwcConfigured: !!ALBY_NWC_URL,
236
+ webhookUrl: ALBY_WEBHOOK_URL,
237
+ satsPerUsd: SATS_PER_USD,
238
+ },
239
+ };
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Breez SDK Payment Service - Bitcoin on Lightning (Nodeless/Liquid)
3
+ *
4
+ * Uses Breez SDK Liquid for self-custodial Lightning payments.
5
+ * Docs: https://sdk-doc-liquid.breez.technology/
6
+ * Fee: Network fees only (no platform fee)
7
+ *
8
+ * Requirements:
9
+ * - Node.js v22+
10
+ * - Breez API key (free, request at https://breez.technology/sdk/)
11
+ * - 12-word mnemonic for self-custody
12
+ */
13
+ import type { Deposit } from '../../types/index.js';
14
+ export interface BreezPaymentRequest {
15
+ amount: number;
16
+ agentId: string;
17
+ description?: string;
18
+ }
19
+ export interface BreezPaymentResponse {
20
+ success: boolean;
21
+ deposit?: Partial<Deposit>;
22
+ invoice?: {
23
+ bolt11: string;
24
+ amountSats: number;
25
+ expiresAt: Date;
26
+ };
27
+ error?: string;
28
+ }
29
+ /**
30
+ * Convert USD to sats
31
+ */
32
+ declare function usdToSats(usd: number): number;
33
+ /**
34
+ * Convert sats to USD
35
+ */
36
+ declare function satsToUsd(sats: number): number;
37
+ /**
38
+ * Create a Lightning invoice for BTC deposit
39
+ */
40
+ export declare function createBreezDeposit(request: BreezPaymentRequest): Promise<BreezPaymentResponse>;
41
+ /**
42
+ * Send Lightning payment (for withdrawals)
43
+ */
44
+ export declare function sendBreezPayment(destination: string, // bolt11 invoice or Lightning Address
45
+ amountUsd: number): Promise<{
46
+ success: boolean;
47
+ txId?: string;
48
+ error?: string;
49
+ }>;
50
+ /**
51
+ * Get wallet balance
52
+ */
53
+ export declare function getWalletBalance(): Promise<{
54
+ success: boolean;
55
+ balanceSats?: number;
56
+ balanceUsd?: number;
57
+ error?: string;
58
+ }>;
59
+ /**
60
+ * List recent payments
61
+ */
62
+ export declare function listPayments(limit?: number): Promise<{
63
+ success: boolean;
64
+ payments?: any[];
65
+ error?: string;
66
+ }>;
67
+ /**
68
+ * Disconnect from SDK (cleanup)
69
+ */
70
+ export declare function disconnect(): Promise<void>;
71
+ /**
72
+ * Generate a new mnemonic (for initial setup)
73
+ */
74
+ export declare function generateMnemonic(): string;
75
+ export declare const breezService: {
76
+ createDeposit: typeof createBreezDeposit;
77
+ sendPayment: typeof sendBreezPayment;
78
+ getWalletBalance: typeof getWalletBalance;
79
+ listPayments: typeof listPayments;
80
+ disconnect: typeof disconnect;
81
+ usdToSats: typeof usdToSats;
82
+ satsToUsd: typeof satsToUsd;
83
+ config: {
84
+ configured: boolean;
85
+ apiKeySet: boolean;
86
+ mnemonicSet: boolean;
87
+ network: string;
88
+ satsPerUsd: number;
89
+ };
90
+ };
91
+ export {};
@@ -0,0 +1,267 @@
1
+ /**
2
+ * Breez SDK Payment Service - Bitcoin on Lightning (Nodeless/Liquid)
3
+ *
4
+ * Uses Breez SDK Liquid for self-custodial Lightning payments.
5
+ * Docs: https://sdk-doc-liquid.breez.technology/
6
+ * Fee: Network fees only (no platform fee)
7
+ *
8
+ * Requirements:
9
+ * - Node.js v22+
10
+ * - Breez API key (free, request at https://breez.technology/sdk/)
11
+ * - 12-word mnemonic for self-custody
12
+ */
13
+ // Configuration
14
+ const BREEZ_API_KEY = process.env.BREEZ_API_KEY || '';
15
+ const BREEZ_MNEMONIC = process.env.BREEZ_MNEMONIC || '';
16
+ const BREEZ_WORKING_DIR = process.env.BREEZ_WORKING_DIR || './breez-data';
17
+ const BREEZ_NETWORK = process.env.BREEZ_NETWORK || 'mainnet'; // 'mainnet' or 'testnet'
18
+ // Exchange rate (sats per USD) - in production, fetch from API
19
+ const SATS_PER_USD = parseInt(process.env.BREEZ_SATS_PER_USD || '1000', 10);
20
+ // SDK instance (lazy loaded)
21
+ let sdkInstance = null;
22
+ let sdkInitPromise = null;
23
+ /**
24
+ * Convert USD to sats
25
+ */
26
+ function usdToSats(usd) {
27
+ return Math.floor(usd * SATS_PER_USD);
28
+ }
29
+ /**
30
+ * Convert sats to USD
31
+ */
32
+ function satsToUsd(sats) {
33
+ return sats / SATS_PER_USD;
34
+ }
35
+ /**
36
+ * Initialize and connect to Breez SDK
37
+ */
38
+ async function getSDK() {
39
+ if (sdkInstance) {
40
+ return sdkInstance;
41
+ }
42
+ if (sdkInitPromise) {
43
+ return sdkInitPromise;
44
+ }
45
+ if (!BREEZ_API_KEY) {
46
+ throw new Error('BREEZ_API_KEY not configured. Request one at https://breez.technology/sdk/');
47
+ }
48
+ if (!BREEZ_MNEMONIC) {
49
+ throw new Error('BREEZ_MNEMONIC not configured. Generate a 12-word mnemonic for self-custody.');
50
+ }
51
+ sdkInitPromise = (async () => {
52
+ try {
53
+ // Dynamic import for the Breez SDK
54
+ const breezModule = await import('@breeztech/breez-sdk-liquid');
55
+ // Network type is a string literal: "mainnet" | "testnet" | "regtest"
56
+ const network = BREEZ_NETWORK;
57
+ const config = breezModule.defaultConfig(network, BREEZ_API_KEY);
58
+ config.workingDir = BREEZ_WORKING_DIR;
59
+ sdkInstance = await breezModule.connect({
60
+ mnemonic: BREEZ_MNEMONIC,
61
+ config,
62
+ });
63
+ return sdkInstance;
64
+ }
65
+ catch (error) {
66
+ sdkInitPromise = null;
67
+ throw error;
68
+ }
69
+ })();
70
+ return sdkInitPromise;
71
+ }
72
+ /**
73
+ * Create a Lightning invoice for BTC deposit
74
+ */
75
+ export async function createBreezDeposit(request) {
76
+ if (!BREEZ_API_KEY || !BREEZ_MNEMONIC) {
77
+ return {
78
+ success: false,
79
+ error: !BREEZ_API_KEY
80
+ ? 'BREEZ_API_KEY not configured. Request one at https://breez.technology/sdk/'
81
+ : 'BREEZ_MNEMONIC not configured. Set a 12-word mnemonic for self-custody.',
82
+ };
83
+ }
84
+ try {
85
+ const sdk = await getSDK();
86
+ const amountSats = usdToSats(request.amount);
87
+ // Fetch limits first
88
+ const limits = await sdk.fetchLightningLimits();
89
+ if (amountSats < limits.receive.minSat) {
90
+ return {
91
+ success: false,
92
+ error: `Minimum deposit: ${limits.receive.minSat} sats (~$${satsToUsd(limits.receive.minSat).toFixed(2)})`,
93
+ };
94
+ }
95
+ if (amountSats > limits.receive.maxSat) {
96
+ return {
97
+ success: false,
98
+ error: `Maximum deposit: ${limits.receive.maxSat} sats (~$${satsToUsd(limits.receive.maxSat).toFixed(2)})`,
99
+ };
100
+ }
101
+ // Prepare the receive payment
102
+ const prepareResponse = await sdk.prepareReceivePayment({
103
+ paymentMethod: 'bolt11Invoice',
104
+ amount: {
105
+ type: 'bitcoin',
106
+ payerAmountSat: amountSats,
107
+ },
108
+ });
109
+ // Create the invoice
110
+ const description = request.description || `Clawdentials deposit for ${request.agentId}`;
111
+ const result = await sdk.receivePayment({
112
+ prepareResponse,
113
+ description,
114
+ });
115
+ // Invoice expires in 1 hour typically
116
+ const expiresAt = new Date(Date.now() + 60 * 60 * 1000);
117
+ return {
118
+ success: true,
119
+ deposit: {
120
+ id: `breez_${Date.now()}_${Math.random().toString(36).substring(7)}`,
121
+ agentId: request.agentId,
122
+ amount: request.amount,
123
+ currency: 'BTC',
124
+ network: 'lightning',
125
+ status: 'pending',
126
+ provider: 'breez',
127
+ externalId: null,
128
+ paymentAddress: result.destination, // bolt11 invoice
129
+ paymentUrl: null,
130
+ createdAt: new Date(),
131
+ expiresAt,
132
+ completedAt: null,
133
+ txHash: null,
134
+ },
135
+ invoice: {
136
+ bolt11: result.destination,
137
+ amountSats,
138
+ expiresAt,
139
+ },
140
+ };
141
+ }
142
+ catch (error) {
143
+ return {
144
+ success: false,
145
+ error: error instanceof Error ? error.message : 'Failed to create Lightning invoice',
146
+ };
147
+ }
148
+ }
149
+ /**
150
+ * Send Lightning payment (for withdrawals)
151
+ */
152
+ export async function sendBreezPayment(destination, // bolt11 invoice or Lightning Address
153
+ amountUsd) {
154
+ if (!BREEZ_API_KEY || !BREEZ_MNEMONIC) {
155
+ return { success: false, error: 'Breez SDK not configured' };
156
+ }
157
+ try {
158
+ const sdk = await getSDK();
159
+ // Prepare the payment
160
+ const prepareResponse = await sdk.prepareSendPayment({
161
+ destination,
162
+ });
163
+ // Check fees are acceptable
164
+ const feesSat = prepareResponse.feesSat;
165
+ console.log(`Breez payment fees: ${feesSat} sats`);
166
+ // Send the payment
167
+ const result = await sdk.sendPayment({
168
+ prepareResponse,
169
+ });
170
+ return {
171
+ success: true,
172
+ txId: result.payment?.txId || result.payment?.id,
173
+ };
174
+ }
175
+ catch (error) {
176
+ return {
177
+ success: false,
178
+ error: error instanceof Error ? error.message : 'Failed to send payment',
179
+ };
180
+ }
181
+ }
182
+ /**
183
+ * Get wallet balance
184
+ */
185
+ export async function getWalletBalance() {
186
+ if (!BREEZ_API_KEY || !BREEZ_MNEMONIC) {
187
+ return { success: false, error: 'Breez SDK not configured' };
188
+ }
189
+ try {
190
+ const sdk = await getSDK();
191
+ const info = await sdk.getInfo();
192
+ return {
193
+ success: true,
194
+ balanceSats: info.balanceSat,
195
+ balanceUsd: satsToUsd(info.balanceSat),
196
+ };
197
+ }
198
+ catch (error) {
199
+ return {
200
+ success: false,
201
+ error: error instanceof Error ? error.message : 'Failed to get balance',
202
+ };
203
+ }
204
+ }
205
+ /**
206
+ * List recent payments
207
+ */
208
+ export async function listPayments(limit = 10) {
209
+ if (!BREEZ_API_KEY || !BREEZ_MNEMONIC) {
210
+ return { success: false, error: 'Breez SDK not configured' };
211
+ }
212
+ try {
213
+ const sdk = await getSDK();
214
+ const payments = await sdk.listPayments({
215
+ limit,
216
+ });
217
+ return {
218
+ success: true,
219
+ payments,
220
+ };
221
+ }
222
+ catch (error) {
223
+ return {
224
+ success: false,
225
+ error: error instanceof Error ? error.message : 'Failed to list payments',
226
+ };
227
+ }
228
+ }
229
+ /**
230
+ * Disconnect from SDK (cleanup)
231
+ */
232
+ export async function disconnect() {
233
+ if (sdkInstance) {
234
+ try {
235
+ await sdkInstance.disconnect();
236
+ }
237
+ catch (e) {
238
+ // Ignore disconnect errors
239
+ }
240
+ sdkInstance = null;
241
+ sdkInitPromise = null;
242
+ }
243
+ }
244
+ /**
245
+ * Generate a new mnemonic (for initial setup)
246
+ */
247
+ export function generateMnemonic() {
248
+ // In production, use a proper BIP39 library
249
+ // This is a placeholder - the actual mnemonic should be generated securely
250
+ throw new Error('Generate mnemonic using a BIP39 library or wallet. Do not use this in production.');
251
+ }
252
+ export const breezService = {
253
+ createDeposit: createBreezDeposit,
254
+ sendPayment: sendBreezPayment,
255
+ getWalletBalance,
256
+ listPayments,
257
+ disconnect,
258
+ usdToSats,
259
+ satsToUsd,
260
+ config: {
261
+ configured: !!(BREEZ_API_KEY && BREEZ_MNEMONIC),
262
+ apiKeySet: !!BREEZ_API_KEY,
263
+ mnemonicSet: !!BREEZ_MNEMONIC,
264
+ network: BREEZ_NETWORK,
265
+ satsPerUsd: SATS_PER_USD,
266
+ },
267
+ };