wip: migrate to typescript

This commit is contained in:
reya
2024-12-22 08:25:14 +07:00
parent a1d87bcd74
commit db9e0b43e5
9 changed files with 303 additions and 153 deletions

View File

@@ -11,7 +11,7 @@
"rules": { "rules": {
"recommended": true, "recommended": true,
"style": { "style": {
"noNonNullAssertion": "warn", "noNonNullAssertion": "off",
"noUselessElse": "off" "noUselessElse": "off"
}, },
"correctness": { "correctness": {

104
build.js
View File

@@ -1,56 +1,56 @@
#!/usr/bin/env node #!/usr/bin/env node
const {copy} = require('esbuild-plugin-copy') import esbuild from "esbuild";
const esbuild = require('esbuild') import copy from "esbuild-copy-plugin";
const isProd = process.argv.indexOf('prod') !== -1 const isProd = process.argv.indexOf("prod") !== -1;
const isFirefox = process.argv.indexOf('firefox') !== -1 const isFirefox = process.argv.indexOf("firefox") !== -1;
esbuild esbuild
.build({ .build({
bundle: true, bundle: true,
entryPoints: { entryPoints: {
'popup.build': './extension/popup.jsx', "popup.build": "./extension/popup.tsx",
'prompt.build': './extension/prompt.jsx', "prompt.build": "./extension/prompt.tsx",
'options.build': './extension/options.jsx', "options.build": "./extension/options.jsx",
'background.build': './extension/background.js', "background.build": "./extension/background.js",
'content-script.build': './extension/content-script.js' "content-script.build": "./extension/content-script.js",
}, },
outdir: './extension/output', outdir: "./extension/output",
sourcemap: isProd ? false : 'inline', sourcemap: isProd ? false : "inline",
define: { define: {
window: 'self', window: "self",
global: 'self' global: "self",
}, },
plugins: [ plugins: [
copy({ copy({
assets: [ assets: [
{ {
from: [ from: [
isFirefox isFirefox
? './extension/firefox/manifest.json' ? "./extension/firefox/manifest.json"
: './extension/chrome/manifest.json' : "./extension/chrome/manifest.json",
], ],
to: ['./'] to: ["./"],
}, },
{ {
from: ['./extension/*.html'], from: ["./extension/*.html"],
to: ['./'] to: ["./"],
}, },
{ {
from: ['./extension/common.js'], from: ["./extension/common.js"],
to: ['./'] to: ["./"],
}, },
{ {
from: ['./extension/nostr-provider.js'], from: ["./extension/nostr-provider.js"],
to: ['./'] to: ["./"],
}, },
{ {
from: ['./extension/icons/*'], from: ["./extension/icons/*"],
to: ['./icons'] to: ["./icons"],
} },
] ],
}) }),
] ],
}) })
.then(() => console.log('Build success.')) .then(() => console.log("Build success."))
.catch(err => console.error('Build error.', err)) .catch((err) => console.error("Build error.", err));

7
extension/global.d.ts vendored Normal file
View File

@@ -0,0 +1,7 @@
import type { WindowNostr } from "nostr-tools/nip07";
declare global {
interface Window {
nostr?: WindowNostr;
}
}

View File

@@ -1,7 +1,7 @@
import * as Checkbox from "@radix-ui/react-checkbox"; import * as Checkbox from "@radix-ui/react-checkbox";
import * as Tabs from "@radix-ui/react-tabs"; import * as Tabs from "@radix-ui/react-tabs";
import { generatePrivateKey, nip19 } from "nostr-tools"; import { nip19, generateSecretKey } from "nostr-tools";
import React, { useState, useCallback, useEffect } from "react"; import { useState, useCallback, useEffect } from "react";
import QRCode from "react-qr-code"; import QRCode from "react-qr-code";
import browser from "webextension-polyfill"; import browser from "webextension-polyfill";
import { removePermissions } from "./common"; import { removePermissions } from "./common";
@@ -17,16 +17,17 @@ function Options() {
); );
const [hidingPrivateKey, hidePrivateKey] = useState(true); const [hidingPrivateKey, hidePrivateKey] = useState(true);
const [showNotifications, setNotifications] = useState(false); const [showNotifications, setNotifications] = useState(false);
const [messages, setMessages] = useState([]); const [messages, setMessages] = useState<string[]>([]);
const [handleNostrLinks, setHandleNostrLinks] = useState(false); const [handleNostrLinks, setHandleNostrLinks] = useState(false);
const [showProtocolHandlerHelp, setShowProtocolHandlerHelp] = useState(false); const [showProtocolHandlerHelp, setShowProtocolHandlerHelp] = useState(false);
const [unsavedChanges, setUnsavedChanges] = useState([]); const [unsavedChanges, setUnsavedChanges] = useState([]);
const showMessage = useCallback((msg) => { const showMessage = useCallback((msg: string) => {
messages.push(msg); messages.push(msg);
setMessages(messages); setMessages(messages);
setTimeout(() => setMessages([]), 3000); setTimeout(() => setMessages([]), 3000);
}); }, []);
useEffect(() => { useEffect(() => {
browser.storage.local browser.storage.local
@@ -515,7 +516,7 @@ examples:
} }
async function generate() { async function generate() {
setPrivKey(nip19.nsecEncode(generatePrivateKey())); setPrivKey(nip19.nsecEncode(generateSecretKey()));
addUnsavedChanges("private_key"); addUnsavedChanges("private_key");
} }

View File

@@ -1,13 +1,21 @@
import * as Tabs from "@radix-ui/react-tabs"; import * as Tabs from "@radix-ui/react-tabs";
import { minidenticon } from "minidenticons"; import { minidenticon } from "minidenticons";
import { getPublicKey, nip19 } from "nostr-tools"; import { getPublicKey, nip19 } from "nostr-tools";
import React, { useState, useMemo, useEffect } from "react"; import { useState, useMemo, useEffect } from "react";
import QRCode from "react-qr-code"; import QRCode from "react-qr-code";
import browser from "webextension-polyfill"; import browser from "webextension-polyfill";
import { SettingsIcon } from "./icons"; import { SettingsIcon } from "./icons";
import { createRoot } from "react-dom/client";
type Keys = {
npub: string;
hex: string;
nprofile: string;
};
function Popup() { function Popup() {
const [keys, setKeys] = useState(null); const [keys, setKeys] = useState<Keys | null>(null);
const avatarURI = useMemo( const avatarURI = useMemo(
() => () =>
keys keys
@@ -25,26 +33,38 @@ function Popup() {
useEffect(() => { useEffect(() => {
browser.storage.local.get(["private_key", "relays"]).then((results) => { browser.storage.local.get(["private_key", "relays"]).then((results) => {
if (results.private_key) { if (results.private_key) {
const hexKey = getPublicKey(results.private_key); const decoded = nip19.decode(results.private_key as unknown as string);
const npubKey = nip19.npubEncode(hexKey);
setKeys({ npub: npubKey, hex: hexKey }); if (decoded.type === "nsec") {
const nsec = decoded.data;
const hexKey = getPublicKey(nsec);
const npubKey = nip19.npubEncode(hexKey);
if (results.relays) { setKeys({ npub: npubKey, hex: hexKey, nprofile: "" });
const relaysList = [];
for (const url in results.relays) { if (results.relays) {
if (results.relays[url].write) { const relaysList: string[] = [];
relaysList.push(url);
if (relaysList.length >= 3) break; for (const url in results.relays) {
if (results.relays[url].write) {
relaysList.push(url);
if (relaysList.length >= 3) break;
}
}
if (relaysList.length) {
const nprofileKey = nip19.nprofileEncode({
pubkey: hexKey,
relays: relaysList,
});
setKeys((prev) =>
prev ? { ...prev, nprofile: nprofileKey } : null,
);
} }
} }
if (relaysList.length) { } else {
const nprofileKey = nip19.nprofileEncode({ setKeys(null);
pubkey: hexKey,
relays: relaysList,
});
setKeys((prev) => ({ ...prev, nprofile: nprofileKey }));
}
} }
} else { } else {
setKeys(null); setKeys(null);
@@ -179,6 +199,6 @@ function Popup() {
} }
const container = document.getElementById("main"); const container = document.getElementById("main");
const root = createRoot(container); const root = createRoot(container!);
root.render(<Popup />); root.render(<Popup />);

View File

@@ -1,4 +1,5 @@
import React, { useState } from "react"; import { useState } from "react";
import { createRoot } from "react-dom/client";
import browser from "webextension-polyfill"; import browser from "webextension-polyfill";
import * as Checkbox from "@radix-ui/react-checkbox"; import * as Checkbox from "@radix-ui/react-checkbox";
import { PERMISSION_NAMES } from "./common"; import { PERMISSION_NAMES } from "./common";
@@ -12,20 +13,27 @@ function Prompt() {
const host = qs.get("host"); const host = qs.get("host");
const type = qs.get("type"); const type = qs.get("type");
let params; let params: { [key: string]: string } | null;
let event; let event = "";
try { try {
params = JSON.parse(qs.get("params")); params = JSON.parse(qs.get("params") as string);
if (Object.keys(params).length === 0) params = null;
else if (params.event) event = params.event; if (params) {
if (Object.keys(params).length === 0) {
params = null;
} else if (params.event) {
event = params.event;
}
}
} catch (err) { } catch (err) {
params = null; params = null;
} }
function authorizeHandler(accept) { function authorizeHandler(accept: boolean) {
const conditions = isRemember ? {} : null; const conditions = isRemember ? {} : null;
return (ev) => {
return (ev: React.FormEvent<HTMLInputElement>) => {
ev.preventDefault(); ev.preventDefault();
browser.runtime.sendMessage({ browser.runtime.sendMessage({
prompt: true, prompt: true,
@@ -46,7 +54,8 @@ function Prompt() {
<div className="flex flex-col items-center text-center"> <div className="flex flex-col items-center text-center">
<h1 className="font-semibold text-lg">{host}</h1> <h1 className="font-semibold text-lg">{host}</h1>
<p> <p>
is requesting your permission to <b>{PERMISSION_NAMES[type]}</b> is requesting your permission to{" "}
<b>{PERMISSION_NAMES[type ? type : "unknown"]}</b>
</p> </p>
</div> </div>
</div> </div>
@@ -63,7 +72,7 @@ function Prompt() {
<Checkbox.Root <Checkbox.Root
id="remember" id="remember"
className="flex h-6 w-6 appearance-none items-center justify-center rounded-lg bg-white outline-none border border-primary data-[state=checked]:bg-primary data-[state=checked]:border-secondary" className="flex h-6 w-6 appearance-none items-center justify-center rounded-lg bg-white outline-none border border-primary data-[state=checked]:bg-primary data-[state=checked]:border-secondary"
onCheckedChange={setIsRemember} onCheckedChange={() => setIsRemember((prev) => !prev)}
> >
<Checkbox.Indicator className="text-white"> <Checkbox.Indicator className="text-white">
<svg <svg
@@ -89,14 +98,14 @@ function Prompt() {
<div className="flex gap-3"> <div className="flex gap-3">
<button <button
type="button" type="button"
onClick={authorizeHandler(false)} onClick={() => authorizeHandler(false)}
className="flex-1 h-10 rounded-lg shadow-sm border border-primary inline-flex items-center justify-center font-semibold" className="flex-1 h-10 rounded-lg shadow-sm border border-primary inline-flex items-center justify-center font-semibold"
> >
Reject Reject
</button> </button>
<button <button
type="button" type="button"
onClick={authorizeHandler(true)} onClick={() => authorizeHandler(true)}
className="flex-1 h-10 rounded-lg shadow-sm border border-secondary bg-primary text-white inline-flex items-center justify-center font-semibold" className="flex-1 h-10 rounded-lg shadow-sm border border-secondary bg-primary text-white inline-flex items-center justify-center font-semibold"
> >
Authorize Authorize
@@ -109,6 +118,6 @@ function Prompt() {
} }
const container = document.getElementById("main"); const container = document.getElementById("main");
const root = createRoot(container); const root = createRoot(container!);
root.render(<Prompt />); root.render(<Prompt />);

View File

@@ -1,9 +1,10 @@
{ {
"license": "WTFPL", "license": "WTFPL",
"dependencies": { "dependencies": {
"@noble/hashes": "^1.6.1",
"@radix-ui/react-checkbox": "^1.1.3", "@radix-ui/react-checkbox": "^1.1.3",
"@radix-ui/react-tabs": "^1.1.2", "@radix-ui/react-tabs": "^1.1.2",
"async-mutex": "^0.3.2", "async-mutex": "^0.5.0",
"esbuild": "^0.14.54", "esbuild": "^0.14.54",
"events": "^3.3.0", "events": "^3.3.0",
"minidenticons": "^4.2.1", "minidenticons": "^4.2.1",
@@ -24,8 +25,11 @@
}, },
"devDependencies": { "devDependencies": {
"@biomejs/biome": "1.9.4", "@biomejs/biome": "1.9.4",
"@types/react": "^19.0.2",
"@types/react-dom": "^19.0.2",
"@types/webextension-polyfill": "^0.12.1", "@types/webextension-polyfill": "^0.12.1",
"esbuild-plugin-copy": "^2.1.1", "esbuild-plugin-copy": "^2.1.1",
"tailwindcss": "^3.4.17" "tailwindcss": "^3.4.17",
"typescript": "^5.7.2"
} }
} }

205
pnpm-lock.yaml generated
View File

@@ -8,15 +8,18 @@ importers:
.: .:
dependencies: dependencies:
'@noble/hashes':
specifier: ^1.6.1
version: 1.6.1
'@radix-ui/react-checkbox': '@radix-ui/react-checkbox':
specifier: ^1.1.3 specifier: ^1.1.3
version: 1.1.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0) version: 1.1.3(@types/react-dom@19.0.2(@types/react@19.0.2))(@types/react@19.0.2)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@radix-ui/react-tabs': '@radix-ui/react-tabs':
specifier: ^1.1.2 specifier: ^1.1.2
version: 1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) version: 1.1.2(@types/react-dom@19.0.2(@types/react@19.0.2))(@types/react@19.0.2)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
async-mutex: async-mutex:
specifier: ^0.3.2 specifier: ^0.5.0
version: 0.3.2 version: 0.5.0
esbuild: esbuild:
specifier: ^0.14.54 specifier: ^0.14.54
version: 0.14.54 version: 0.14.54
@@ -28,7 +31,7 @@ importers:
version: 4.2.1 version: 4.2.1
nostr-tools: nostr-tools:
specifier: ^2.10.4 specifier: ^2.10.4
version: 2.10.4 version: 2.10.4(typescript@5.7.2)
react: react:
specifier: ^19.0.0 specifier: ^19.0.0
version: 19.0.0 version: 19.0.0
@@ -54,6 +57,12 @@ importers:
'@biomejs/biome': '@biomejs/biome':
specifier: 1.9.4 specifier: 1.9.4
version: 1.9.4 version: 1.9.4
'@types/react':
specifier: ^19.0.2
version: 19.0.2
'@types/react-dom':
specifier: ^19.0.2
version: 19.0.2(@types/react@19.0.2)
'@types/webextension-polyfill': '@types/webextension-polyfill':
specifier: ^0.12.1 specifier: ^0.12.1
version: 0.12.1 version: 0.12.1
@@ -63,6 +72,9 @@ importers:
tailwindcss: tailwindcss:
specifier: ^3.4.17 specifier: ^3.4.17
version: 3.4.17 version: 3.4.17
typescript:
specifier: ^5.7.2
version: 5.7.2
packages: packages:
@@ -901,6 +913,10 @@ packages:
resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==}
engines: {node: '>= 16'} engines: {node: '>= 16'}
'@noble/hashes@1.6.1':
resolution: {integrity: sha512-pq5D8h10hHBjyqX+cfBm0i8JUXJ0UhczFc4r74zbuT9XgewFo2E3J1cOaGtdZynILNmQ685YWGzGE1Zv6io50w==}
engines: {node: ^14.21.3 || >=16}
'@nodelib/fs.scandir@2.1.5': '@nodelib/fs.scandir@2.1.5':
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
engines: {node: '>= 8'} engines: {node: '>= 8'}
@@ -1187,6 +1203,14 @@ packages:
'@types/node@22.10.2': '@types/node@22.10.2':
resolution: {integrity: sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==} resolution: {integrity: sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==}
'@types/react-dom@19.0.2':
resolution: {integrity: sha512-c1s+7TKFaDRRxr1TxccIX2u7sfCnc3RxkVyBIUA2lCpyqCF+QoAwQ/CBg7bsMdVwP120HEH143VQezKtef5nCg==}
peerDependencies:
'@types/react': ^19.0.0
'@types/react@19.0.2':
resolution: {integrity: sha512-USU8ZI/xyKJwFTpjSVIrSeHBVAGagkHQKPNbxeWwql/vDmnTIBgx+TJnhFnj1NXgz8XfprU0egV2dROLGpsBEg==}
'@types/stack-utils@2.0.3': '@types/stack-utils@2.0.3':
resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==}
@@ -1286,8 +1310,8 @@ packages:
async-limiter@1.0.1: async-limiter@1.0.1:
resolution: {integrity: sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==} resolution: {integrity: sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==}
async-mutex@0.3.2: async-mutex@0.5.0:
resolution: {integrity: sha512-HuTK7E7MT7jZEh1P9GtRW9+aTWiDWWi9InbZ5hjxrnRa39KS4BW04+xLBhYNS2aXhHUIKZSw3gj4Pn1pj+qGAA==} resolution: {integrity: sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA==}
async@3.2.6: async@3.2.6:
resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==}
@@ -1526,6 +1550,9 @@ packages:
engines: {node: '>=4'} engines: {node: '>=4'}
hasBin: true hasBin: true
csstype@3.1.3:
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
dayjs@1.11.13: dayjs@1.11.13:
resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==}
@@ -2971,6 +2998,11 @@ packages:
resolution: {integrity: sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==} resolution: {integrity: sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==}
engines: {node: '>=8'} engines: {node: '>=8'}
typescript@5.7.2:
resolution: {integrity: sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==}
engines: {node: '>=14.17'}
hasBin: true
uglify-es@3.3.9: uglify-es@3.3.9:
resolution: {integrity: sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==} resolution: {integrity: sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==}
engines: {node: '>=0.8.0'} engines: {node: '>=0.8.0'}
@@ -4185,6 +4217,8 @@ snapshots:
'@noble/hashes@1.3.2': {} '@noble/hashes@1.3.2': {}
'@noble/hashes@1.6.1': {}
'@nodelib/fs.scandir@2.1.5': '@nodelib/fs.scandir@2.1.5':
dependencies: dependencies:
'@nodelib/fs.stat': 2.0.5 '@nodelib/fs.stat': 2.0.5
@@ -4202,111 +4236,149 @@ snapshots:
'@radix-ui/primitive@1.1.1': {} '@radix-ui/primitive@1.1.1': {}
'@radix-ui/react-checkbox@1.1.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': '@radix-ui/react-checkbox@1.1.3(@types/react-dom@19.0.2(@types/react@19.0.2))(@types/react@19.0.2)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
dependencies: dependencies:
'@radix-ui/primitive': 1.1.1 '@radix-ui/primitive': 1.1.1
'@radix-ui/react-compose-refs': 1.1.1(react@19.0.0) '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.2)(react@19.0.0)
'@radix-ui/react-context': 1.1.1(react@19.0.0) '@radix-ui/react-context': 1.1.1(@types/react@19.0.2)(react@19.0.0)
'@radix-ui/react-presence': 1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.0.2(@types/react@19.0.2))(@types/react@19.0.2)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@radix-ui/react-primitive': 2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@radix-ui/react-primitive': 2.0.1(@types/react-dom@19.0.2(@types/react@19.0.2))(@types/react@19.0.2)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@radix-ui/react-use-controllable-state': 1.1.0(react@19.0.0) '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.2)(react@19.0.0)
'@radix-ui/react-use-previous': 1.1.0(react@19.0.0) '@radix-ui/react-use-previous': 1.1.0(@types/react@19.0.2)(react@19.0.0)
'@radix-ui/react-use-size': 1.1.0(react@19.0.0) '@radix-ui/react-use-size': 1.1.0(@types/react@19.0.2)(react@19.0.0)
react: 19.0.0 react: 19.0.0
react-dom: 19.0.0(react@19.0.0) react-dom: 19.0.0(react@19.0.0)
optionalDependencies:
'@types/react': 19.0.2
'@types/react-dom': 19.0.2(@types/react@19.0.2)
'@radix-ui/react-collection@1.1.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': '@radix-ui/react-collection@1.1.1(@types/react-dom@19.0.2(@types/react@19.0.2))(@types/react@19.0.2)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
dependencies: dependencies:
'@radix-ui/react-compose-refs': 1.1.1(react@19.0.0) '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.2)(react@19.0.0)
'@radix-ui/react-context': 1.1.1(react@19.0.0) '@radix-ui/react-context': 1.1.1(@types/react@19.0.2)(react@19.0.0)
'@radix-ui/react-primitive': 2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@radix-ui/react-primitive': 2.0.1(@types/react-dom@19.0.2(@types/react@19.0.2))(@types/react@19.0.2)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@radix-ui/react-slot': 1.1.1(react@19.0.0) '@radix-ui/react-slot': 1.1.1(@types/react@19.0.2)(react@19.0.0)
react: 19.0.0 react: 19.0.0
react-dom: 19.0.0(react@19.0.0) react-dom: 19.0.0(react@19.0.0)
optionalDependencies:
'@types/react': 19.0.2
'@types/react-dom': 19.0.2(@types/react@19.0.2)
'@radix-ui/react-compose-refs@1.1.1(react@19.0.0)': '@radix-ui/react-compose-refs@1.1.1(@types/react@19.0.2)(react@19.0.0)':
dependencies: dependencies:
react: 19.0.0 react: 19.0.0
optionalDependencies:
'@types/react': 19.0.2
'@radix-ui/react-context@1.1.1(react@19.0.0)': '@radix-ui/react-context@1.1.1(@types/react@19.0.2)(react@19.0.0)':
dependencies: dependencies:
react: 19.0.0 react: 19.0.0
optionalDependencies:
'@types/react': 19.0.2
'@radix-ui/react-direction@1.1.0(react@19.0.0)': '@radix-ui/react-direction@1.1.0(@types/react@19.0.2)(react@19.0.0)':
dependencies: dependencies:
react: 19.0.0 react: 19.0.0
optionalDependencies:
'@types/react': 19.0.2
'@radix-ui/react-id@1.1.0(react@19.0.0)': '@radix-ui/react-id@1.1.0(@types/react@19.0.2)(react@19.0.0)':
dependencies: dependencies:
'@radix-ui/react-use-layout-effect': 1.1.0(react@19.0.0) '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.2)(react@19.0.0)
react: 19.0.0 react: 19.0.0
optionalDependencies:
'@types/react': 19.0.2
'@radix-ui/react-presence@1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': '@radix-ui/react-presence@1.1.2(@types/react-dom@19.0.2(@types/react@19.0.2))(@types/react@19.0.2)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
dependencies: dependencies:
'@radix-ui/react-compose-refs': 1.1.1(react@19.0.0) '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.2)(react@19.0.0)
'@radix-ui/react-use-layout-effect': 1.1.0(react@19.0.0) '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.2)(react@19.0.0)
react: 19.0.0 react: 19.0.0
react-dom: 19.0.0(react@19.0.0) react-dom: 19.0.0(react@19.0.0)
optionalDependencies:
'@types/react': 19.0.2
'@types/react-dom': 19.0.2(@types/react@19.0.2)
'@radix-ui/react-primitive@2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': '@radix-ui/react-primitive@2.0.1(@types/react-dom@19.0.2(@types/react@19.0.2))(@types/react@19.0.2)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
dependencies: dependencies:
'@radix-ui/react-slot': 1.1.1(react@19.0.0) '@radix-ui/react-slot': 1.1.1(@types/react@19.0.2)(react@19.0.0)
react: 19.0.0 react: 19.0.0
react-dom: 19.0.0(react@19.0.0) react-dom: 19.0.0(react@19.0.0)
optionalDependencies:
'@types/react': 19.0.2
'@types/react-dom': 19.0.2(@types/react@19.0.2)
'@radix-ui/react-roving-focus@1.1.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': '@radix-ui/react-roving-focus@1.1.1(@types/react-dom@19.0.2(@types/react@19.0.2))(@types/react@19.0.2)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
dependencies: dependencies:
'@radix-ui/primitive': 1.1.1 '@radix-ui/primitive': 1.1.1
'@radix-ui/react-collection': 1.1.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@radix-ui/react-collection': 1.1.1(@types/react-dom@19.0.2(@types/react@19.0.2))(@types/react@19.0.2)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@radix-ui/react-compose-refs': 1.1.1(react@19.0.0) '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.2)(react@19.0.0)
'@radix-ui/react-context': 1.1.1(react@19.0.0) '@radix-ui/react-context': 1.1.1(@types/react@19.0.2)(react@19.0.0)
'@radix-ui/react-direction': 1.1.0(react@19.0.0) '@radix-ui/react-direction': 1.1.0(@types/react@19.0.2)(react@19.0.0)
'@radix-ui/react-id': 1.1.0(react@19.0.0) '@radix-ui/react-id': 1.1.0(@types/react@19.0.2)(react@19.0.0)
'@radix-ui/react-primitive': 2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@radix-ui/react-primitive': 2.0.1(@types/react-dom@19.0.2(@types/react@19.0.2))(@types/react@19.0.2)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@radix-ui/react-use-callback-ref': 1.1.0(react@19.0.0) '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.2)(react@19.0.0)
'@radix-ui/react-use-controllable-state': 1.1.0(react@19.0.0) '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.2)(react@19.0.0)
react: 19.0.0 react: 19.0.0
react-dom: 19.0.0(react@19.0.0) react-dom: 19.0.0(react@19.0.0)
optionalDependencies:
'@types/react': 19.0.2
'@types/react-dom': 19.0.2(@types/react@19.0.2)
'@radix-ui/react-slot@1.1.1(react@19.0.0)': '@radix-ui/react-slot@1.1.1(@types/react@19.0.2)(react@19.0.0)':
dependencies: dependencies:
'@radix-ui/react-compose-refs': 1.1.1(react@19.0.0) '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.2)(react@19.0.0)
react: 19.0.0 react: 19.0.0
optionalDependencies:
'@types/react': 19.0.2
'@radix-ui/react-tabs@1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': '@radix-ui/react-tabs@1.1.2(@types/react-dom@19.0.2(@types/react@19.0.2))(@types/react@19.0.2)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
dependencies: dependencies:
'@radix-ui/primitive': 1.1.1 '@radix-ui/primitive': 1.1.1
'@radix-ui/react-context': 1.1.1(react@19.0.0) '@radix-ui/react-context': 1.1.1(@types/react@19.0.2)(react@19.0.0)
'@radix-ui/react-direction': 1.1.0(react@19.0.0) '@radix-ui/react-direction': 1.1.0(@types/react@19.0.2)(react@19.0.0)
'@radix-ui/react-id': 1.1.0(react@19.0.0) '@radix-ui/react-id': 1.1.0(@types/react@19.0.2)(react@19.0.0)
'@radix-ui/react-presence': 1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.0.2(@types/react@19.0.2))(@types/react@19.0.2)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@radix-ui/react-primitive': 2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@radix-ui/react-primitive': 2.0.1(@types/react-dom@19.0.2(@types/react@19.0.2))(@types/react@19.0.2)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@radix-ui/react-roving-focus': 1.1.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@radix-ui/react-roving-focus': 1.1.1(@types/react-dom@19.0.2(@types/react@19.0.2))(@types/react@19.0.2)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@radix-ui/react-use-controllable-state': 1.1.0(react@19.0.0) '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.2)(react@19.0.0)
react: 19.0.0 react: 19.0.0
react-dom: 19.0.0(react@19.0.0) react-dom: 19.0.0(react@19.0.0)
optionalDependencies:
'@types/react': 19.0.2
'@types/react-dom': 19.0.2(@types/react@19.0.2)
'@radix-ui/react-use-callback-ref@1.1.0(react@19.0.0)': '@radix-ui/react-use-callback-ref@1.1.0(@types/react@19.0.2)(react@19.0.0)':
dependencies: dependencies:
react: 19.0.0 react: 19.0.0
optionalDependencies:
'@types/react': 19.0.2
'@radix-ui/react-use-controllable-state@1.1.0(react@19.0.0)': '@radix-ui/react-use-controllable-state@1.1.0(@types/react@19.0.2)(react@19.0.0)':
dependencies: dependencies:
'@radix-ui/react-use-callback-ref': 1.1.0(react@19.0.0) '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.2)(react@19.0.0)
react: 19.0.0 react: 19.0.0
optionalDependencies:
'@types/react': 19.0.2
'@radix-ui/react-use-layout-effect@1.1.0(react@19.0.0)': '@radix-ui/react-use-layout-effect@1.1.0(@types/react@19.0.2)(react@19.0.0)':
dependencies: dependencies:
react: 19.0.0 react: 19.0.0
optionalDependencies:
'@types/react': 19.0.2
'@radix-ui/react-use-previous@1.1.0(react@19.0.0)': '@radix-ui/react-use-previous@1.1.0(@types/react@19.0.2)(react@19.0.0)':
dependencies: dependencies:
react: 19.0.0 react: 19.0.0
optionalDependencies:
'@types/react': 19.0.2
'@radix-ui/react-use-size@1.1.0(react@19.0.0)': '@radix-ui/react-use-size@1.1.0(@types/react@19.0.2)(react@19.0.0)':
dependencies: dependencies:
'@radix-ui/react-use-layout-effect': 1.1.0(react@19.0.0) '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.2)(react@19.0.0)
react: 19.0.0 react: 19.0.0
optionalDependencies:
'@types/react': 19.0.2
'@react-native-community/cli-clean@11.3.10': '@react-native-community/cli-clean@11.3.10':
dependencies: dependencies:
@@ -4501,12 +4573,12 @@ snapshots:
'@scure/bip32@1.3.1': '@scure/bip32@1.3.1':
dependencies: dependencies:
'@noble/curves': 1.1.0 '@noble/curves': 1.1.0
'@noble/hashes': 1.3.1 '@noble/hashes': 1.3.2
'@scure/base': 1.1.1 '@scure/base': 1.1.1
'@scure/bip39@1.2.1': '@scure/bip39@1.2.1':
dependencies: dependencies:
'@noble/hashes': 1.3.1 '@noble/hashes': 1.3.2
'@scure/base': 1.1.1 '@scure/base': 1.1.1
'@sideway/address@4.1.5': '@sideway/address@4.1.5':
@@ -4541,6 +4613,14 @@ snapshots:
dependencies: dependencies:
undici-types: 6.20.0 undici-types: 6.20.0
'@types/react-dom@19.0.2(@types/react@19.0.2)':
dependencies:
'@types/react': 19.0.2
'@types/react@19.0.2':
dependencies:
csstype: 3.1.3
'@types/stack-utils@2.0.3': {} '@types/stack-utils@2.0.3': {}
'@types/webextension-polyfill@0.12.1': {} '@types/webextension-polyfill@0.12.1': {}
@@ -4623,7 +4703,7 @@ snapshots:
async-limiter@1.0.1: {} async-limiter@1.0.1: {}
async-mutex@0.3.2: async-mutex@0.5.0:
dependencies: dependencies:
tslib: 2.8.1 tslib: 2.8.1
@@ -4916,6 +4996,8 @@ snapshots:
cssesc@3.0.0: {} cssesc@3.0.0: {}
csstype@3.1.3: {}
dayjs@1.11.13: {} dayjs@1.11.13: {}
debug@2.6.9: debug@2.6.9:
@@ -5870,7 +5952,7 @@ snapshots:
normalize-path@3.0.0: {} normalize-path@3.0.0: {}
nostr-tools@2.10.4: nostr-tools@2.10.4(typescript@5.7.2):
dependencies: dependencies:
'@noble/ciphers': 0.5.3 '@noble/ciphers': 0.5.3
'@noble/curves': 1.2.0 '@noble/curves': 1.2.0
@@ -5880,6 +5962,7 @@ snapshots:
'@scure/bip39': 1.2.1 '@scure/bip39': 1.2.1
optionalDependencies: optionalDependencies:
nostr-wasm: 0.1.0 nostr-wasm: 0.1.0
typescript: 5.7.2
nostr-wasm@0.1.0: nostr-wasm@0.1.0:
optional: true optional: true
@@ -6488,6 +6571,8 @@ snapshots:
type-fest@0.7.1: {} type-fest@0.7.1: {}
typescript@5.7.2: {}
uglify-es@3.3.9: uglify-es@3.3.9:
dependencies: dependencies:
commander: 2.13.0 commander: 2.13.0

24
tsconfig.json Normal file
View File

@@ -0,0 +1,24 @@
{
"compilerOptions": {
"target": "ESNext",
"useDefineForClassFields": true,
"lib": ["ESNext", "ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"strict": true,
"noUnusedLocals": true,
"noImplicitAny": false,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"paths": {
"*": ["./extension/*.d.ts"]
}
},
"include": ["extension"]
}