mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-29 00:42:30 +00:00
133 lines
3.1 KiB
JavaScript
133 lines
3.1 KiB
JavaScript
// js/nip07Support.js
|
|
|
|
import { isDevMode } from "./config.js";
|
|
|
|
export const NIP07_LOGIN_TIMEOUT_MS = 60_000; // 60 seconds
|
|
export const NIP07_LOGIN_TIMEOUT_ERROR_MESSAGE =
|
|
"Timed out waiting for the NIP-07 extension. Confirm the extension prompt in your browser toolbar and try again.";
|
|
|
|
const DEFAULT_ENABLE_VARIANT_TIMEOUT_MS = 7000;
|
|
|
|
export const DEFAULT_NIP07_PERMISSION_METHODS = Object.freeze([
|
|
"get_public_key",
|
|
"sign_event",
|
|
"nip04.encrypt",
|
|
"nip04.decrypt",
|
|
"read_relays",
|
|
"write_relays",
|
|
]);
|
|
|
|
export function getEnableVariantTimeoutMs() {
|
|
const overrideValue =
|
|
typeof globalThis !== "undefined" &&
|
|
globalThis !== null &&
|
|
Number.isFinite(globalThis.__BITVID_NIP07_ENABLE_VARIANT_TIMEOUT_MS__)
|
|
? Math.floor(globalThis.__BITVID_NIP07_ENABLE_VARIANT_TIMEOUT_MS__)
|
|
: null;
|
|
|
|
if (overrideValue !== null && overrideValue > 0) {
|
|
return Math.max(50, overrideValue);
|
|
}
|
|
|
|
return DEFAULT_ENABLE_VARIANT_TIMEOUT_MS;
|
|
}
|
|
|
|
function withNip07Timeout(
|
|
operation,
|
|
{
|
|
timeoutMs = NIP07_LOGIN_TIMEOUT_MS,
|
|
message = NIP07_LOGIN_TIMEOUT_ERROR_MESSAGE,
|
|
} = {},
|
|
) {
|
|
const numericTimeout = Number(timeoutMs);
|
|
const effectiveTimeout =
|
|
Number.isFinite(numericTimeout) && numericTimeout > 0
|
|
? numericTimeout
|
|
: NIP07_LOGIN_TIMEOUT_MS;
|
|
|
|
let timeoutId;
|
|
const timeoutPromise = new Promise((_, reject) => {
|
|
timeoutId = setTimeout(() => {
|
|
reject(new Error(message));
|
|
}, effectiveTimeout);
|
|
});
|
|
|
|
let operationResult;
|
|
try {
|
|
operationResult = operation();
|
|
} catch (err) {
|
|
if (timeoutId) {
|
|
clearTimeout(timeoutId);
|
|
}
|
|
throw err;
|
|
}
|
|
|
|
const operationPromise = Promise.resolve(operationResult);
|
|
|
|
return Promise.race([operationPromise, timeoutPromise]).finally(() => {
|
|
if (timeoutId) {
|
|
clearTimeout(timeoutId);
|
|
}
|
|
});
|
|
}
|
|
|
|
export async function runNip07WithRetry(
|
|
operation,
|
|
{
|
|
label = "NIP-07 operation",
|
|
timeoutMs = NIP07_LOGIN_TIMEOUT_MS,
|
|
retryMultiplier = 2,
|
|
} = {},
|
|
) {
|
|
let hasStarted = false;
|
|
let cachedPromise = null;
|
|
|
|
const getOrStartOperation = () => {
|
|
if (!hasStarted) {
|
|
hasStarted = true;
|
|
try {
|
|
cachedPromise = Promise.resolve(operation());
|
|
} catch (error) {
|
|
hasStarted = false;
|
|
cachedPromise = null;
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
return cachedPromise;
|
|
};
|
|
|
|
try {
|
|
return await withNip07Timeout(getOrStartOperation, {
|
|
timeoutMs,
|
|
message: NIP07_LOGIN_TIMEOUT_ERROR_MESSAGE,
|
|
});
|
|
} catch (error) {
|
|
const isTimeoutError =
|
|
error instanceof Error &&
|
|
error.message === NIP07_LOGIN_TIMEOUT_ERROR_MESSAGE;
|
|
|
|
if (!isTimeoutError || retryMultiplier <= 1) {
|
|
throw error;
|
|
}
|
|
|
|
const extendedTimeout = Math.max(
|
|
timeoutMs,
|
|
Math.round(timeoutMs * retryMultiplier),
|
|
);
|
|
|
|
if (isDevMode) {
|
|
console.warn(
|
|
`[nostr] ${label} taking longer than ${timeoutMs}ms. Waiting up to ${extendedTimeout}ms for extension response.`,
|
|
);
|
|
}
|
|
|
|
return withNip07Timeout(getOrStartOperation, {
|
|
timeoutMs: extendedTimeout,
|
|
message: NIP07_LOGIN_TIMEOUT_ERROR_MESSAGE,
|
|
});
|
|
}
|
|
}
|
|
|
|
export const __testExports = { runNip07WithRetry };
|