diff --git a/packages/app/package.json b/packages/app/package.json
index 4f9cc05f..35deb4c6 100644
--- a/packages/app/package.json
+++ b/packages/app/package.json
@@ -7,6 +7,7 @@
"@fortawesome/free-solid-svg-icons": "^6.2.1",
"@fortawesome/react-fontawesome": "^0.2.0",
"@jukben/emoji-search": "^2.0.1",
+ "@lightninglabs/lnc-web": "^0.2.3-alpha",
"@noble/hashes": "^1.2.0",
"@noble/secp256k1": "^1.7.0",
"@protobufjs/base64": "^1.1.2",
diff --git a/packages/app/src/Element/SendSats.tsx b/packages/app/src/Element/SendSats.tsx
index e3f3492d..ccb5961c 100644
--- a/packages/app/src/Element/SendSats.tsx
+++ b/packages/app/src/Element/SendSats.tsx
@@ -19,7 +19,7 @@ import { LNURL, LNURLError, LNURLErrorCode, LNURLInvoice, LNURLSuccessAction } f
import { debounce } from "Util";
import messages from "./messages";
-import { openWallet } from "Wallet";
+import { useWallet } from "Wallet";
enum ZapType {
PublicZap = 1,
@@ -81,6 +81,7 @@ export default function SendSats(props: SendSatsProps) {
const { formatMessage } = useIntl();
const publisher = useEventPublisher();
const canComment = handler ? (handler.canZap && zapType !== ZapType.NonZap) || handler.maxCommentLength > 0 : false;
+ const wallet = useWallet();
useEffect(() => {
if (props.show) {
@@ -298,11 +299,9 @@ export default function SendSats(props: SendSatsProps) {
>
);
}
-
+
async function payWithWallet(pr: string) {
- const cfg = window.localStorage.getItem("wallet-lndhub");
- if (cfg) {
- const wallet = await openWallet(cfg);
+ if (wallet) {
const rsp = await wallet.payInvoice(pr);
console.debug(rsp);
setSuccess(rsp as LNURLSuccessAction);
@@ -332,9 +331,11 @@ export default function SendSats(props: SendSatsProps) {
-
+ {wallet && (
+
+ )}
>
)}
@@ -365,9 +366,9 @@ export default function SendSats(props: SendSatsProps) {
const defaultTitle = handler?.canZap ? formatMessage(messages.SendZap) : formatMessage(messages.SendSats);
const title = target
? formatMessage(messages.ToTarget, {
- action: defaultTitle,
- target,
- })
+ action: defaultTitle,
+ target,
+ })
: defaultTitle;
if (!(props.show ?? false)) return null;
return (
diff --git a/packages/app/src/Pages/Layout.tsx b/packages/app/src/Pages/Layout.tsx
index dfa95165..c1758daf 100644
--- a/packages/app/src/Pages/Layout.tsx
+++ b/packages/app/src/Pages/Layout.tsx
@@ -45,9 +45,6 @@ export default function Layout() {
const [pageClass, setPageClass] = useState("page");
const pub = useEventPublisher();
useLoginFeed();
- useEffect(() => {
- System.nip42Auth = pub.nip42Auth;
- }, [pub]);
const shouldHideNoteCreator = useMemo(() => {
const hideOn = ["/settings", "/messages", "/new", "/login", "/donate", "/p/"];
diff --git a/packages/app/src/Pages/WalletPage.tsx b/packages/app/src/Pages/WalletPage.tsx
index 1d66dda6..e336aafe 100644
--- a/packages/app/src/Pages/WalletPage.tsx
+++ b/packages/app/src/Pages/WalletPage.tsx
@@ -6,7 +6,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faCheck, faClock, faXmark } from "@fortawesome/free-solid-svg-icons";
import NoteTime from "Element/NoteTime";
-import { openWallet, WalletInvoice, Sats, WalletInfo, WalletInvoiceState, useWallet, LNWallet } from "Wallet";
+import { WalletInvoice, Sats, WalletInfo, WalletInvoiceState, useWallet, LNWallet } from "Wallet";
export const WalletRoutes: RouteObject[] = [
{
@@ -51,9 +51,7 @@ export default function WalletPage() {
}
async function createInvoice() {
- const cfg = window.localStorage.getItem("wallet-lndhub");
- if (cfg) {
- const wallet = await openWallet(cfg);
+ if (wallet) {
const rsp = await wallet.createInvoice({
memo: "test",
amount: 100,
diff --git a/packages/app/src/Wallet/LNCWallet.ts b/packages/app/src/Wallet/LNCWallet.ts
new file mode 100644
index 00000000..23eded20
--- /dev/null
+++ b/packages/app/src/Wallet/LNCWallet.ts
@@ -0,0 +1,84 @@
+import { InvoiceRequest, LNWallet, Login, WalletError, WalletInfo, WalletInvoice, WalletInvoiceState } from "Wallet";
+
+import LNC from "@lightninglabs/lnc-web";
+export class LNCWallet implements LNWallet {
+ #lnc: LNC;
+
+ private constructor(pairingPhrase?: string, password?: string) {
+ this.#lnc = new LNC({
+ pairingPhrase,
+ password,
+ });
+ }
+
+ static async Initialize(pairingPhrase: string, password: string) {
+ const lnc = new LNCWallet(pairingPhrase, password);
+ await lnc.login();
+ return lnc;
+ }
+
+ static async Connect(password: string) {
+ const lnc = new LNCWallet(undefined, password);
+ await lnc.login();
+ return lnc;
+ }
+
+ 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(): Promise {
+ 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();
+ console.debug(rsp);
+ return parseInt(rsp.localBalance?.sat ?? "0");
+ }
+
+ createInvoice(req: InvoiceRequest): Promise {
+ throw new Error("Not implemented");
+ }
+
+ payInvoice(pr: string): Promise {
+ throw new Error("Not implemented");
+ }
+
+ async getInvoices(): Promise {
+ const invoices = await this.#lnc.lnd.lightning.listPayments({
+ includeIncomplete: true,
+ maxPayments: "10",
+ reversed: true,
+ });
+
+ return invoices.payments.map(a => {
+ return {
+ amount: parseInt(a.valueSat),
+ state: a.status === "SUCCEEDED" ? WalletInvoiceState.Paid : WalletInvoiceState.Pending,
+ timestamp: parseInt(a.creationTimeNs) / 1e9,
+ } as WalletInvoice;
+ });
+ }
+}
diff --git a/packages/app/src/Wallet/LNDHub.ts b/packages/app/src/Wallet/LNDHub.ts
index 76465b40..52d2993d 100644
--- a/packages/app/src/Wallet/LNDHub.ts
+++ b/packages/app/src/Wallet/LNDHub.ts
@@ -1,5 +1,4 @@
import { EventPublisher } from "Feed/EventPublisher";
-import EventKind from "Nostr/EventKind";
import {
InvoiceRequest,
LNWallet,
@@ -48,6 +47,10 @@ export default class LNDHubWallet implements LNWallet {
}
}
+ close(): Promise {
+ throw new Error("Not implemented");
+ }
+
async createAccount() {
return Promise.resolve(UnknownWalletError);
}
@@ -136,7 +139,7 @@ export default class LNDHubWallet implements LNWallet {
private async getJson(method: "GET" | "POST", path: string, body?: any): Promise {
let auth = `Bearer ${this.auth?.access_token}`;
if (this.type === "snort") {
- const ev = await this.publisher?.generic(`${new URL(this.url).pathname}${path}`, EventKind.Ephemeral);
+ const ev = await this.publisher?.generic(`${new URL(this.url).pathname}${path}`, 30_000);
auth = JSON.stringify(ev?.ToObject());
}
const rsp = await fetch(`${this.url}${path}`, {
diff --git a/packages/app/src/Wallet/index.ts b/packages/app/src/Wallet/index.ts
index 84f87a91..cc94f8b3 100644
--- a/packages/app/src/Wallet/index.ts
+++ b/packages/app/src/Wallet/index.ts
@@ -1,7 +1,3 @@
-import useEventPublisher, { EventPublisher } from "Feed/EventPublisher";
-import { useEffect, useState } from "react";
-import LNDHubWallet from "./LNDHub";
-
export enum WalletErrorCode {
BadAuth = 1,
NotEnoughBalance = 2,
@@ -70,32 +66,13 @@ export interface LNWallet {
createAccount: () => Promise;
getInfo: () => Promise;
login: () => Promise;
+ close: () => Promise;
getBalance: () => Promise;
createInvoice: (req: InvoiceRequest) => Promise;
payInvoice: (pr: string) => Promise;
getInvoices: () => Promise;
}
-export async function openWallet(config: string, publisher?: EventPublisher) {
- const wallet = new LNDHubWallet(config, publisher);
- await wallet.login();
- return wallet;
-}
-
-export function useWallet() {
- const [wallet, setWallet] = useState();
- const publisher = useEventPublisher();
-
- useEffect(() => {
- if (publisher) {
- const cfg = window.localStorage.getItem("wallet-lndhub");
- if (cfg) {
- openWallet(cfg, publisher)
- .then(a => setWallet(a))
- .catch(console.error);
- }
- }
- }, [publisher]);
-
- return wallet;
+export function useWallet(): LNWallet | undefined {
+ return undefined;
}
diff --git a/yarn.lock b/yarn.lock
index 044d8049..3ff2f76e 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1681,6 +1681,19 @@
resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b"
integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==
+"@lightninglabs/lnc-core@0.2.3-alpha":
+ version "0.2.3-alpha"
+ resolved "https://registry.yarnpkg.com/@lightninglabs/lnc-core/-/lnc-core-0.2.3-alpha.tgz#e1b92a9071d1dfb92e2d565710b56f28f57cbbd4"
+ integrity sha512-93D/uU64ayAaJv5kv4Pqwvkt+uT7yCtmHD08aUzvql+lbWm6U7m5loZLxz7tACFLXVPOQ8OHJL25W+3QMEYthg==
+
+"@lightninglabs/lnc-web@^0.2.3-alpha":
+ version "0.2.3-alpha"
+ resolved "https://registry.yarnpkg.com/@lightninglabs/lnc-web/-/lnc-web-0.2.3-alpha.tgz#d41184d815034c15fc9966da390222babc4eb19c"
+ integrity sha512-Pr02Ti9a0YzEIP2FTJT+IuoE02xgXqhMKoo8lK+Y6kSf3xk8/wJXJssFMA96iWV5Phf1Ra9ynmLVIQjD176BxA==
+ dependencies:
+ "@lightninglabs/lnc-core" "0.2.3-alpha"
+ crypto-js "4.1.1"
+
"@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1":
version "5.1.1-v1"
resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz#dbf733a965ca47b1973177dc0bb6c889edcfb129"
@@ -3716,6 +3729,11 @@ cross-spawn@^7.0.2, cross-spawn@^7.0.3:
shebang-command "^2.0.0"
which "^2.0.1"
+crypto-js@4.1.1:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.1.1.tgz#9e485bcf03521041bd85844786b83fb7619736cf"
+ integrity sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==
+
crypto-random-string@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5"