forked from Kieran/snort
progress
This commit is contained in:
parent
7db8960914
commit
1b363ec15f
@ -19,6 +19,7 @@ import { LNURL, LNURLError, LNURLErrorCode, LNURLInvoice, LNURLSuccessAction } f
|
|||||||
import { debounce } from "Util";
|
import { debounce } from "Util";
|
||||||
|
|
||||||
import messages from "./messages";
|
import messages from "./messages";
|
||||||
|
import { openWallet } from "Wallet";
|
||||||
|
|
||||||
enum ZapType {
|
enum ZapType {
|
||||||
PublicZap = 1,
|
PublicZap = 1,
|
||||||
@ -297,6 +298,16 @@ 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);
|
||||||
|
const rsp = await wallet.payInvoice(pr);
|
||||||
|
console.debug(rsp);
|
||||||
|
setSuccess(rsp as LNURLSuccessAction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function payInvoice() {
|
function payInvoice() {
|
||||||
if (success || !invoice) return null;
|
if (success || !invoice) return null;
|
||||||
@ -321,6 +332,9 @@ export default function SendSats(props: SendSatsProps) {
|
|||||||
<button className="wallet-action" type="button" onClick={() => window.open(`lightning:${invoice}`)}>
|
<button className="wallet-action" type="button" onClick={() => window.open(`lightning:${invoice}`)}>
|
||||||
<FormattedMessage {...messages.OpenWallet} />
|
<FormattedMessage {...messages.OpenWallet} />
|
||||||
</button>
|
</button>
|
||||||
|
<button className="wallet-action" type="button" onClick={() => payWithWallet(pr)}>
|
||||||
|
<FormattedMessage defaultMessage="Pay with Snort" />
|
||||||
|
</button>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -351,9 +365,9 @@ export default function SendSats(props: SendSatsProps) {
|
|||||||
const defaultTitle = handler?.canZap ? formatMessage(messages.SendZap) : formatMessage(messages.SendSats);
|
const defaultTitle = handler?.canZap ? formatMessage(messages.SendZap) : formatMessage(messages.SendSats);
|
||||||
const title = target
|
const title = target
|
||||||
? formatMessage(messages.ToTarget, {
|
? formatMessage(messages.ToTarget, {
|
||||||
action: defaultTitle,
|
action: defaultTitle,
|
||||||
target,
|
target,
|
||||||
})
|
})
|
||||||
: defaultTitle;
|
: defaultTitle;
|
||||||
if (!(props.show ?? false)) return null;
|
if (!(props.show ?? false)) return null;
|
||||||
return (
|
return (
|
||||||
|
@ -8,6 +8,7 @@ import { HexKey, RawEvent, u256, UserMetadata, Lists } from "@snort/nostr";
|
|||||||
import { bech32ToHex, delay, unwrap } from "Util";
|
import { bech32ToHex, delay, unwrap } from "Util";
|
||||||
import { DefaultRelays, HashtagRegex } from "Const";
|
import { DefaultRelays, HashtagRegex } from "Const";
|
||||||
import { System } from "System";
|
import { System } from "System";
|
||||||
|
import { useMemo } from "react";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
@ -23,6 +24,8 @@ declare global {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type EventPublisher = ReturnType<typeof useEventPublisher>;
|
||||||
|
|
||||||
export default function useEventPublisher() {
|
export default function useEventPublisher() {
|
||||||
const pubKey = useSelector<RootState, HexKey | undefined>(s => s.login.publicKey);
|
const pubKey = useSelector<RootState, HexKey | undefined>(s => s.login.publicKey);
|
||||||
const privKey = useSelector<RootState, HexKey | undefined>(s => s.login.privateKey);
|
const privKey = useSelector<RootState, HexKey | undefined>(s => s.login.privateKey);
|
||||||
@ -78,7 +81,7 @@ export default function useEventPublisher() {
|
|||||||
ev.Content = content;
|
ev.Content = content;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
const ret = {
|
||||||
nip42Auth: async (challenge: string, relay: string) => {
|
nip42Auth: async (challenge: string, relay: string) => {
|
||||||
if (pubKey) {
|
if (pubKey) {
|
||||||
const ev = NEvent.ForPubKey(pubKey);
|
const ev = NEvent.ForPubKey(pubKey);
|
||||||
@ -393,7 +396,17 @@ export default function useEventPublisher() {
|
|||||||
publicKey: pubKey,
|
publicKey: pubKey,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
generic: async (content: string, kind: EventKind) => {
|
||||||
|
if (pubKey) {
|
||||||
|
const ev = NEvent.ForPubKey(pubKey);
|
||||||
|
ev.Kind = kind;
|
||||||
|
ev.Content = content;
|
||||||
|
return await signEvent(ev);
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return useMemo(() => ret, [pubKey, relays, follows]);
|
||||||
}
|
}
|
||||||
|
|
||||||
let isNip07Busy = false;
|
let isNip07Busy = false;
|
||||||
|
@ -1,12 +1,6 @@
|
|||||||
const Bitcoin = () => {
|
const Bitcoin = () => {
|
||||||
return (
|
return (
|
||||||
<svg
|
<svg width="16" height="22" viewBox="0 0 16 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
width="16"
|
|
||||||
height="22"
|
|
||||||
viewBox="0 0 16 22"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
<path
|
||||||
d="M5.5 1V3M5.5 19V21M9.5 1V3M9.5 19V21M3.5 3H10C12.2091 3 14 4.79086 14 7C14 9.20914 12.2091 11 10 11H3.5H11C13.2091 11 15 12.7909 15 15C15 17.2091 13.2091 19 11 19H3.5M3.5 3H1.5M3.5 3V19M3.5 19H1.5"
|
d="M5.5 1V3M5.5 19V21M9.5 1V3M9.5 19V21M3.5 3H10C12.2091 3 14 4.79086 14 7C14 9.20914 12.2091 11 10 11H3.5H11C13.2091 11 15 12.7909 15 15C15 17.2091 13.2091 19 11 19H3.5M3.5 3H1.5M3.5 3V19M3.5 19H1.5"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
|
@ -6,13 +6,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|||||||
import { faCheck, faClock, faXmark } from "@fortawesome/free-solid-svg-icons";
|
import { faCheck, faClock, faXmark } from "@fortawesome/free-solid-svg-icons";
|
||||||
|
|
||||||
import NoteTime from "Element/NoteTime";
|
import NoteTime from "Element/NoteTime";
|
||||||
import {
|
import { openWallet, WalletInvoice, Sats, WalletInfo, WalletInvoiceState, useWallet, LNWallet } from "Wallet";
|
||||||
openWallet,
|
|
||||||
WalletInvoice,
|
|
||||||
Sats,
|
|
||||||
WalletInfo,
|
|
||||||
WalletInvoiceState,
|
|
||||||
} from "Wallet";
|
|
||||||
|
|
||||||
export const WalletRoutes: RouteObject[] = [
|
export const WalletRoutes: RouteObject[] = [
|
||||||
{
|
{
|
||||||
@ -25,28 +19,25 @@ export default function WalletPage() {
|
|||||||
const [info, setInfo] = useState<WalletInfo>();
|
const [info, setInfo] = useState<WalletInfo>();
|
||||||
const [balance, setBalance] = useState<Sats>();
|
const [balance, setBalance] = useState<Sats>();
|
||||||
const [history, setHistory] = useState<WalletInvoice[]>();
|
const [history, setHistory] = useState<WalletInvoice[]>();
|
||||||
|
const wallet = useWallet();
|
||||||
|
|
||||||
async function loadWallet() {
|
async function loadWallet(wallet: LNWallet) {
|
||||||
let cfg = window.localStorage.getItem("wallet-lndhub");
|
const i = await wallet.getInfo();
|
||||||
if (cfg) {
|
if ("error" in i) {
|
||||||
let wallet = await openWallet(cfg);
|
return;
|
||||||
let i = await wallet.getInfo();
|
|
||||||
if ("error" in i) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setInfo(i as WalletInfo);
|
|
||||||
let b = await wallet.getBalance();
|
|
||||||
setBalance(b as Sats);
|
|
||||||
let h = await wallet.getInvoices();
|
|
||||||
setHistory(
|
|
||||||
(h as WalletInvoice[]).sort((a, b) => b.timestamp - a.timestamp)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
setInfo(i as WalletInfo);
|
||||||
|
const b = await wallet.getBalance();
|
||||||
|
setBalance(b as Sats);
|
||||||
|
const h = await wallet.getInvoices();
|
||||||
|
setHistory((h as WalletInvoice[]).sort((a, b) => b.timestamp - a.timestamp));
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadWallet().catch(console.warn);
|
if (wallet) {
|
||||||
}, []);
|
loadWallet(wallet).catch(console.warn);
|
||||||
|
}
|
||||||
|
}, [wallet]);
|
||||||
|
|
||||||
function stateIcon(s: WalletInvoiceState) {
|
function stateIcon(s: WalletInvoiceState) {
|
||||||
switch (s) {
|
switch (s) {
|
||||||
@ -58,26 +49,35 @@ export default function WalletPage() {
|
|||||||
return <FontAwesomeIcon icon={faXmark} className="mr5" />;
|
return <FontAwesomeIcon icon={faXmark} className="mr5" />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function createInvoice() {
|
||||||
|
const cfg = window.localStorage.getItem("wallet-lndhub");
|
||||||
|
if (cfg) {
|
||||||
|
const wallet = await openWallet(cfg);
|
||||||
|
const rsp = await wallet.createInvoice({
|
||||||
|
memo: "test",
|
||||||
|
amount: 100,
|
||||||
|
});
|
||||||
|
console.debug(rsp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h3>{info?.alias}</h3>
|
<h3>{info?.alias}</h3>
|
||||||
<b>Balance: {(balance ?? 0).toLocaleString()} sats</b>
|
<b>Balance: {(balance ?? 0).toLocaleString()} sats</b>
|
||||||
<div className="flex wallet-buttons">
|
<div className="flex wallet-buttons">
|
||||||
<button>Send</button>
|
<button>Send</button>
|
||||||
<button>Receive</button>
|
<button onClick={() => createInvoice()}>Receive</button>
|
||||||
</div>
|
</div>
|
||||||
<h3>History</h3>
|
<h3>History</h3>
|
||||||
{history?.map((a) => (
|
{history?.map(a => (
|
||||||
<div className="card flex wallet-history-item" key={a.timestamp}>
|
<div className="card flex wallet-history-item" key={a.timestamp}>
|
||||||
<div className="f-grow f-col">
|
<div className="f-grow f-col">
|
||||||
<NoteTime from={a.timestamp * 1000} />
|
<NoteTime from={a.timestamp * 1000} />
|
||||||
<div>{(a.memo ?? "").length === 0 ? <> </> : a.memo}</div>
|
<div>{(a.memo ?? "").length === 0 ? <> </> : a.memo}</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div className={`${a.state === WalletInvoiceState.Paid ? "success" : "pending"}`}>
|
||||||
className={`${
|
|
||||||
a.state === WalletInvoiceState.Paid ? "success" : "pending"
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{stateIcon(a.state)}
|
{stateIcon(a.state)}
|
||||||
{a.amount.toLocaleString()} sats
|
{a.amount.toLocaleString()} sats
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
import { defineMessages } from "react-intl";
|
|
||||||
import { addIdAndDefaultMessageToMessages } from "Util";
|
|
||||||
|
|
||||||
const messages = defineMessages({
|
|
||||||
Login: "Login",
|
|
||||||
});
|
|
||||||
|
|
||||||
export default addIdAndDefaultMessageToMessages(messages, "Pages");
|
|
@ -1,3 +1,5 @@
|
|||||||
|
import { EventPublisher } from "Feed/EventPublisher";
|
||||||
|
import EventKind from "Nostr/EventKind";
|
||||||
import {
|
import {
|
||||||
InvoiceRequest,
|
InvoiceRequest,
|
||||||
LNWallet,
|
LNWallet,
|
||||||
@ -15,20 +17,35 @@ const defaultHeaders = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default class LNDHubWallet implements LNWallet {
|
export default class LNDHubWallet implements LNWallet {
|
||||||
|
type: "lndhub" | "snort";
|
||||||
url: string;
|
url: string;
|
||||||
user: string;
|
user: string;
|
||||||
password: string;
|
password: string;
|
||||||
auth?: AuthResponse;
|
auth?: AuthResponse;
|
||||||
|
publisher?: EventPublisher;
|
||||||
|
|
||||||
constructor(url: string) {
|
constructor(url: string, publisher?: EventPublisher) {
|
||||||
const regex = /^lndhub:\/\/([\S-]+):([\S-]+)@(.*)$/i;
|
if (url.startsWith("lndhub://")) {
|
||||||
const parsedUrl = url.match(regex);
|
const regex = /^lndhub:\/\/([\S-]+):([\S-]+)@(.*)$/i;
|
||||||
if (!parsedUrl || parsedUrl.length !== 4) {
|
const parsedUrl = url.match(regex);
|
||||||
throw new Error("Invalid LNDHUB config");
|
console.debug(parsedUrl);
|
||||||
|
if (!parsedUrl || parsedUrl.length !== 4) {
|
||||||
|
throw new Error("Invalid LNDHUB config");
|
||||||
|
}
|
||||||
|
this.url = new URL(parsedUrl[3]).toString();
|
||||||
|
this.user = parsedUrl[1];
|
||||||
|
this.password = parsedUrl[2];
|
||||||
|
this.type = "lndhub";
|
||||||
|
} else if (url.startsWith("snort://")) {
|
||||||
|
const u = new URL(url);
|
||||||
|
this.url = `https://${u.host}${u.pathname}`;
|
||||||
|
this.user = "";
|
||||||
|
this.password = "";
|
||||||
|
this.type = "snort";
|
||||||
|
this.publisher = publisher;
|
||||||
|
} else {
|
||||||
|
throw new Error("Invalid config");
|
||||||
}
|
}
|
||||||
this.url = new URL(parsedUrl[3]).toString();
|
|
||||||
this.user = parsedUrl[1];
|
|
||||||
this.password = parsedUrl[2];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async createAccount() {
|
async createAccount() {
|
||||||
@ -40,6 +57,8 @@ export default class LNDHubWallet implements LNWallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async login() {
|
async login() {
|
||||||
|
if (this.type === "snort") return true;
|
||||||
|
|
||||||
const rsp = await this.getJson<AuthResponse>("POST", "/auth?type=auth", {
|
const rsp = await this.getJson<AuthResponse>("POST", "/auth?type=auth", {
|
||||||
login: this.user,
|
login: this.user,
|
||||||
password: this.password,
|
password: this.password,
|
||||||
@ -53,31 +72,56 @@ export default class LNDHubWallet implements LNWallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getBalance(): Promise<Sats | WalletError> {
|
async getBalance(): Promise<Sats | WalletError> {
|
||||||
let rsp = await this.getJson<GetBalanceResponse>("GET", "/balance");
|
const rsp = await this.getJson<GetBalanceResponse>("GET", "/balance");
|
||||||
if ("error" in rsp) {
|
if ("error" in rsp) {
|
||||||
return rsp as WalletError;
|
return rsp as WalletError;
|
||||||
}
|
}
|
||||||
let bal = Math.floor((rsp as GetBalanceResponse).BTC.AvailableBalance);
|
const bal = Math.floor((rsp as GetBalanceResponse).BTC.AvailableBalance);
|
||||||
return bal as Sats;
|
return bal as Sats;
|
||||||
}
|
}
|
||||||
|
|
||||||
async createInvoice(req: InvoiceRequest) {
|
async createInvoice(req: InvoiceRequest) {
|
||||||
return Promise.resolve(UnknownWalletError);
|
const rsp = await this.getJson<UserInvoicesResponse>("POST", "/addinvoice", {
|
||||||
}
|
amt: req.amount,
|
||||||
|
memo: req.memo,
|
||||||
async payInvoice(pr: string) {
|
});
|
||||||
return Promise.resolve(UnknownWalletError);
|
|
||||||
}
|
|
||||||
|
|
||||||
async getInvoices(): Promise<WalletInvoice[] | WalletError> {
|
|
||||||
let rsp = await this.getJson<GetUserInvoicesResponse[]>(
|
|
||||||
"GET",
|
|
||||||
"/getuserinvoices"
|
|
||||||
);
|
|
||||||
if ("error" in rsp) {
|
if ("error" in rsp) {
|
||||||
return rsp as WalletError;
|
return rsp as WalletError;
|
||||||
}
|
}
|
||||||
return (rsp as GetUserInvoicesResponse[]).map((a) => {
|
|
||||||
|
const pRsp = rsp as UserInvoicesResponse;
|
||||||
|
return {
|
||||||
|
pr: pRsp.payment_request,
|
||||||
|
memo: req.memo,
|
||||||
|
amount: req.amount,
|
||||||
|
paymentHash: pRsp.payment_hash,
|
||||||
|
timestamp: pRsp.timestamp,
|
||||||
|
} as WalletInvoice;
|
||||||
|
}
|
||||||
|
|
||||||
|
async payInvoice(pr: string) {
|
||||||
|
const rsp = await this.getJson<PayInvoiceResponse>("POST", "/payinvoice", {
|
||||||
|
invoice: pr,
|
||||||
|
});
|
||||||
|
|
||||||
|
if ("error" in rsp) {
|
||||||
|
return rsp as WalletError;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pRsp = rsp as PayInvoiceResponse;
|
||||||
|
return {
|
||||||
|
pr: pr,
|
||||||
|
paymentHash: pRsp.payment_hash,
|
||||||
|
state: pRsp.payment_error === undefined ? WalletInvoiceState.Paid : WalletInvoiceState.Pending,
|
||||||
|
} as WalletInvoice;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getInvoices(): Promise<WalletInvoice[] | WalletError> {
|
||||||
|
const rsp = await this.getJson<UserInvoicesResponse[]>("GET", "/getuserinvoices");
|
||||||
|
if ("error" in rsp) {
|
||||||
|
return rsp as WalletError;
|
||||||
|
}
|
||||||
|
return (rsp as UserInvoicesResponse[]).map(a => {
|
||||||
return {
|
return {
|
||||||
memo: a.description,
|
memo: a.description,
|
||||||
amount: Math.floor(a.amt),
|
amount: Math.floor(a.amt),
|
||||||
@ -89,17 +133,18 @@ export default class LNDHubWallet implements LNWallet {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async getJson<T>(
|
private async getJson<T>(method: "GET" | "POST", path: string, body?: any): Promise<T | WalletError> {
|
||||||
method: "GET" | "POST",
|
let auth = `Bearer ${this.auth?.access_token}`;
|
||||||
path: string,
|
if (this.type === "snort") {
|
||||||
body?: any
|
const ev = await this.publisher?.generic(`${new URL(this.url).pathname}${path}`, EventKind.Ephemeral);
|
||||||
): Promise<T | WalletError> {
|
auth = JSON.stringify(ev?.ToObject());
|
||||||
|
}
|
||||||
const rsp = await fetch(`${this.url}${path}`, {
|
const rsp = await fetch(`${this.url}${path}`, {
|
||||||
method: method,
|
method: method,
|
||||||
body: body ? JSON.stringify(body) : undefined,
|
body: body ? JSON.stringify(body) : undefined,
|
||||||
headers: {
|
headers: {
|
||||||
...defaultHeaders,
|
...defaultHeaders,
|
||||||
Authorization: `Bearer ${this.auth?.access_token}`,
|
Authorization: auth,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const json = await rsp.json();
|
const json = await rsp.json();
|
||||||
@ -122,7 +167,7 @@ interface GetBalanceResponse {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
interface GetUserInvoicesResponse {
|
interface UserInvoicesResponse {
|
||||||
amt: number;
|
amt: number;
|
||||||
description: string;
|
description: string;
|
||||||
ispaid: boolean;
|
ispaid: boolean;
|
||||||
@ -131,4 +176,12 @@ interface GetUserInvoicesResponse {
|
|||||||
pay_req: string;
|
pay_req: string;
|
||||||
payment_hash: string;
|
payment_hash: string;
|
||||||
payment_request: string;
|
payment_request: string;
|
||||||
|
r_hash: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PayInvoiceResponse {
|
||||||
|
payment_error?: string;
|
||||||
|
payment_hash: string;
|
||||||
|
payment_preimage: string;
|
||||||
|
payment_route?: { total_amt: number; total_fees: number };
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import useEventPublisher, { EventPublisher } from "Feed/EventPublisher";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
import LNDHubWallet from "./LNDHub";
|
import LNDHubWallet from "./LNDHub";
|
||||||
|
|
||||||
export enum WalletErrorCode {
|
export enum WalletErrorCode {
|
||||||
@ -74,8 +76,26 @@ export interface LNWallet {
|
|||||||
getInvoices: () => Promise<WalletInvoice[] | WalletError>;
|
getInvoices: () => Promise<WalletInvoice[] | WalletError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function openWallet(config: string) {
|
export async function openWallet(config: string, publisher?: EventPublisher) {
|
||||||
let wallet = new LNDHubWallet(config);
|
const wallet = new LNDHubWallet(config, publisher);
|
||||||
await wallet.login();
|
await wallet.login();
|
||||||
return wallet;
|
return wallet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useWallet() {
|
||||||
|
const [wallet, setWallet] = useState<LNWallet>();
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
@ -26,10 +26,9 @@ import HashTagsPage from "Pages/HashTagsPage";
|
|||||||
import SearchPage from "Pages/SearchPage";
|
import SearchPage from "Pages/SearchPage";
|
||||||
import HelpPage from "Pages/HelpPage";
|
import HelpPage from "Pages/HelpPage";
|
||||||
import { NewUserRoutes } from "Pages/new";
|
import { NewUserRoutes } from "Pages/new";
|
||||||
import NostrLinkHandler from "Pages/NostrLinkHandler";
|
|
||||||
import { IntlProvider } from "./IntlProvider";
|
|
||||||
import { unwrap } from "Util";
|
|
||||||
import { WalletRoutes } from "Pages/WalletPage";
|
import { WalletRoutes } from "Pages/WalletPage";
|
||||||
|
import NostrLinkHandler from "Pages/NostrLinkHandler";
|
||||||
|
import { unwrap } from "Util";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HTTP query provider
|
* HTTP query provider
|
||||||
|
@ -9,6 +9,7 @@ enum EventKind {
|
|||||||
Repost = 6, // NIP-18
|
Repost = 6, // NIP-18
|
||||||
Reaction = 7, // NIP-25
|
Reaction = 7, // NIP-25
|
||||||
Relays = 10002, // NIP-65
|
Relays = 10002, // NIP-65
|
||||||
|
Ephemeral = 20_000,
|
||||||
Auth = 22242, // NIP-42
|
Auth = 22242, // NIP-42
|
||||||
PubkeyLists = 30000, // NIP-51a
|
PubkeyLists = 30000, // NIP-51a
|
||||||
NoteLists = 30001, // NIP-51b
|
NoteLists = 30001, // NIP-51b
|
||||||
|
Loading…
Reference in New Issue
Block a user