6ef4f4bfe0d4735222414b10ddedfb81f173b1556bb07db64135b518a65f7f01.json raw

   1  {"ast":null,"code":"import _asyncToGenerator from \"/home/mleku/src/orly.dev/next/signer/node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js\";\nimport { BehaviorSubject } from 'rxjs';\nimport { NwcClient } from './nwc-client';\nimport { parseNwcUrl } from '../storage/related/nwc';\nimport * as i0 from \"@angular/core\";\nimport * as i1 from \"@common\";\n/**\n * Angular service for managing NWC wallet connections\n */\nexport let NwcService = /*#__PURE__*/(() => {\n  class NwcService {\n    storageService;\n    clients = new Map();\n    _logs$ = new BehaviorSubject([]);\n    maxLogs = 100;\n    /** Observable stream of NWC log entries */\n    logs$ = this._logs$.asObservable();\n    constructor(storageService) {\n      this.storageService = storageService;\n    }\n    /** Get current logs */\n    get logs() {\n      return this._logs$.value;\n    }\n    /** Clear all logs */\n    clearLogs() {\n      this._logs$.next([]);\n    }\n    /** Add a log entry */\n    addLog(level, message) {\n      const entry = {\n        timestamp: new Date(),\n        level,\n        message\n      };\n      const logs = [entry, ...this._logs$.value].slice(0, this.maxLogs);\n      this._logs$.next(logs);\n    }\n    /** Create a log callback for the NWC client */\n    createLogCallback() {\n      return (level, message) => {\n        this.addLog(level, message);\n      };\n    }\n    /**\n     * Parse and validate an NWC URL\n     */\n    parseNwcUrl(url) {\n      return parseNwcUrl(url);\n    }\n    /**\n     * Get all NWC connections from storage\n     */\n    getConnections() {\n      const sessionData = this.storageService.getBrowserSessionHandler().browserSessionData;\n      return sessionData?.nwcConnections ?? [];\n    }\n    /**\n     * Get a single NWC connection by ID\n     */\n    getConnection(connectionId) {\n      return this.getConnections().find(c => c.id === connectionId);\n    }\n    /**\n     * Add a new NWC connection\n     */\n    addConnection(name, connectionUrl) {\n      var _this = this;\n      return _asyncToGenerator(function* () {\n        yield _this.storageService.addNwcConnection({\n          name,\n          connectionUrl\n        });\n      })();\n    }\n    /**\n     * Delete an NWC connection\n     */\n    deleteConnection(connectionId) {\n      var _this2 = this;\n      return _asyncToGenerator(function* () {\n        // Disconnect and remove the client if it exists\n        _this2.disconnectClient(connectionId);\n        yield _this2.storageService.deleteNwcConnection(connectionId);\n      })();\n    }\n    /**\n     * Get a connected client for a connection, creating it if necessary\n     */\n    getClient(connectionId) {\n      var _this3 = this;\n      return _asyncToGenerator(function* () {\n        // Check if we have a cached client\n        const cached = _this3.clients.get(connectionId);\n        if (cached && cached.client.isConnected()) {\n          return cached.client;\n        }\n        // Get the connection data\n        const connection = _this3.getConnection(connectionId);\n        if (!connection) {\n          throw new Error('Connection not found');\n        }\n        // Create a new client\n        const connectionData = {\n          walletPubkey: connection.walletPubkey,\n          relayUrl: connection.relayUrl,\n          secret: connection.secret\n        };\n        const client = new NwcClient(connectionData, _this3.createLogCallback());\n        yield client.connect();\n        // Cache the client\n        _this3.clients.set(connectionId, {\n          client,\n          connectionId\n        });\n        return client;\n      })();\n    }\n    /**\n     * Disconnect a client\n     */\n    disconnectClient(connectionId) {\n      const cached = this.clients.get(connectionId);\n      if (cached) {\n        cached.client.disconnect();\n        this.clients.delete(connectionId);\n      }\n    }\n    /**\n     * Disconnect all clients\n     */\n    disconnectAll() {\n      for (const cached of this.clients.values()) {\n        cached.client.disconnect();\n      }\n      this.clients.clear();\n    }\n    /**\n     * Get wallet info for a connection\n     */\n    getInfo(connectionId) {\n      var _this4 = this;\n      return _asyncToGenerator(function* () {\n        const client = yield _this4.getClient(connectionId);\n        return client.getInfo();\n      })();\n    }\n    /**\n     * Get balance for a connection (in millisatoshis)\n     */\n    getBalance(connectionId) {\n      var _this5 = this;\n      return _asyncToGenerator(function* () {\n        const client = yield _this5.getClient(connectionId);\n        const result = yield client.getBalance();\n        // Update the cached balance in storage\n        yield _this5.storageService.updateNwcConnectionBalance(connectionId, result.balance);\n        return result.balance;\n      })();\n    }\n    /**\n     * Get balances for all connections\n     * Returns a map of connectionId -> balance in millisatoshis\n     */\n    getAllBalances() {\n      var _this6 = this;\n      return _asyncToGenerator(function* () {\n        const balances = new Map();\n        const connections = _this6.getConnections();\n        const results = yield Promise.allSettled(connections.map(/*#__PURE__*/function () {\n          var _ref = _asyncToGenerator(function* (conn) {\n            try {\n              const balance = yield _this6.getBalance(conn.id);\n              return {\n                id: conn.id,\n                balance\n              };\n            } catch (error) {\n              // Return cached balance if available\n              if (conn.cachedBalance !== undefined) {\n                return {\n                  id: conn.id,\n                  balance: conn.cachedBalance\n                };\n              }\n              throw error;\n            }\n          });\n          return function (_x) {\n            return _ref.apply(this, arguments);\n          };\n        }()));\n        for (const result of results) {\n          if (result.status === 'fulfilled') {\n            balances.set(result.value.id, result.value.balance);\n          }\n        }\n        return balances;\n      })();\n    }\n    /**\n     * Get total balance across all connections (in millisatoshis)\n     */\n    getTotalBalance() {\n      var _this7 = this;\n      return _asyncToGenerator(function* () {\n        const balances = yield _this7.getAllBalances();\n        let total = 0;\n        for (const balance of balances.values()) {\n          total += balance;\n        }\n        return total;\n      })();\n    }\n    /**\n     * Get cached total balance (without making network requests)\n     */\n    getCachedTotalBalance() {\n      const connections = this.getConnections();\n      let total = 0;\n      for (const conn of connections) {\n        if (conn.cachedBalance !== undefined) {\n          total += conn.cachedBalance;\n        }\n      }\n      return total;\n    }\n    /**\n     * Pay a Lightning invoice\n     */\n    payInvoice(connectionId, invoice, amountMsat) {\n      var _this8 = this;\n      return _asyncToGenerator(function* () {\n        const client = yield _this8.getClient(connectionId);\n        const result = yield client.payInvoice({\n          invoice,\n          amount: amountMsat\n        });\n        // Refresh balance after payment\n        try {\n          yield _this8.getBalance(connectionId);\n        } catch {\n          // Ignore balance refresh errors\n        }\n        return result;\n      })();\n    }\n    /**\n     * Create a Lightning invoice\n     */\n    makeInvoice(connectionId, amountMsat, description) {\n      var _this9 = this;\n      return _asyncToGenerator(function* () {\n        const client = yield _this9.getClient(connectionId);\n        return client.makeInvoice({\n          amount: amountMsat,\n          description\n        });\n      })();\n    }\n    /**\n     * List transaction history\n     */\n    listTransactions(connectionId, params) {\n      var _this0 = this;\n      return _asyncToGenerator(function* () {\n        const client = yield _this0.getClient(connectionId);\n        const result = yield client.listTransactions(params);\n        return result.transactions;\n      })();\n    }\n    /**\n     * Resolve a Lightning Address (user@domain.com) to a bolt11 invoice\n     * Uses LNURL-pay protocol\n     */\n    resolveLightningAddress(address, amountMsat) {\n      var _this1 = this;\n      return _asyncToGenerator(function* () {\n        // Parse lightning address\n        const match = address.match(/^([^@]+)@([^@]+)$/);\n        if (!match) {\n          throw new Error('Invalid lightning address format');\n        }\n        const [, name, domain] = match;\n        // Fetch LNURL-pay endpoint\n        const lnurlpUrl = `https://${domain}/.well-known/lnurlp/${name}`;\n        _this1.addLog('info', `Fetching LNURL-pay from ${domain}...`);\n        const response = yield fetch(lnurlpUrl);\n        if (!response.ok) {\n          throw new Error(`Failed to fetch LNURL-pay: ${response.status}`);\n        }\n        const lnurlpData = yield response.json();\n        // Validate response\n        if (lnurlpData.status === 'ERROR') {\n          throw new Error(lnurlpData.reason || 'LNURL-pay error');\n        }\n        if (!lnurlpData.callback) {\n          throw new Error('Invalid LNURL-pay response: missing callback');\n        }\n        // Check amount bounds\n        const minSendable = lnurlpData.minSendable || 1000;\n        const maxSendable = lnurlpData.maxSendable || 100000000000;\n        if (amountMsat < minSendable) {\n          throw new Error(`Amount too small. Minimum: ${Math.ceil(minSendable / 1000)} sats`);\n        }\n        if (amountMsat > maxSendable) {\n          throw new Error(`Amount too large. Maximum: ${Math.floor(maxSendable / 1000)} sats`);\n        }\n        // Request invoice from callback\n        const callbackUrl = new URL(lnurlpData.callback);\n        callbackUrl.searchParams.set('amount', amountMsat.toString());\n        _this1.addLog('info', 'Requesting invoice...');\n        const invoiceResponse = yield fetch(callbackUrl.toString());\n        if (!invoiceResponse.ok) {\n          throw new Error(`Failed to get invoice: ${invoiceResponse.status}`);\n        }\n        const invoiceData = yield invoiceResponse.json();\n        if (invoiceData.status === 'ERROR') {\n          throw new Error(invoiceData.reason || 'Failed to get invoice');\n        }\n        if (!invoiceData.pr) {\n          throw new Error('Invalid invoice response: missing payment request');\n        }\n        _this1.addLog('info', 'Invoice received');\n        return invoiceData.pr;\n      })();\n    }\n    /**\n     * Check if a string is a lightning address (user@domain)\n     */\n    isLightningAddress(input) {\n      return /^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$/.test(input);\n    }\n    /**\n     * Check if a string is a bolt11 invoice\n     */\n    isBolt11Invoice(input) {\n      return /^ln(bc|tb|tbs)[0-9a-z]+$/i.test(input.toLowerCase());\n    }\n    /**\n     * Test a connection by getting wallet info\n     */\n    testConnection(connectionUrl) {\n      var _this10 = this;\n      return _asyncToGenerator(function* () {\n        _this10.addLog('info', 'Testing NWC connection...');\n        const parsed = _this10.parseNwcUrl(connectionUrl);\n        if (!parsed) {\n          _this10.addLog('error', 'Invalid NWC URL');\n          throw new Error('Invalid NWC URL');\n        }\n        const client = new NwcClient(parsed, _this10.createLogCallback());\n        try {\n          yield client.connect();\n          const info = yield client.getInfo();\n          _this10.addLog('info', `Connection test successful: ${info.alias || 'wallet'}`);\n          return info;\n        } catch (error) {\n          _this10.addLog('error', `Connection test failed: ${error.message}`);\n          throw error;\n        } finally {\n          client.disconnect();\n        }\n      })();\n    }\n    static ɵfac = function NwcService_Factory(__ngFactoryType__) {\n      return new (__ngFactoryType__ || NwcService)(i0.ɵɵinject(i1.StorageService));\n    };\n    static ɵprov = /*@__PURE__*/i0.ɵɵdefineInjectable({\n      token: NwcService,\n      factory: NwcService.ɵfac,\n      providedIn: 'root'\n    });\n  }\n  return NwcService;\n})();","map":null,"metadata":{},"sourceType":"module","externalDependencies":[]}