diff --git a/packages/app/package.json b/packages/app/package.json index 62bf05dcb..0b1d73072 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -3,14 +3,14 @@ "version": "0.1.8", "private": true, "dependencies": { + "@cashu/cashu-ts": "^0.6.1", "@fortawesome/fontawesome-svg-core": "^6.2.1", "@fortawesome/free-solid-svg-icons": "^6.2.1", "@fortawesome/react-fontawesome": "^0.2.0", - "@cashu/cashu-ts": "^0.6.1", "@jukben/emoji-search": "^2.0.1", "@lightninglabs/lnc-web": "^0.2.3-alpha", + "@noble/curves": "^1.0.0", "@noble/hashes": "^1.2.0", - "@noble/secp256k1": "^1.7.0", "@protobufjs/base64": "^1.1.2", "@reduxjs/toolkit": "^1.9.1", "@scure/bip32": "^1.1.5", @@ -69,7 +69,11 @@ }, "browserslist": { "production": [ - ">0.5%" + "chrome >= 67", + "edge >= 79", + "firefox >= 68", + "opera >= 54", + "safari >= 14" ], "development": [ "last 1 chrome version", diff --git a/packages/app/src/Hooks/useImgProxy.ts b/packages/app/src/Hooks/useImgProxy.ts index ca41e386b..3cf5d4bf8 100644 --- a/packages/app/src/Hooks/useImgProxy.ts +++ b/packages/app/src/Hooks/useImgProxy.ts @@ -1,4 +1,4 @@ -import * as secp from "@noble/secp256k1"; +import * as utils from "@noble/curves/abstract/utils"; import * as base64 from "@protobufjs/base64"; import { hmacSha256, unwrap } from "Util"; import useLogin from "Hooks/useLogin"; @@ -19,8 +19,8 @@ export default function useImgProxy() { function signUrl(u: string) { const result = hmacSha256( - secp.utils.hexToBytes(unwrap(settings).key), - secp.utils.hexToBytes(unwrap(settings).salt), + utils.hexToBytes(unwrap(settings).key), + utils.hexToBytes(unwrap(settings).salt), te.encode(u) ); return urlSafe(base64.encode(result, 0, result.byteLength)); diff --git a/packages/app/src/Hooks/useLoginHandler.tsx b/packages/app/src/Hooks/useLoginHandler.tsx index 4d08cf4e2..156844df4 100644 --- a/packages/app/src/Hooks/useLoginHandler.tsx +++ b/packages/app/src/Hooks/useLoginHandler.tsx @@ -1,5 +1,4 @@ import { useIntl } from "react-intl"; -import * as secp from "@noble/secp256k1"; import { EmailRegex, MnemonicRegex } from "Const"; import { LoginStore } from "Login"; @@ -21,7 +20,7 @@ export default function useLoginHandler() { throw new Error(insecureMsg); } const hexKey = bech32ToHex(key); - if (secp.utils.isValidPrivateKey(hexKey)) { + if (hexKey.length === 64) { LoginStore.loginWithPrivateKey(hexKey); } else { throw new Error("INVALID PRIVATE KEY"); @@ -39,7 +38,7 @@ export default function useLoginHandler() { const ent = generateBip39Entropy(key); const keyHex = entropyToPrivateKey(ent); LoginStore.loginWithPrivateKey(keyHex); - } else if (secp.utils.isValidPrivateKey(key)) { + } else if (key.length === 64) { if (!hasSubtleCrypto) { throw new Error(insecureMsg); } diff --git a/packages/app/src/Login/Functions.ts b/packages/app/src/Login/Functions.ts index 567a4cfa4..9be5e0a78 100644 --- a/packages/app/src/Login/Functions.ts +++ b/packages/app/src/Login/Functions.ts @@ -1,5 +1,6 @@ import { HexKey, RelaySettings } from "@snort/nostr"; -import * as secp from "@noble/secp256k1"; +import * as secp from "@noble/curves/secp256k1"; +import * as utils from "@noble/curves/abstract/utils"; import { DefaultRelays, SnortPubKey } from "Const"; import { LoginStore, UserPreferences, LoginSession } from "Login"; @@ -57,7 +58,7 @@ export function clearEntropy(state: LoginSession) { */ export async function generateNewLogin() { const ent = generateBip39Entropy(); - const entropy = secp.utils.bytesToHex(ent); + const entropy = utils.bytesToHex(ent); const privateKey = entropyToPrivateKey(ent); let newRelays: Record = {}; @@ -76,7 +77,7 @@ export async function generateNewLogin() { console.warn(e); } - const publicKey = secp.utils.bytesToHex(secp.schnorr.getPublicKey(privateKey)); + const publicKey = utils.bytesToHex(secp.schnorr.getPublicKey(privateKey)); const publisher = new EventPublisher(publicKey, privateKey); const ev = await publisher.contactList([bech32ToHex(SnortPubKey), publicKey], newRelays); publisher.broadcast(ev); @@ -85,8 +86,8 @@ export async function generateNewLogin() { } export function generateRandomKey() { - const privateKey = secp.utils.bytesToHex(secp.utils.randomPrivateKey()); - const publicKey = secp.utils.bytesToHex(secp.schnorr.getPublicKey(privateKey)); + const privateKey = utils.bytesToHex(secp.schnorr.utils.randomPrivateKey()); + const publicKey = utils.bytesToHex(secp.schnorr.getPublicKey(privateKey)); return { privateKey, publicKey, diff --git a/packages/app/src/Login/MultiAccountStore.ts b/packages/app/src/Login/MultiAccountStore.ts index 5ee61c6ef..916833a4c 100644 --- a/packages/app/src/Login/MultiAccountStore.ts +++ b/packages/app/src/Login/MultiAccountStore.ts @@ -1,4 +1,6 @@ -import * as secp from "@noble/secp256k1"; +import * as secp from "@noble/curves/secp256k1"; +import * as utils from "@noble/curves/abstract/utils"; + import { HexKey, RelaySettings } from "@snort/nostr"; import { DefaultRelays } from "Const"; @@ -113,7 +115,7 @@ export class MultiAccountStore extends ExternalStore { } loginWithPrivateKey(key: HexKey, entropy?: string, relays?: Record) { - const pubKey = secp.utils.bytesToHex(secp.schnorr.getPublicKey(key)); + const pubKey = utils.bytesToHex(secp.schnorr.getPublicKey(key)); if (this.#accounts.has(pubKey)) { throw new Error("Already logged in with this pubkey"); } @@ -167,7 +169,7 @@ export class MultiAccountStore extends ExternalStore { const privKey = window.localStorage.getItem(LegacyKeys.PrivateKeyItem); if (privKey) { - const pubKey = secp.utils.bytesToHex(secp.schnorr.getPublicKey(privKey)); + const pubKey = utils.bytesToHex(secp.schnorr.getPublicKey(privKey)); this.#accounts.set(pubKey, { ...LoggedOut, privateKey: privKey, diff --git a/packages/app/src/System/EventExt.ts b/packages/app/src/System/EventExt.ts index 269294689..934ff32bf 100644 --- a/packages/app/src/System/EventExt.ts +++ b/packages/app/src/System/EventExt.ts @@ -1,4 +1,5 @@ -import * as secp from "@noble/secp256k1"; +import * as secp from "@noble/curves/secp256k1"; +import * as utils from "@noble/curves/abstract/utils"; import { EventKind, HexKey, RawEvent, Tag } from "@snort/nostr"; import base64 from "@protobufjs/base64"; import { sha256, unixNow } from "Util"; @@ -29,7 +30,7 @@ export abstract class EventExt { e.id = this.createId(e); const sig = await secp.schnorr.sign(e.id, key); - e.sig = secp.utils.bytesToHex(sig); + e.sig = utils.bytesToHex(sig); if (!(await secp.schnorr.verify(e.sig, e.id, e.pubkey))) { throw new Error("Signing failed"); } @@ -158,7 +159,7 @@ export abstract class EventExt { } static async #getDmSharedKey(pubkey: HexKey, privkey: HexKey) { - const sharedPoint = secp.getSharedSecret(privkey, "02" + pubkey); + const sharedPoint = secp.secp256k1.getSharedSecret(privkey, "02" + pubkey); const sharedX = sharedPoint.slice(1, 33); return await window.crypto.subtle.importKey("raw", sharedX, { name: "AES-CBC" }, false, ["encrypt", "decrypt"]); } diff --git a/packages/app/src/System/EventPublisher.ts b/packages/app/src/System/EventPublisher.ts index 2408cecad..70fa3a0be 100644 --- a/packages/app/src/System/EventPublisher.ts +++ b/packages/app/src/System/EventPublisher.ts @@ -1,4 +1,5 @@ -import * as secp from "@noble/secp256k1"; +import * as secp from "@noble/curves/secp256k1"; +import * as utils from "@noble/curves/abstract/utils"; import { EventKind, FullRelaySettings, @@ -60,7 +61,7 @@ export class EventPublisher { constructor(pubKey: string, privKey?: string) { if (privKey) { this.#privateKey = privKey; - this.#pubKey = secp.utils.bytesToHex(secp.schnorr.getPublicKey(privKey)); + this.#pubKey = utils.bytesToHex(secp.schnorr.getPublicKey(privKey)); } else { this.#pubKey = pubKey; } diff --git a/packages/app/src/Upload/VoidCat.ts b/packages/app/src/Upload/VoidCat.ts index 99c878b43..bc7e014c9 100644 --- a/packages/app/src/Upload/VoidCat.ts +++ b/packages/app/src/Upload/VoidCat.ts @@ -1,4 +1,4 @@ -import * as secp from "@noble/secp256k1"; +import * as utils from "@noble/curves/abstract/utils"; import { EventKind } from "@snort/nostr"; import { FileExtensionRegex, VoidCatHost } from "Const"; import { EventPublisher } from "System/EventPublisher"; @@ -25,7 +25,7 @@ export default async function VoidCat( "Content-Type": "application/octet-stream", "V-Content-Type": file.type, "V-Filename": filename, - "V-Full-Digest": secp.utils.bytesToHex(new Uint8Array(digest)), + "V-Full-Digest": utils.bytesToHex(new Uint8Array(digest)), "V-Description": "Upload from https://snort.social", "V-Strip-Metadata": "true", }, diff --git a/packages/app/src/Util.ts b/packages/app/src/Util.ts index d8d2eab4c..a886be4dd 100644 --- a/packages/app/src/Util.ts +++ b/packages/app/src/Util.ts @@ -1,4 +1,5 @@ -import * as secp from "@noble/secp256k1"; +import * as secp from "@noble/curves/secp256k1"; +import * as utils from "@noble/curves/abstract/utils"; import { sha256 as hash } from "@noble/hashes/sha256"; import { hmac } from "@noble/hashes/hmac"; import { bytesToHex } from "@noble/hashes/utils"; @@ -19,11 +20,11 @@ import { import { MetadataCache } from "Cache"; export const sha256 = (str: string | Uint8Array): u256 => { - return secp.utils.bytesToHex(hash(str)); + return utils.bytesToHex(hash(str)); }; export function getPublicKey(privKey: HexKey) { - return secp.utils.bytesToHex(secp.schnorr.getPublicKey(privKey)); + return utils.bytesToHex(secp.schnorr.getPublicKey(privKey)); } export async function openFile(): Promise { @@ -63,7 +64,7 @@ export function bech32ToHex(str: string) { try { const nKey = bech32.decode(str, 1_000); const buff = bech32.fromWords(nKey.words); - return secp.utils.bytesToHex(Uint8Array.from(buff)); + return utils.bytesToHex(Uint8Array.from(buff)); } catch { return str; } @@ -116,7 +117,7 @@ export function hexToBech32(hrp: string, hex?: string) { try { if (hrp === NostrPrefix.Note || hrp === NostrPrefix.PrivateKey || hrp === NostrPrefix.PublicKey) { - const buf = secp.utils.hexToBytes(hex); + const buf = utils.hexToBytes(hex); return bech32.encode(hrp, bech32.toWords(buf)); } else { return encodeTLV(hrp as NostrPrefix, hex); @@ -488,7 +489,7 @@ export function findTag(e: RawEvent, tag: string) { } export function hmacSha256(key: Uint8Array, ...messages: Uint8Array[]) { - return hmac(hash, key, secp.utils.concatBytes(...messages)); + return hmac(hash, key, utils.concatBytes(...messages)); } export function getRelayName(url: string) { diff --git a/packages/app/src/nip6.ts b/packages/app/src/nip6.ts index 9f7f150ca..091329605 100644 --- a/packages/app/src/nip6.ts +++ b/packages/app/src/nip6.ts @@ -1,4 +1,4 @@ -import * as secp from "@noble/secp256k1"; +import * as utils from "@noble/curves/abstract/utils"; import * as bip39 from "@scure/bip39"; import { wordlist } from "@scure/bip39/wordlists/english"; import { HDKey } from "@scure/bip32"; @@ -18,7 +18,7 @@ export function generateBip39Entropy(mnemonic?: string): Uint8Array { * Convert hex-encoded entropy into mnemonic phrase */ export function hexToMnemonic(hex: string): string { - const bytes = secp.utils.hexToBytes(hex); + const bytes = utils.hexToBytes(hex); return bip39.entropyToMnemonic(bytes, wordlist); } @@ -33,5 +33,5 @@ export function entropyToPrivateKey(entropy: Uint8Array): string { throw new Error("INVALID KEY DERIVATION"); } - return secp.utils.bytesToHex(newKey.privateKey); + return utils.bytesToHex(newKey.privateKey); } diff --git a/packages/nostr/package.json b/packages/nostr/package.json index e31e2d21f..41f8d9ce3 100644 --- a/packages/nostr/package.json +++ b/packages/nostr/package.json @@ -29,8 +29,8 @@ "semi": false }, "dependencies": { + "@noble/curves": "^1.0.0", "@noble/hashes": "^1.2.0", - "@noble/secp256k1": "^1.7.1", "@types/chai": "^4.3.4", "@types/uuid": "^9.0.1", "base64-js": "^1.5.1", @@ -47,8 +47,22 @@ "directories": { "test": "test" }, + "browserslist": { + "production": [ + "chrome >= 67", + "edge >= 79", + "firefox >= 68", + "opera >= 54", + "safari >= 14" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + }, "keywords": [], "author": "", "license": "ISC", "description": "" -} +} \ No newline at end of file diff --git a/packages/nostr/src/client/conn.ts b/packages/nostr/src/client/conn.ts index 4584fbe91..1abeb8038 100644 --- a/packages/nostr/src/client/conn.ts +++ b/packages/nostr/src/client/conn.ts @@ -38,7 +38,7 @@ export class Conn { onError, }: { url: URL - onMessage: (msg: IncomingMessage) => Promise + onMessage: (msg: IncomingMessage) => void onOpen: () => Promise onClose: () => void onError: (err: unknown) => void @@ -55,7 +55,7 @@ export class Conn { throw new NostrError(`invalid message data: ${value}`) } const msg = parseIncomingMessage(value) - await onMessage(msg) + onMessage(msg) } catch (err) { onError(err) } diff --git a/packages/nostr/src/client/index.ts b/packages/nostr/src/client/index.ts index df11d1bcb..2f7ccf661 100644 --- a/packages/nostr/src/client/index.ts +++ b/packages/nostr/src/client/index.ts @@ -1,7 +1,7 @@ import { NostrError } from "../common" import { RawEvent, parseEvent } from "../event" import { Conn } from "./conn" -import * as secp from "@noble/secp256k1" +import * as utils from "@noble/curves/abstract/utils"; import { EventEmitter } from "./emitter" import { fetchRelayInfo, ReadyState, Relay } from "./relay" import { Filters } from "../filters" @@ -71,21 +71,21 @@ export class Nostr extends EventEmitter { opts?.fetchInfo === false ? Promise.resolve({}) : fetchRelayInfo(relayUrl).catch((e) => { - this.#error(e) - return {} - }) + this.#error(e) + return {} + }) // If there is no existing connection, open a new one. const conn = new Conn({ url: relayUrl, // Handle messages on this connection. - onMessage: async (msg) => { + onMessage: (msg) => { if (msg.kind === "event") { this.emit( "event", { - event: await parseEvent(msg.event), + event: parseEvent(msg.event), subscriptionId: msg.subscriptionId, }, this @@ -128,8 +128,7 @@ export class Nostr extends EventEmitter { if (conn.relay.readyState !== ReadyState.CONNECTING) { this.#error( new NostrError( - `bug: expected connection to ${relayUrl.toString()} to have readyState CONNECTING, got ${ - conn.relay.readyState + `bug: expected connection to ${relayUrl.toString()} to have readyState CONNECTING, got ${conn.relay.readyState }` ) ) @@ -294,7 +293,7 @@ export class Nostr extends EventEmitter { relay.info === undefined ? undefined : // Deep copy of the info. - JSON.parse(JSON.stringify(relay.info)) + JSON.parse(JSON.stringify(relay.info)) return { ...relay, info } } }) @@ -330,5 +329,5 @@ interface ConnState { export type SubscriptionId = string function randomSubscriptionId(): SubscriptionId { - return secp.utils.bytesToHex(secp.utils.randomBytes(32)) + return utils.bytesToHex(globalThis.crypto.getRandomValues(new Uint8Array(32))) } diff --git a/packages/nostr/src/crypto.ts b/packages/nostr/src/crypto.ts index caee0388c..d68aeffa8 100644 --- a/packages/nostr/src/crypto.ts +++ b/packages/nostr/src/crypto.ts @@ -1,4 +1,6 @@ -import * as secp from "@noble/secp256k1" +import * as secp from "@noble/curves/secp256k1" +import * as utils from "@noble/curves/abstract/utils"; +import {sha256 as sha} from "@noble/hashes/sha256"; import base64 from "base64-js" import { bech32 } from "bech32" @@ -43,7 +45,7 @@ export function getPublicKey(priv: HexOrBechPrivateKey): PublicKey { * Convert the data to lowercase hex. */ function toHex(data: Uint8Array): Hex { - return secp.utils.bytesToHex(data).toLowerCase() + return utils.bytesToHex(data).toLowerCase() } /** @@ -76,15 +78,15 @@ function parseKey(key: string, bechPrefix: string): Hex { /** * Get the SHA256 hash of the data, in hex format. */ -export async function sha256(data: Uint8Array): Promise { - return toHex(await secp.utils.sha256(data)) +export function sha256(data: Uint8Array): Hex { + return toHex(sha(data)) } /** * Sign the data using elliptic curve cryptography. */ -export async function schnorrSign(data: Hex, priv: PrivateKey): Promise { - return toHex(await secp.schnorr.sign(data, priv)) +export function schnorrSign(data: Hex, priv: PrivateKey): Hex { + return toHex(secp.schnorr.sign(data, priv)) } /** @@ -94,7 +96,7 @@ export function schnorrVerify( sig: Hex, data: Hex, key: PublicKey -): Promise { +): boolean { return secp.schnorr.verify(sig.toString(), data.toString(), key.toString()) } @@ -103,7 +105,7 @@ export async function aesEncryptBase64( recipient: PublicKey, plaintext: string ): Promise { - const sharedPoint = secp.getSharedSecret(sender, "02" + recipient) + const sharedPoint = secp.secp256k1.getSharedSecret(sender, "02" + recipient) const sharedKey = sharedPoint.slice(1, 33) if (typeof window === "object") { const key = await window.crypto.subtle.importKey( @@ -149,7 +151,7 @@ export async function aesDecryptBase64( recipient: PrivateKey, { data, iv }: AesEncryptedBase64 ): Promise { - const sharedPoint = secp.getSharedSecret(recipient, "02" + sender) + const sharedPoint = secp.secp256k1.getSharedSecret(recipient, "02" + sender) const sharedKey = sharedPoint.slice(1, 33) if (typeof window === "object") { const decodedData = base64.toByteArray(data) diff --git a/packages/nostr/src/event/index.ts b/packages/nostr/src/event/index.ts index 8a3d853ff..1cd8c2030 100644 --- a/packages/nostr/src/event/index.ts +++ b/packages/nostr/src/event/index.ts @@ -128,12 +128,12 @@ export async function signEvent( if (priv !== undefined) { priv = parsePrivateKey(priv) event.pubkey = getPublicKey(priv) - const id = await serializeEventId( + const id = serializeEventId( // This conversion is safe because the pubkey field is set above. event as unknown as UnsignedWithPubkey ) event.id = id - event.sig = await schnorrSign(id, priv) + event.sig = schnorrSign(id, priv) return event as T } else { if (typeof window === "undefined" || window.nostr === undefined) { @@ -158,15 +158,15 @@ export async function signEvent( /** * Parse an event from its raw format. */ -export async function parseEvent(event: RawEvent): Promise { - if (event.id !== (await serializeEventId(event))) { +export function parseEvent(event: RawEvent): Event { + if (event.id !== (serializeEventId(event))) { throw new NostrError( `invalid id ${event.id} for event ${JSON.stringify( event - )}, expected ${await serializeEventId(event)}` + )}, expected ${serializeEventId(event)}` ) } - if (!(await schnorrVerify(event.sig, event.id, event.pubkey))) { + if (!(schnorrVerify(event.sig, event.id, event.pubkey))) { throw new NostrError(`invalid signature for event ${JSON.stringify(event)}`) } @@ -221,9 +221,9 @@ export async function parseEvent(event: RawEvent): Promise { } } -async function serializeEventId( +function serializeEventId( event: UnsignedWithPubkey -): Promise { +): EventId { const serialized = JSON.stringify([ 0, event.pubkey, @@ -232,7 +232,7 @@ async function serializeEventId( event.tags, event.content, ]) - return await sha256(Uint8Array.from(charCodes(serialized))) + return sha256(Uint8Array.from(charCodes(serialized))) } function* charCodes(data: string): Iterable { diff --git a/packages/nostr/src/legacy/Links.ts b/packages/nostr/src/legacy/Links.ts index 70071328f..8f3d4a35a 100644 --- a/packages/nostr/src/legacy/Links.ts +++ b/packages/nostr/src/legacy/Links.ts @@ -1,4 +1,4 @@ -import * as secp from "@noble/secp256k1"; +import * as utils from "@noble/curves/abstract/utils"; import { bech32 } from "bech32"; import { HexKey } from "."; @@ -29,7 +29,7 @@ export interface TLVEntry { export function encodeTLV(prefix: NostrPrefix, id: string, relays?: string[], kind?: number, author?: string) { const enc = new TextEncoder(); - const buf = prefix === NostrPrefix.Address ? enc.encode(id) : secp.utils.hexToBytes(id); + const buf = prefix === NostrPrefix.Address ? enc.encode(id) : utils.hexToBytes(id); const tl0 = [0, buf.length, ...buf]; const tl1 = @@ -40,7 +40,7 @@ export function encodeTLV(prefix: NostrPrefix, id: string, relays?: string[], ki }) .flat() ?? []; - const tl2 = author ? [2, 32, ...secp.utils.hexToBytes(author)] : []; + const tl2 = author ? [2, 32, ...utils.hexToBytes(author)] : []; const tl3 = kind ? [3, 4, ...new Uint8Array(new Uint32Array([kind]).buffer).reverse()] : [] return bech32.encode(prefix, bech32.toWords([...tl0, ...tl1, ...tl2, ...tl3]), 1_000); @@ -72,11 +72,11 @@ function decodeTLVEntry(type: TLVEntryType, prefix: string, data: Uint8Array) { if (prefix === NostrPrefix.Address) { return new TextDecoder("ASCII").decode(data); } else { - return secp.utils.bytesToHex(data); + return utils.bytesToHex(data); } } case TLVEntryType.Author: { - return secp.utils.bytesToHex(data); + return utils.bytesToHex(data); } case TLVEntryType.Kind: { return new Uint32Array(new Uint8Array(data.reverse()).buffer)[0]; diff --git a/packages/nostr/src/legacy/Util.ts b/packages/nostr/src/legacy/Util.ts index dd32c24ab..dcc7147cd 100644 --- a/packages/nostr/src/legacy/Util.ts +++ b/packages/nostr/src/legacy/Util.ts @@ -1,4 +1,4 @@ -import * as secp from "@noble/secp256k1"; +import * as utils from "@noble/curves/abstract/utils"; import { bech32 } from "bech32"; export function unwrap(v: T | undefined | null): T { @@ -17,7 +17,7 @@ export function hexToBech32(hrp: string, hex?: string) { } try { - const buf = secp.utils.hexToBytes(hex); + const buf = utils.hexToBytes(hex); return bech32.encode(hrp, bech32.toWords(buf)); } catch (e) { console.warn("Invalid hex", hex, e); diff --git a/yarn.lock b/yarn.lock index 4aa4fbf92..19bc16adf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1741,6 +1741,13 @@ dependencies: eslint-scope "5.1.1" +"@noble/curves@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.0.0.tgz#e40be8c7daf088aaf291887cbc73f43464a92932" + integrity sha512-2upgEu0iLiDVDZkNLeFV2+ht0BAVgQnEmCk6JsOch9Rp8xfkMCbvbAZlA2pBHQc73dbl+vFOXfqkf4uemdn0bw== + dependencies: + "@noble/hashes" "1.3.0" + "@noble/curves@~0.8.3": version "0.8.3" resolved "https://registry.npmjs.org/@noble/curves/-/curves-0.8.3.tgz" @@ -1753,7 +1760,7 @@ resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.0.tgz" integrity sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg== -"@noble/secp256k1@^1.7.0", "@noble/secp256k1@^1.7.1": +"@noble/secp256k1@^1.7.0": version "1.7.1" resolved "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.7.1.tgz" integrity sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==