From 07474a836ef1cae2597d1afd8e4e5f32a7bf6e9b Mon Sep 17 00:00:00 2001 From: Kieran Date: Tue, 6 May 2025 12:50:04 +0100 Subject: [PATCH] chore: remove lnc / cashu wallets --- .../app/src/Pages/settings/WalletSettings.tsx | 14 -- .../app/src/Pages/settings/wallet/Cashu.txt | 78 -------- .../app/src/Pages/settings/wallet/LNC.tsx | 123 ------------ .../app/src/Pages/settings/wallet/index.tsx | 10 - packages/app/src/lang.json | 18 -- packages/app/src/translations/en.json | 6 - packages/wallet/package.json | 2 - packages/wallet/src/Cashu.ts | 104 ---------- packages/wallet/src/LNCWallet.ts | 182 ------------------ packages/wallet/src/index.ts | 16 +- 10 files changed, 3 insertions(+), 550 deletions(-) delete mode 100644 packages/app/src/Pages/settings/wallet/Cashu.txt delete mode 100644 packages/app/src/Pages/settings/wallet/LNC.tsx delete mode 100644 packages/wallet/src/Cashu.ts delete mode 100644 packages/wallet/src/LNCWallet.ts diff --git a/packages/app/src/Pages/settings/WalletSettings.tsx b/packages/app/src/Pages/settings/WalletSettings.tsx index 4312dfb6..2923ad6b 100644 --- a/packages/app/src/Pages/settings/WalletSettings.tsx +++ b/packages/app/src/Pages/settings/WalletSettings.tsx @@ -2,10 +2,8 @@ import { ReactNode } from "react"; import { FormattedMessage } from "react-intl"; import { useNavigate } from "react-router-dom"; -import LndLogo from "@/assets/img/lnd-logo.png"; import AlbyIcon from "@/Components/Icons/Alby"; import BlueWallet from "@/Components/Icons/BlueWallet"; -//import CashuIcon from "@/Components/Icons/Cashu"; import Icon from "@/Components/Icons/Icon"; import NWCIcon from "@/Components/Icons/NWC"; import { getAlbyOAuth } from "@/Pages/settings/wallet/utils"; @@ -57,24 +55,12 @@ const WalletSettings = () => { url="/settings/wallet/nwc" desc={} /> - } - name="LND via LNC" - url="/settings/wallet/lnc" - desc={} - /> } name="LNDHub" url="/settings/wallet/lndhub" desc={} /> - {/*} - name="Cashu" - url="/settings/wallet/cashu" - desc={} - />*/} {CONFIG.alby && ( } diff --git a/packages/app/src/Pages/settings/wallet/Cashu.txt b/packages/app/src/Pages/settings/wallet/Cashu.txt deleted file mode 100644 index 820d786a..00000000 --- a/packages/app/src/Pages/settings/wallet/Cashu.txt +++ /dev/null @@ -1,78 +0,0 @@ -import { CashuWallet, WalletKind } from "@snort/wallet"; -import { useState } from "react"; -import { FormattedMessage, useIntl } from "react-intl"; -import { useNavigate } from "react-router-dom"; -import { v4 as uuid } from "uuid"; - -import AsyncButton from "@/Components/Button/AsyncButton"; -import { unwrap } from "@/Utils"; -import { WalletConfig, Wallets } from "@/Wallet"; - -const ConnectCashu = () => { - const navigate = useNavigate(); - const { formatMessage } = useIntl(); - const [mintUrl, setMintUrl] = useState("https://8333.space:3338"); - const [error, setError] = useState(); - - async function tryConnect(config: string) { - try { - if (!mintUrl) { - throw new Error("Mint URL is required"); - } - - const connection = new CashuWallet({ - url: config, - keys: {}, - proofs: [], - keysets: [], - }); - await connection.login(); - const info = await connection.getInfo(); - const newWallet = { - id: uuid(), - kind: WalletKind.Cashu, - active: true, - info, - data: JSON.stringify(connection.getConfig()), - } as WalletConfig; - Wallets.add(newWallet); - navigate("/settings/wallet"); - } catch (e) { - if (e instanceof Error) { - setError((e as Error).message); - } else { - setError( - formatMessage({ - defaultMessage: "Unknown error", - id: "qDwvZ4", - }), - ); - } - } - } - - return ( - <> -

- -

-
-
- setMintUrl(e.target.value)} - /> -
- tryConnect(unwrap(mintUrl))} disabled={!mintUrl}> - - -
- {error && {error}} - - ); -}; - -export default ConnectCashu; diff --git a/packages/app/src/Pages/settings/wallet/LNC.tsx b/packages/app/src/Pages/settings/wallet/LNC.tsx deleted file mode 100644 index 2785131b..00000000 --- a/packages/app/src/Pages/settings/wallet/LNC.tsx +++ /dev/null @@ -1,123 +0,0 @@ -import { LNCWallet, LNWallet, WalletInfo, WalletKind } from "@snort/wallet"; -import { useState } from "react"; -import { FormattedMessage, useIntl } from "react-intl"; -import { useNavigate } from "react-router-dom"; -import { v4 as uuid } from "uuid"; - -import AsyncButton from "@/Components/Button/AsyncButton"; -import { unwrap } from "@/Utils"; -import { Wallets } from "@/Wallet"; - -const ConnectLNC = () => { - const { formatMessage } = useIntl(); - const navigate = useNavigate(); - const [pairingPhrase, setPairingPhrase] = useState(); - const [error, setError] = useState(); - const [connectedLNC, setConnectedLNC] = useState(); - const [walletInfo, setWalletInfo] = useState(); - const [walletPassword, setWalletPassword] = useState(); - - async function tryConnect(cfg: string) { - try { - const lnc = await LNCWallet.Initialize(cfg); - const info = await lnc.getInfo(); - - // prompt password - setConnectedLNC(lnc); - setWalletInfo(info as WalletInfo); - } catch (e) { - if (e instanceof Error) { - setError(e.message); - } else { - setError( - formatMessage({ - defaultMessage: "Unknown error", - id: "qDwvZ4", - }), - ); - } - } - } - - function setLNCPassword(pw: string) { - connectedLNC?.setPassword(pw); - Wallets.add({ - id: uuid(), - kind: WalletKind.LNC, - active: true, - info: unwrap(walletInfo), - }); - navigate("/settings/wallet"); - } - - function flowConnect() { - if (connectedLNC) return null; - return ( - <> -

- -

-
-
- setPairingPhrase(e.target.value)} - /> -
- tryConnect(unwrap(pairingPhrase))} disabled={!pairingPhrase}> - - -
- {error && {error}} - - ); - } - - function flowSetPassword() { - if (!connectedLNC) return null; - return ( -
-

- -

-

- -

-
-
- setWalletPassword(e.target.value)} - /> -
- setLNCPassword(unwrap(walletPassword))} - disabled={(walletPassword?.length ?? 0) < 8}> - - -
-
- ); - } - - return ( - <> - {flowConnect()} - {flowSetPassword()} - - ); -}; - -export default ConnectLNC; diff --git a/packages/app/src/Pages/settings/wallet/index.tsx b/packages/app/src/Pages/settings/wallet/index.tsx index d6c8a3e6..231d3a0c 100644 --- a/packages/app/src/Pages/settings/wallet/index.tsx +++ b/packages/app/src/Pages/settings/wallet/index.tsx @@ -2,8 +2,6 @@ import { RouteObject } from "react-router-dom"; import WalletSettings from "../WalletSettings"; import AlbyOAuth from "./Alby"; -//import ConnectCashu from "./Cashu"; -import ConnectLNC from "./LNC"; import ConnectLNDHub from "./LNDHub"; import ConnectNostrWallet from "./NWC"; @@ -12,10 +10,6 @@ export const WalletSettingsRoutes = [ path: "/settings/wallet", element: , }, - { - path: "/settings/wallet/lnc", - element: , - }, { path: "/settings/wallet/lndhub", element: , @@ -24,10 +18,6 @@ export const WalletSettingsRoutes = [ path: "/settings/wallet/nwc", element: , }, - /*{ - path: "/settings/wallet/cashu", - element: , - },*/ { path: "/settings/wallet/alby", element: , diff --git a/packages/app/src/lang.json b/packages/app/src/lang.json index 5d61cdb1..21591882 100644 --- a/packages/app/src/lang.json +++ b/packages/app/src/lang.json @@ -129,9 +129,6 @@ "1UWegE": { "defaultMessage": "Be sure to back up your keys!" }, - "1c4YST": { - "defaultMessage": "Connected to: {node} 🎉" - }, "1nYUGC": { "defaultMessage": "{n} Following" }, @@ -168,9 +165,6 @@ "2IFGap": { "defaultMessage": "Donate" }, - "2LbrkB": { - "defaultMessage": "Enter password" - }, "2O2sfp": { "defaultMessage": "Finish" }, @@ -456,9 +450,6 @@ "8jmwT8": { "defaultMessage": "bech32-encoded entities" }, - "8v1NN+": { - "defaultMessage": "Pairing phrase" - }, "8xdDLn": { "defaultMessage": "Follow sets" }, @@ -1512,9 +1503,6 @@ "Z48UEo": { "defaultMessage": "Channel Metadata" }, - "Z4BMCZ": { - "defaultMessage": "Enter pairing phrase" - }, "Z7kkeJ": { "defaultMessage": "Delegated Event Signing" }, @@ -1560,9 +1548,6 @@ "aRex7h": { "defaultMessage": "Paid {amount} sats, fee {fee} sats" }, - "aSGz4J": { - "defaultMessage": "Connect to your own LND node with Lightning Node Connect" - }, "aWpBzj": { "defaultMessage": "Show more" }, @@ -2008,9 +1993,6 @@ "lPWASz": { "defaultMessage": "Snort nostr address" }, - "lTbT3s": { - "defaultMessage": "Wallet password" - }, "lbr3Lq": { "defaultMessage": "Copy link" }, diff --git a/packages/app/src/translations/en.json b/packages/app/src/translations/en.json index 6f51edbc..9bc4dbec 100644 --- a/packages/app/src/translations/en.json +++ b/packages/app/src/translations/en.json @@ -42,7 +42,6 @@ "1Mo59U": "Are you sure you want to remove this note from bookmarks?", "1R43+L": "Enter Nostr Wallet Connect config", "1UWegE": "Be sure to back up your keys!", - "1c4YST": "Connected to: {node} 🎉", "1nYUGC": "{n} Following", "1o2BgB": "Check Signatures", "1ozeyg": "Nature", @@ -55,7 +54,6 @@ "2BBGxX": "Subject tag in text events", "2HIqeO": "User emoji list", "2IFGap": "Donate", - "2LbrkB": "Enter password", "2O2sfp": "Finish", "2Qsf9/": "Generic lists", "2YxhJx": "Reserved Cashu Wallet Tokens", @@ -151,7 +149,6 @@ "8Y6bZQ": "Invalid zap split: {input}", "8g2vyB": "name too long", "8jmwT8": "bech32-encoded entities", - "8v1NN+": "Pairing phrase", "8xdDLn": "Follow sets", "8za9Pq": "Draft Classified Listing", "9+Ddtu": "Next", @@ -501,7 +498,6 @@ "Yf3DwC": "Connect a wallet to send instant payments", "YuoEb9": "Try another relay", "Z48UEo": "Channel Metadata", - "Z4BMCZ": "Enter pairing phrase", "Z7kkeJ": "Delegated Event Signing", "ZFe9tl": "Compose a note", "ZKORll": "Activate Now", @@ -517,7 +513,6 @@ "aHje0o": "Name or nym", "aMaLBK": "Supported Extensions", "aRex7h": "Paid {amount} sats, fee {fee} sats", - "aSGz4J": "Connect to your own LND node with Lightning Node Connect", "aWpBzj": "Show more", "abbGKq": "{n} km", "ak3MTf": "Invite Friends", @@ -666,7 +661,6 @@ "lD3+8a": "Pay", "lEnclp": "My events: {n}", "lPWASz": "Snort nostr address", - "lTbT3s": "Wallet password", "lbr3Lq": "Copy link", "lfOesV": "Non-Zap", "lgg1KN": "account page", diff --git a/packages/wallet/package.json b/packages/wallet/package.json index e695eb6a..e378879c 100644 --- a/packages/wallet/package.json +++ b/packages/wallet/package.json @@ -19,8 +19,6 @@ ], "packageManager": "yarn@4.1.1", "dependencies": { - "@cashu/cashu-ts": "^1.0.0-rc.3", - "@lightninglabs/lnc-web": "^0.3.1-alpha", "@scure/base": "^1.1.6", "@snort/shared": "^1.0.17", "@snort/system": "^1.6.1", diff --git a/packages/wallet/src/Cashu.ts b/packages/wallet/src/Cashu.ts deleted file mode 100644 index cdac31bd..00000000 --- a/packages/wallet/src/Cashu.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { CashuMint, Proof } from "@cashu/cashu-ts"; - -import { InvoiceRequest, LNWallet, WalletEvents, WalletInfo, WalletInvoice } from "."; -import EventEmitter from "eventemitter3"; - -export type CashuWalletConfig = { - url: string; - keys: Record; - keysets: Array; - proofs: Array; -}; - -export class CashuWallet extends EventEmitter implements LNWallet { - #wallet: CashuWalletConfig; - #mint: CashuMint; - - constructor(wallet: CashuWalletConfig) { - super(); - this.#wallet = wallet; - this.#mint = new CashuMint(this.#wallet.url); - } - - getConfig() { - return { ...this.#wallet }; - } - - canGetInvoices() { - return false; - } - - canGetBalance() { - return true; - } - - canAutoLogin() { - return true; - } - - isReady() { - return true; - } - - canCreateInvoice() { - return true; - } - - canPayInvoice() { - return true; - } - - async getInfo() { - return { - alias: "Cashu mint: " + this.#wallet.url, - } as WalletInfo; - } - - async login(): Promise { - if (this.#wallet.keysets.length === 0) { - const keys = await this.#mint.getKeys(); - this.#wallet.keys = keys; - this.#wallet.keysets = [""]; - this.onChange(this.#wallet); - } - await this.#checkProofs(); - return true; - } - - close(): Promise { - return Promise.resolve(true); - } - - async getBalance() { - return this.#wallet.proofs.reduce((acc, v) => (acc += v.amount), 0); - } - - async createInvoice(req: InvoiceRequest) { - const rsp = await this.#mint.requestMint(req.amount); - return { - pr: rsp.pr, - } as WalletInvoice; - } - - payInvoice(): Promise { - throw new Error("Method not implemented."); - } - - getInvoices(): Promise { - return Promise.resolve([]); - } - - async #checkProofs() { - if (this.#wallet.proofs.length == 0) return; - - const checks = await this.#mint.check({ - proofs: this.#wallet.proofs.map(a => ({ secret: a.secret })), - }); - - const filteredProofs = this.#wallet.proofs.filter((_, i) => checks.spendable[i]); - this.#wallet.proofs = filteredProofs; - if (filteredProofs.length !== checks.spendable.length) { - this.emit("change", JSON.stringify(this.#wallet)); - } - } -} diff --git a/packages/wallet/src/LNCWallet.ts b/packages/wallet/src/LNCWallet.ts deleted file mode 100644 index 21bd8a20..00000000 --- a/packages/wallet/src/LNCWallet.ts +++ /dev/null @@ -1,182 +0,0 @@ -import LNC from "@lightninglabs/lnc-web"; -import debug from "debug"; - -import { - InvoiceRequest, - LNWallet, - Login, - prToWalletInvoice, - WalletError, - WalletErrorCode, - WalletEvents, - WalletInfo, - WalletInvoice, - WalletInvoiceState, -} from "."; -import { unwrap } from "@snort/shared"; -import EventEmitter from "eventemitter3"; - -enum Payment_PaymentStatus { - UNKNOWN = "UNKNOWN", - IN_FLIGHT = "IN_FLIGHT", - SUCCEEDED = "SUCCEEDED", - FAILED = "FAILED", - UNRECOGNIZED = "UNRECOGNIZED", -} - -export class LNCWallet extends EventEmitter implements LNWallet { - #lnc: LNC; - readonly #log = debug("LNC"); - - private constructor(pairingPhrase?: string, password?: string) { - super(); - this.#lnc = new LNC({ - pairingPhrase, - password, - }); - } - - canAutoLogin() { - return false; - } - - canGetInvoices() { - return true; - } - - canGetBalance() { - return true; - } - - canCreateInvoice() { - return true; - } - - canPayInvoice() { - return true; - } - - isReady(): boolean { - return this.#lnc.isReady; - } - - static async Initialize(pairingPhrase: string) { - const lnc = new LNCWallet(pairingPhrase); - await lnc.login(); - return lnc; - } - - static Empty() { - return new LNCWallet(); - } - - setPassword(pw: string) { - if (this.#lnc.credentials.password && pw !== this.#lnc.credentials.password) { - throw new WalletError(WalletErrorCode.GeneralError, "Password is already set, cannot update password"); - } - this.#lnc.credentials.password = pw; - } - - createAccount(): Promise { - throw new Error("Not implemented"); - } - - async getInfo(): Promise { - const nodeInfo = await this.#lnc.lnd.lightning.getInfo(); - return { - nodePubKey: nodeInfo.identityPubkey, - alias: nodeInfo.alias, - } as WalletInfo; - } - - close(): Promise { - if (this.#lnc.isConnected) { - this.#lnc.disconnect(); - } - return Promise.resolve(true); - } - - async login(password?: string): Promise { - if (password) { - this.setPassword(password); - this.#lnc.run(); - } - await this.#lnc.connect(); - while (!this.#lnc.isConnected) { - await new Promise(resolve => { - setTimeout(resolve, 100); - }); - } - return true; - } - - async getBalance(): Promise { - const rsp = await this.#lnc.lnd.lightning.channelBalance(); - this.#log(rsp); - return parseInt(rsp.localBalance?.sat ?? "0"); - } - - async createInvoice(req: InvoiceRequest): Promise { - const rsp = await this.#lnc.lnd.lightning.addInvoice({ - memo: req.memo, - value: req.amount.toString(), - expiry: req.expiry?.toString(), - }); - return unwrap(prToWalletInvoice(rsp.paymentRequest)); - } - - async payInvoice(pr: string): Promise { - return new Promise((resolve, reject) => { - this.#lnc.lnd.router.sendPaymentV2( - { - paymentRequest: pr, - timeoutSeconds: 60, - feeLimitSat: "100", - }, - msg => { - this.#log(msg); - if (msg.status === Payment_PaymentStatus.SUCCEEDED) { - resolve({ - preimage: msg.paymentPreimage, - state: WalletInvoiceState.Paid, - timestamp: parseInt(msg.creationTimeNs) / 1e9, - } as WalletInvoice); - } - }, - err => { - this.#log(err); - reject(err); - }, - ); - }); - } - - async getInvoices(): Promise { - const invoices = await this.#lnc.lnd.lightning.listPayments({ - maxPayments: "10", - reversed: true, - }); - - this.#log(invoices); - return invoices.payments.map(a => { - const parsedInvoice = prToWalletInvoice(a.paymentRequest); - if (!parsedInvoice) { - throw new WalletError(WalletErrorCode.InvalidInvoice, `Could not parse ${a.paymentRequest}`); - } - return { - ...parsedInvoice, - state: (() => { - switch (a.status) { - case Payment_PaymentStatus.SUCCEEDED: - return WalletInvoiceState.Paid; - case Payment_PaymentStatus.FAILED: - return WalletInvoiceState.Failed; - default: - return WalletInvoiceState.Pending; - } - })(), - preimage: a.paymentPreimage, - } as WalletInvoice; - }); - } -} diff --git a/packages/wallet/src/index.ts b/packages/wallet/src/index.ts index 44bfc883..e86b4e1c 100644 --- a/packages/wallet/src/index.ts +++ b/packages/wallet/src/index.ts @@ -1,7 +1,5 @@ import { decodeInvoice, unwrap } from "@snort/shared"; import AlbyWallet from "./AlbyWallet"; -//import { CashuWallet } from "./Cashu"; -import { LNCWallet } from "./LNCWallet"; import LNDHubWallet from "./LNDHub"; import { NostrConnectWallet } from "./NostrWalletConnect"; import { WebLNWallet } from "./WebLN"; @@ -11,10 +9,10 @@ export * from "./zapper"; export const enum WalletKind { LNDHub = 1, - LNC = 2, + //LNC = 2, WebLN = 3, NWC = 4, - Cashu = 5, + //Cashu = 5, Alby = 6, } @@ -135,10 +133,6 @@ export type LNWallet = EventEmitter & { */ export async function loadWallet(kind: WalletKind, data: string | undefined) { switch (kind) { - case WalletKind.LNC: { - const { LNCWallet } = await import("./LNCWallet"); - return LNCWallet.Empty(); - } case WalletKind.WebLN: { return new WebLNWallet(); } @@ -151,11 +145,7 @@ export async function loadWallet(kind: WalletKind, data: string | undefined) { case WalletKind.Alby: { return new AlbyWallet(JSON.parse(unwrap(data))); } - case WalletKind.Cashu: { - //const { CashuWallet } = await import("./Cashu"); - //return new CashuWallet(JSON.parse(unwrap(data))); - } } } -export { LNCWallet, WebLNWallet, LNDHubWallet, NostrConnectWallet, AlbyWallet }; +export { WebLNWallet, LNDHubWallet, NostrConnectWallet, AlbyWallet };