diff --git a/src/extension/background-script/connectors/nwc.ts b/src/extension/background-script/connectors/nwc.ts index df246bc1be..edc5a592a6 100644 --- a/src/extension/background-script/connectors/nwc.ts +++ b/src/extension/background-script/connectors/nwc.ts @@ -1,8 +1,8 @@ -import { webln } from "@getalby/sdk"; -import { NostrWebLNProvider } from "@getalby/sdk/dist/webln"; +import { nwc } from "@getalby/sdk"; import lightningPayReq from "bolt11-signet"; import Base64 from "crypto-js/enc-base64"; import Hex from "crypto-js/enc-hex"; +import UTF8 from "crypto-js/enc-utf8"; import SHA256 from "crypto-js/sha256"; import { Account } from "~/types"; import Connector, { @@ -35,9 +35,14 @@ interface Config { nostrWalletConnectUrl: string; } +interface TlvRecord { + type: number; + value: string; +} + class NWCConnector implements Connector { config: Config; - nwc: NostrWebLNProvider; + nwc: nwc.NWCClient; get supportedMethods() { return [ @@ -54,13 +59,13 @@ class NWCConnector implements Connector { constructor(account: Account, config: Config) { this.config = config; - this.nwc = new webln.NostrWebLNProvider({ + this.nwc = new nwc.NWCClient({ nostrWalletConnectUrl: this.config.nostrWalletConnectUrl, }); } async init() { - return this.nwc.enable(); + return Promise.resolve(); } async unload() { @@ -70,14 +75,14 @@ class NWCConnector implements Connector { async getInfo(): Promise { const info = await this.nwc.getInfo(); return { - data: info.node, + data: info, }; } async getBalance(): Promise { const balance = await this.nwc.getBalance(); return { - data: { balance: balance.balance, currency: "BTC" }, + data: { balance: Math.floor(balance.balance / 1000), currency: "BTC" }, }; } @@ -96,9 +101,9 @@ class NWCConnector implements Connector { payment_hash: transaction.payment_hash, settled: true, settleDate: transaction.settled_at * 1000, - totalAmount: transaction.amount, + totalAmount: Math.floor(transaction.amount / 1000), type: transaction.type == "incoming" ? "received" : "sent", - custom_records: mapTLVRecords( + custom_records: this.tlvToCustomRecords( transaction.metadata?.["tlv_records"] as TLVRecord[] | undefined ), }) @@ -112,22 +117,17 @@ class NWCConnector implements Connector { async makeInvoice(args: MakeInvoiceArgs): Promise { const invoice = await this.nwc.makeInvoice({ - amount: args.amount, - defaultMemo: args.memo, + amount: + typeof args.amount === "number" + ? args.amount * 1000 + : parseInt(args.amount) * 1000 || 0, + description: args.memo, }); - const decodedInvoice = lightningPayReq.decode(invoice.paymentRequest); - const paymentHash = decodedInvoice.tags.find( - (tag) => tag.tagName === "payment_hash" - )?.data as string | undefined; - if (!paymentHash) { - throw new Error("Could not find payment hash in invoice"); - } - return { data: { - paymentRequest: invoice.paymentRequest, - rHash: paymentHash, + paymentRequest: invoice.invoice, + rHash: invoice.payment_hash, }, }; } @@ -141,15 +141,18 @@ class NWCConnector implements Connector { throw new Error("Could not find payment hash in invoice"); } - const response = await this.nwc.sendPayment(args.paymentRequest); + const response = await this.nwc.payInvoice({ + invoice: args.paymentRequest, + }); + return { data: { preimage: response.preimage, paymentHash, route: { // TODO: how to get amount paid for zero-amount invoices? - total_amt: parseInt(invoice.millisatoshis || "0") / 1000, - // TODO: How to get fees from WebLN? + total_amt: Math.floor(parseInt(invoice.millisatoshis || "0") / 1000), + // TODO: How to get fees? total_fees: 0, }, }, @@ -157,10 +160,10 @@ class NWCConnector implements Connector { } async keysend(args: KeysendArgs): Promise { - const data = await this.nwc.keysend({ - destination: args.pubkey, - amount: args.amount, - customRecords: args.customRecords, + const data = await this.nwc.payKeysend({ + pubkey: args.pubkey, + amount: args.amount * 1000, + tlv_records: this.customRecordsToTlv(args.customRecords), }); const paymentHash = SHA256(data.preimage).toString(Hex); @@ -172,7 +175,7 @@ class NWCConnector implements Connector { route: { total_amt: args.amount, - // TODO: How to get fees from WebLN? + // TODO: How to get fees? total_fees: 0, }, }, @@ -182,12 +185,12 @@ class NWCConnector implements Connector { async checkPayment(args: CheckPaymentArgs): Promise { try { const response = await this.nwc.lookupInvoice({ - paymentHash: args.paymentHash, + payment_hash: args.paymentHash, }); return { data: { - paid: response.paid, + paid: !!response.settled_at, preimage: response.preimage, }, }; @@ -202,7 +205,7 @@ class NWCConnector implements Connector { } async signMessage(args: SignMessageArgs): Promise { - const response = await this.nwc.signMessage(args.message); + const response = await this.nwc.signMessage({ message: args.message }); return Promise.resolve({ data: { @@ -215,21 +218,32 @@ class NWCConnector implements Connector { connectPeer(args: ConnectPeerArgs): Promise { throw new Error("Method not implemented."); } -} -function mapTLVRecords( - tlvRecords: TLVRecord[] | undefined -): ConnectorTransaction["custom_records"] | undefined { - if (!tlvRecords) { - return undefined; + private customRecordsToTlv( + customRecords: Record + ): TlvRecord[] { + return Object.entries(customRecords).map(([key, value]) => ({ + type: parseInt(key), + value: UTF8.parse(value).toString(Hex), + })); } - const customRecords: ConnectorTransaction["custom_records"] = {}; - for (const tlv of tlvRecords) { - // TODO: ConnectorTransaction["custom_records"] should not be in base64 format - // as this requires unnecessary re-encoding - customRecords[tlv.type.toString()] = Hex.parse(tlv.value).toString(Base64); + + private tlvToCustomRecords( + tlvRecords: TLVRecord[] | undefined + ): ConnectorTransaction["custom_records"] | undefined { + if (!tlvRecords) { + return undefined; + } + const customRecords: ConnectorTransaction["custom_records"] = {}; + for (const tlv of tlvRecords) { + // TODO: ConnectorTransaction["custom_records"] should not be in base64 format + // as this requires unnecessary re-encoding + customRecords[tlv.type.toString()] = Hex.parse(tlv.value).toString( + Base64 + ); + } + return customRecords; } - return customRecords; } export default NWCConnector;