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
@@ -1,5 +1,27 @@
1
1
  import { initializeApp, getApps, applicationDefault } from 'firebase-admin/app';
2
2
  import { getFirestore, Timestamp } from 'firebase-admin/firestore';
3
+ import { createHash, randomBytes } from 'crypto';
4
+ import { generateSecretKey, getPublicKey } from 'nostr-tools/pure';
5
+ import * as nip19 from 'nostr-tools/nip19';
6
+ // Platform fee rate (10%)
7
+ export const FEE_RATE = 0.10;
8
+ // Admin secret (in production, use environment variable)
9
+ export const ADMIN_SECRET = process.env.CLAWDENTIALS_ADMIN_SECRET || 'clawdentials-admin-secret-change-me';
10
+ // API Key utilities
11
+ export function generateApiKey() {
12
+ return `clw_${randomBytes(24).toString('hex')}`;
13
+ }
14
+ export function hashApiKey(apiKey) {
15
+ return createHash('sha256').update(apiKey).digest('hex');
16
+ }
17
+ // Nostr identity utilities
18
+ export function generateNostrKeypair() {
19
+ const secretKey = generateSecretKey();
20
+ const publicKey = getPublicKey(secretKey); // hex format
21
+ const nsec = nip19.nsecEncode(secretKey);
22
+ const npub = nip19.npubEncode(publicKey);
23
+ return { secretKey, publicKey, nsec, npub };
24
+ }
3
25
  let app;
4
26
  let db;
5
27
  export function initFirestore() {
@@ -30,16 +52,22 @@ export const collections = {
30
52
  agents: () => getDb().collection('agents'),
31
53
  tasks: () => getDb().collection('tasks'),
32
54
  subscriptions: () => getDb().collection('subscriptions'),
55
+ withdrawals: () => getDb().collection('withdrawals'),
56
+ deposits: () => getDb().collection('deposits'),
33
57
  };
34
58
  // Escrow operations
35
59
  export async function createEscrow(data) {
36
60
  const docRef = collections.escrows().doc();
61
+ const fee = data.amount * FEE_RATE;
37
62
  const escrow = {
38
63
  ...data,
64
+ fee,
65
+ feeRate: FEE_RATE,
39
66
  status: 'pending',
40
67
  createdAt: new Date(),
41
68
  completedAt: null,
42
69
  proofOfWork: null,
70
+ disputeReason: null,
43
71
  };
44
72
  await docRef.set({
45
73
  ...escrow,
@@ -59,11 +87,14 @@ export async function getEscrow(escrowId) {
59
87
  providerAgentId: data.providerAgentId,
60
88
  taskDescription: data.taskDescription,
61
89
  amount: data.amount,
90
+ fee: data.fee ?? 0,
91
+ feeRate: data.feeRate ?? FEE_RATE,
62
92
  currency: data.currency,
63
93
  status: data.status,
64
94
  createdAt: data.createdAt.toDate(),
65
95
  completedAt: data.completedAt?.toDate() ?? null,
66
96
  proofOfWork: data.proofOfWork ?? null,
97
+ disputeReason: data.disputeReason ?? null,
67
98
  };
68
99
  }
69
100
  export async function completeEscrow(escrowId, proofOfWork) {
@@ -85,15 +116,388 @@ export async function completeEscrow(escrowId, proofOfWork) {
85
116
  }
86
117
  return escrow;
87
118
  }
119
+ // Default stats for new agents
120
+ function defaultAgentStats() {
121
+ return {
122
+ tasksCompleted: 0,
123
+ totalEarned: 0,
124
+ successRate: 100,
125
+ avgCompletionTime: 0,
126
+ disputeCount: 0,
127
+ disputeRate: 0,
128
+ };
129
+ }
130
+ // Agent operations
131
+ export async function createAgent(data) {
132
+ const docRef = collections.agents().doc(data.name); // Use name as ID for simplicity
133
+ const existingDoc = await docRef.get();
134
+ if (existingDoc.exists) {
135
+ throw new Error(`Agent with name "${data.name}" already exists`);
136
+ }
137
+ // Generate API key
138
+ const apiKey = generateApiKey();
139
+ const apiKeyHash = hashApiKey(apiKey);
140
+ // Generate Nostr keypair for NIP-05 identity
141
+ const nostrKeys = generateNostrKeypair();
142
+ const nip05 = `${data.name}@clawdentials.com`;
143
+ const agent = {
144
+ ...data,
145
+ createdAt: new Date(),
146
+ stats: defaultAgentStats(),
147
+ apiKeyHash,
148
+ balance: 0,
149
+ nostrPubkey: nostrKeys.publicKey,
150
+ nip05,
151
+ };
152
+ await docRef.set({
153
+ ...agent,
154
+ createdAt: Timestamp.fromDate(agent.createdAt),
155
+ });
156
+ return {
157
+ agent: { id: docRef.id, ...agent },
158
+ apiKey,
159
+ nostr: {
160
+ nsec: nostrKeys.nsec,
161
+ npub: nostrKeys.npub,
162
+ nip05,
163
+ },
164
+ };
165
+ }
166
+ export async function getAgent(agentId) {
167
+ const doc = await collections.agents().doc(agentId).get();
168
+ if (!doc.exists) {
169
+ return null;
170
+ }
171
+ const data = doc.data();
172
+ return {
173
+ id: doc.id,
174
+ name: data.name,
175
+ description: data.description,
176
+ skills: data.skills || [],
177
+ createdAt: data.createdAt.toDate(),
178
+ verified: data.verified || false,
179
+ subscriptionTier: data.subscriptionTier || 'free',
180
+ stats: {
181
+ tasksCompleted: data.stats?.tasksCompleted || 0,
182
+ totalEarned: data.stats?.totalEarned || 0,
183
+ successRate: data.stats?.successRate || 100,
184
+ avgCompletionTime: data.stats?.avgCompletionTime || 0,
185
+ disputeCount: data.stats?.disputeCount || 0,
186
+ disputeRate: data.stats?.disputeRate || 0,
187
+ },
188
+ apiKeyHash: data.apiKeyHash || '',
189
+ balance: data.balance || 0,
190
+ nostrPubkey: data.nostrPubkey || undefined,
191
+ nip05: data.nip05 || undefined,
192
+ };
193
+ }
194
+ // Validate API key for an agent
195
+ export async function validateApiKey(agentId, apiKey) {
196
+ const agent = await getAgent(agentId);
197
+ if (!agent || !agent.apiKeyHash) {
198
+ return false;
199
+ }
200
+ return agent.apiKeyHash === hashApiKey(apiKey);
201
+ }
202
+ export async function getOrCreateAgent(agentId) {
203
+ const existing = await getAgent(agentId);
204
+ if (existing) {
205
+ return existing;
206
+ }
207
+ // Auto-create minimal agent record for tracking
208
+ const { agent } = await createAgent({
209
+ name: agentId,
210
+ description: 'Auto-registered agent',
211
+ skills: [],
212
+ verified: false,
213
+ subscriptionTier: 'free',
214
+ });
215
+ return agent;
216
+ }
217
+ export async function searchAgents(query) {
218
+ let ref = collections.agents().limit(query.limit || 20);
219
+ if (query.verified !== undefined) {
220
+ ref = ref.where('verified', '==', query.verified);
221
+ }
222
+ if (query.minTasksCompleted !== undefined) {
223
+ ref = ref.where('stats.tasksCompleted', '>=', query.minTasksCompleted);
224
+ }
225
+ const snapshot = await ref.get();
226
+ const agents = [];
227
+ for (const doc of snapshot.docs) {
228
+ const agent = await getAgent(doc.id);
229
+ if (agent) {
230
+ // Filter by skill in memory (Firestore array-contains limitation)
231
+ if (query.skill && !agent.skills.some(s => s.toLowerCase().includes(query.skill.toLowerCase()))) {
232
+ continue;
233
+ }
234
+ agents.push(agent);
235
+ }
236
+ }
237
+ return agents;
238
+ }
88
239
  async function updateAgentStats(agentId, amount) {
240
+ // Ensure agent exists (auto-create if needed)
241
+ await getOrCreateAgent(agentId);
242
+ const agentRef = collections.agents().doc(agentId);
243
+ const doc = await agentRef.get();
244
+ const data = doc.data();
245
+ const currentStats = data.stats || defaultAgentStats();
246
+ const newTasksCompleted = currentStats.tasksCompleted + 1;
247
+ const newTotalEarned = currentStats.totalEarned + amount;
248
+ await agentRef.update({
249
+ 'stats.tasksCompleted': newTasksCompleted,
250
+ 'stats.totalEarned': newTotalEarned,
251
+ // Recalculate dispute rate
252
+ 'stats.disputeRate': currentStats.disputeCount / newTasksCompleted * 100,
253
+ });
254
+ }
255
+ export async function incrementAgentDisputes(agentId) {
256
+ await getOrCreateAgent(agentId);
257
+ const agentRef = collections.agents().doc(agentId);
258
+ const doc = await agentRef.get();
259
+ const data = doc.data();
260
+ const currentStats = data.stats || defaultAgentStats();
261
+ const newDisputeCount = currentStats.disputeCount + 1;
262
+ const totalTasks = currentStats.tasksCompleted || 1;
263
+ await agentRef.update({
264
+ 'stats.disputeCount': newDisputeCount,
265
+ 'stats.disputeRate': (newDisputeCount / totalTasks) * 100,
266
+ });
267
+ }
268
+ export async function disputeEscrow(escrowId, reason) {
269
+ const escrowRef = collections.escrows().doc(escrowId);
270
+ const doc = await escrowRef.get();
271
+ if (!doc.exists) {
272
+ return null;
273
+ }
274
+ const data = doc.data();
275
+ // Can only dispute pending or in_progress escrows
276
+ if (data.status === 'completed' || data.status === 'cancelled') {
277
+ throw new Error(`Cannot dispute escrow with status: ${data.status}`);
278
+ }
279
+ await escrowRef.update({
280
+ status: 'disputed',
281
+ disputeReason: reason,
282
+ });
283
+ // Increment dispute count for the provider agent
284
+ await incrementAgentDisputes(data.providerAgentId);
285
+ return getEscrow(escrowId);
286
+ }
287
+ // Reputation scoring algorithm (from ARCHITECTURE.md)
288
+ // score = (
289
+ // (tasks_completed * 2) +
290
+ // (success_rate * 30) +
291
+ // (log(total_earned + 1) * 10) +
292
+ // (speed_bonus * 10) +
293
+ // (account_age_days * 0.1)
294
+ // ) / max_possible * 100
295
+ export function calculateReputationScore(agent) {
296
+ const stats = agent.stats;
297
+ const accountAgeDays = Math.floor((Date.now() - agent.createdAt.getTime()) / (1000 * 60 * 60 * 24));
298
+ // Calculate success rate (accounting for disputes)
299
+ const effectiveSuccessRate = stats.tasksCompleted > 0
300
+ ? ((stats.tasksCompleted - stats.disputeCount) / stats.tasksCompleted) * 100
301
+ : 100;
302
+ // Speed bonus (placeholder - would need actual timing data)
303
+ const speedBonus = stats.avgCompletionTime > 0 ? Math.max(0, 10 - stats.avgCompletionTime / 60) : 5;
304
+ // Raw score components
305
+ const taskScore = stats.tasksCompleted * 2;
306
+ const successScore = effectiveSuccessRate * 0.3; // Normalized (max 30)
307
+ const earningsScore = Math.log10(stats.totalEarned + 1) * 10;
308
+ const speedScore = speedBonus;
309
+ const ageScore = accountAgeDays * 0.1;
310
+ // Max possible (for normalization)
311
+ // Assuming max: 10000 tasks, 100% success, $1M earned, max speed, 365 days
312
+ const maxPossible = (10000 * 2) + (100 * 0.3) + (Math.log10(1000001) * 10) + 10 + (365 * 0.1);
313
+ const rawScore = taskScore + successScore + earningsScore + speedScore + ageScore;
314
+ const normalizedScore = (rawScore / maxPossible) * 100;
315
+ // Clamp between 0 and 100
316
+ return Math.min(100, Math.max(0, Math.round(normalizedScore * 10) / 10));
317
+ }
318
+ // Balance operations
319
+ export async function getBalance(agentId) {
320
+ const agent = await getAgent(agentId);
321
+ return agent?.balance ?? 0;
322
+ }
323
+ export async function creditBalance(agentId, amount, notes) {
324
+ const agentRef = collections.agents().doc(agentId);
325
+ const doc = await agentRef.get();
326
+ if (!doc.exists) {
327
+ throw new Error(`Agent not found: ${agentId}`);
328
+ }
329
+ const currentBalance = doc.data().balance || 0;
330
+ const newBalance = currentBalance + amount;
331
+ await agentRef.update({ balance: newBalance });
332
+ return newBalance;
333
+ }
334
+ export async function debitBalance(agentId, amount) {
89
335
  const agentRef = collections.agents().doc(agentId);
90
336
  const doc = await agentRef.get();
91
- if (doc.exists) {
92
- const data = doc.data();
93
- const currentStats = data.stats || { tasksCompleted: 0, totalEarned: 0, successRate: 100, avgCompletionTime: 0 };
94
- await agentRef.update({
95
- 'stats.tasksCompleted': currentStats.tasksCompleted + 1,
96
- 'stats.totalEarned': currentStats.totalEarned + amount,
337
+ if (!doc.exists) {
338
+ throw new Error(`Agent not found: ${agentId}`);
339
+ }
340
+ const currentBalance = doc.data().balance || 0;
341
+ if (currentBalance < amount) {
342
+ throw new Error(`Insufficient balance: have ${currentBalance}, need ${amount}`);
343
+ }
344
+ const newBalance = currentBalance - amount;
345
+ await agentRef.update({ balance: newBalance });
346
+ return newBalance;
347
+ }
348
+ // Escrow with balance (new flow)
349
+ export async function createEscrowWithBalance(data) {
350
+ // First, check and debit client balance
351
+ const clientBalance = await getBalance(data.clientAgentId);
352
+ if (clientBalance < data.amount) {
353
+ throw new Error(`Insufficient balance: have ${clientBalance} ${data.currency}, need ${data.amount} ${data.currency}`);
354
+ }
355
+ // Debit the full amount from client
356
+ await debitBalance(data.clientAgentId, data.amount);
357
+ // Create the escrow
358
+ const docRef = collections.escrows().doc();
359
+ const fee = data.amount * FEE_RATE;
360
+ const escrow = {
361
+ ...data,
362
+ fee,
363
+ feeRate: FEE_RATE,
364
+ status: 'pending',
365
+ createdAt: new Date(),
366
+ completedAt: null,
367
+ proofOfWork: null,
368
+ disputeReason: null,
369
+ };
370
+ await docRef.set({
371
+ ...escrow,
372
+ createdAt: Timestamp.fromDate(escrow.createdAt),
373
+ });
374
+ return { id: docRef.id, ...escrow };
375
+ }
376
+ export async function completeEscrowWithBalance(escrowId, proofOfWork) {
377
+ const escrowRef = collections.escrows().doc(escrowId);
378
+ const doc = await escrowRef.get();
379
+ if (!doc.exists) {
380
+ return null;
381
+ }
382
+ const escrowData = doc.data();
383
+ // Credit provider with amount minus fee
384
+ const netAmount = escrowData.amount - (escrowData.fee || escrowData.amount * FEE_RATE);
385
+ await creditBalance(escrowData.providerAgentId, netAmount);
386
+ const completedAt = new Date();
387
+ await escrowRef.update({
388
+ status: 'completed',
389
+ completedAt: Timestamp.fromDate(completedAt),
390
+ proofOfWork,
391
+ });
392
+ const escrow = await getEscrow(escrowId);
393
+ // Update agent stats
394
+ if (escrow) {
395
+ await updateAgentStats(escrow.providerAgentId, netAmount);
396
+ }
397
+ return escrow;
398
+ }
399
+ export async function refundEscrow(escrowId) {
400
+ const escrow = await getEscrow(escrowId);
401
+ if (!escrow) {
402
+ return null;
403
+ }
404
+ if (escrow.status !== 'disputed') {
405
+ throw new Error('Can only refund disputed escrows');
406
+ }
407
+ // Refund full amount to client
408
+ await creditBalance(escrow.clientAgentId, escrow.amount);
409
+ // Update escrow status
410
+ const escrowRef = collections.escrows().doc(escrowId);
411
+ await escrowRef.update({ status: 'cancelled' });
412
+ return getEscrow(escrowId);
413
+ }
414
+ // Withdrawal operations
415
+ export async function createWithdrawal(agentId, amount, currency, paymentMethod) {
416
+ // Check balance
417
+ const balance = await getBalance(agentId);
418
+ if (balance < amount) {
419
+ throw new Error(`Insufficient balance: have ${balance}, need ${amount}`);
420
+ }
421
+ // Debit balance (hold funds)
422
+ await debitBalance(agentId, amount);
423
+ // Create withdrawal record
424
+ const docRef = collections.withdrawals().doc();
425
+ const withdrawal = {
426
+ agentId,
427
+ amount,
428
+ currency,
429
+ status: 'pending',
430
+ paymentMethod,
431
+ requestedAt: new Date(),
432
+ processedAt: null,
433
+ notes: null,
434
+ };
435
+ await docRef.set({
436
+ ...withdrawal,
437
+ requestedAt: Timestamp.fromDate(withdrawal.requestedAt),
438
+ });
439
+ return { id: docRef.id, ...withdrawal };
440
+ }
441
+ export async function getWithdrawal(withdrawalId) {
442
+ const doc = await collections.withdrawals().doc(withdrawalId).get();
443
+ if (!doc.exists) {
444
+ return null;
445
+ }
446
+ const data = doc.data();
447
+ return {
448
+ id: doc.id,
449
+ agentId: data.agentId,
450
+ amount: data.amount,
451
+ currency: data.currency,
452
+ status: data.status,
453
+ paymentMethod: data.paymentMethod,
454
+ requestedAt: data.requestedAt.toDate(),
455
+ processedAt: data.processedAt?.toDate() ?? null,
456
+ notes: data.notes ?? null,
457
+ };
458
+ }
459
+ export async function listWithdrawals(status, limit = 50) {
460
+ // Simple query without compound index - filter in memory
461
+ const snapshot = await collections.withdrawals().limit(limit * 2).get();
462
+ let withdrawals = [];
463
+ for (const doc of snapshot.docs) {
464
+ const w = await getWithdrawal(doc.id);
465
+ if (w) {
466
+ if (!status || w.status === status) {
467
+ withdrawals.push(w);
468
+ }
469
+ }
470
+ }
471
+ // Sort by requestedAt descending and limit
472
+ withdrawals = withdrawals
473
+ .sort((a, b) => b.requestedAt.getTime() - a.requestedAt.getTime())
474
+ .slice(0, limit);
475
+ return withdrawals;
476
+ }
477
+ export async function processWithdrawal(withdrawalId, action, notes) {
478
+ const withdrawal = await getWithdrawal(withdrawalId);
479
+ if (!withdrawal) {
480
+ return null;
481
+ }
482
+ if (withdrawal.status !== 'pending' && withdrawal.status !== 'processing') {
483
+ throw new Error(`Cannot process withdrawal with status: ${withdrawal.status}`);
484
+ }
485
+ const withdrawalRef = collections.withdrawals().doc(withdrawalId);
486
+ if (action === 'complete') {
487
+ await withdrawalRef.update({
488
+ status: 'completed',
489
+ processedAt: Timestamp.fromDate(new Date()),
490
+ notes: notes || 'Payment sent',
491
+ });
492
+ }
493
+ else {
494
+ // Refund the held amount back to agent
495
+ await creditBalance(withdrawal.agentId, withdrawal.amount);
496
+ await withdrawalRef.update({
497
+ status: 'rejected',
498
+ processedAt: Timestamp.fromDate(new Date()),
499
+ notes: notes || 'Withdrawal rejected',
97
500
  });
98
501
  }
502
+ return getWithdrawal(withdrawalId);
99
503
  }
@@ -0,0 +1,104 @@
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
+ import type { Deposit } from '../../types/index.js';
9
+ export interface AlbyPaymentRequest {
10
+ amount: number;
11
+ agentId: string;
12
+ description?: string;
13
+ }
14
+ export interface AlbyPaymentResponse {
15
+ success: boolean;
16
+ deposit?: Partial<Deposit>;
17
+ invoice?: {
18
+ paymentHash: string;
19
+ paymentRequest: string;
20
+ amountSats: number;
21
+ expiresAt: Date;
22
+ };
23
+ error?: string;
24
+ }
25
+ /**
26
+ * Convert USD to sats
27
+ */
28
+ declare function usdToSats(usd: number): number;
29
+ /**
30
+ * Convert sats to USD
31
+ */
32
+ declare function satsToUsd(sats: number): number;
33
+ /**
34
+ * Create a Lightning invoice for BTC deposit
35
+ */
36
+ export declare function createAlbyDeposit(request: AlbyPaymentRequest): Promise<AlbyPaymentResponse>;
37
+ /**
38
+ * Check invoice status
39
+ */
40
+ export declare function getInvoiceStatus(paymentHash: string): Promise<{
41
+ success: boolean;
42
+ status?: string;
43
+ paid?: boolean;
44
+ amountSats?: number;
45
+ amountUsd?: number;
46
+ error?: string;
47
+ }>;
48
+ /**
49
+ * Process webhook callback from Alby
50
+ */
51
+ export declare function parseWebhookPayload(body: Record<string, any>): {
52
+ paymentHash: string;
53
+ status: string;
54
+ amountSats: number;
55
+ amountUsd: number;
56
+ memo: string;
57
+ };
58
+ /**
59
+ * Send Lightning payment (for withdrawals)
60
+ */
61
+ export declare function sendAlbyPayment(destination: string, // Lightning invoice or Lightning Address
62
+ amountUsd: number): Promise<{
63
+ success: boolean;
64
+ paymentHash?: string;
65
+ error?: string;
66
+ }>;
67
+ /**
68
+ * Get wallet balance
69
+ */
70
+ export declare function getWalletBalance(): Promise<{
71
+ success: boolean;
72
+ balanceSats?: number;
73
+ balanceUsd?: number;
74
+ error?: string;
75
+ }>;
76
+ /**
77
+ * Decode a Lightning invoice to get amount and details
78
+ */
79
+ export declare function decodeInvoice(invoice: string): Promise<{
80
+ success: boolean;
81
+ amountSats?: number;
82
+ amountUsd?: number;
83
+ description?: string;
84
+ paymentHash?: string;
85
+ expiresAt?: Date;
86
+ error?: string;
87
+ }>;
88
+ export declare const albyService: {
89
+ createDeposit: typeof createAlbyDeposit;
90
+ getInvoiceStatus: typeof getInvoiceStatus;
91
+ parseWebhookPayload: typeof parseWebhookPayload;
92
+ sendPayment: typeof sendAlbyPayment;
93
+ getWalletBalance: typeof getWalletBalance;
94
+ decodeInvoice: typeof decodeInvoice;
95
+ usdToSats: typeof usdToSats;
96
+ satsToUsd: typeof satsToUsd;
97
+ config: {
98
+ configured: boolean;
99
+ nwcConfigured: boolean;
100
+ webhookUrl: string;
101
+ satsPerUsd: number;
102
+ };
103
+ };
104
+ export {};