bug: prevent multiple parallel WebLN calls

This commit is contained in:
Kieran 2023-02-28 19:25:10 +00:00
parent 1ad0270819
commit f30a9075a2
Signed by: Kieran
GPG Key ID: DE71CEB3925BE941
3 changed files with 73 additions and 16 deletions

View File

@ -5,7 +5,7 @@ import { TaggedRawEvent } from "@snort/nostr";
import { EventKind, Tag, Event as NEvent, RelaySettings } from "@snort/nostr";
import { RootState } from "State/Store";
import { HexKey, RawEvent, u256, UserMetadata, Lists } from "@snort/nostr";
import { bech32ToHex, unwrap } from "Util";
import { bech32ToHex, delay, unwrap } from "Util";
import { DefaultRelays, HashtagRegex } from "Const";
import { System } from "System";
@ -398,12 +398,6 @@ export default function useEventPublisher() {
let isNip07Busy = false;
const delay = (t: number) => {
return new Promise(resolve => {
setTimeout(resolve, t);
});
};
export const barrierNip07 = async <T>(then: () => Promise<T>): Promise<T> => {
while (isNip07Busy) {
await delay(10);

View File

@ -1,25 +1,82 @@
import { useEffect } from "react";
import { delay, unwrap } from "Util";
interface WebLNPaymentResponse {
paymentHash: string;
let isWebLnBusy = false;
export const barrierWebLn = async <T>(then: () => Promise<T>): Promise<T> => {
while (isWebLnBusy) {
await delay(10);
}
isWebLnBusy = true;
try {
return await then();
} finally {
isWebLnBusy = false;
}
};
interface SendPaymentResponse {
paymentHash?: string;
preimage: string;
route: {
route?: {
total_amt: number;
total_fees: number;
};
}
interface RequestInvoiceArgs {
amount?: string | number;
defaultAmount?: string | number;
minimumAmount?: string | number;
maximumAmount?: string | number;
defaultMemo?: string;
}
interface RequestInvoiceResponse {
paymentRequest: string;
}
interface GetInfoResponse {
node: {
alias: string;
pubkey: string;
color?: string;
};
}
interface SignMessageResponse {
message: string;
signature: string;
}
interface WebLN {
enabled: boolean;
getInfo(): Promise<GetInfoResponse>;
enable: () => Promise<void>;
makeInvoice(args: RequestInvoiceArgs): Promise<RequestInvoiceResponse>;
signMessage(message: string): Promise<SignMessageResponse>;
verifyMessage(signature: string, message: string): Promise<void>;
sendPayment: (pr: string) => Promise<SendPaymentResponse>;
}
declare global {
interface Window {
webln?: {
enabled: boolean;
enable: () => Promise<void>;
sendPayment: (pr: string) => Promise<WebLNPaymentResponse>;
};
webln?: WebLN;
}
}
export default function useWebln(enable = true) {
const maybeWebLn = "webln" in window ? window.webln : null;
const maybeWebLn =
"webln" in window && window.webln
? ({
enabled: unwrap(window.webln).enabled,
getInfo: () => barrierWebLn(() => unwrap(window.webln).getInfo()),
enable: () => barrierWebLn(() => unwrap(window.webln).enable()),
makeInvoice: args => barrierWebLn(() => unwrap(window.webln).makeInvoice(args)),
signMessage: msg => barrierWebLn(() => unwrap(window.webln).signMessage(msg)),
verifyMessage: (sig, msg) => barrierWebLn(() => unwrap(window.webln).verifyMessage(sig, msg)),
sendPayment: pr => barrierWebLn(() => unwrap(window.webln).sendPayment(pr)),
} as WebLN)
: null;
useEffect(() => {
if (maybeWebLn && !maybeWebLn.enabled && enable) {

View File

@ -229,3 +229,9 @@ export function splitByUrl(str: string) {
return str.split(urlRegex);
}
export const delay = (t: number) => {
return new Promise(resolve => {
setTimeout(resolve, t);
});
};