From 0e32a1f136fde579c2935d9744ce46b9a88d859c Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Tue, 19 May 2020 18:26:52 +0200 Subject: [PATCH] route payload requests and handle signer methods --- package.json | 3 +- src/client.ts | 22 ++++- src/constants/index.ts | 1 + src/constants/rpc.ts | 2 + src/constants/store.ts | 1 + src/controllers/provider.ts | 6 +- src/controllers/signer.ts | 190 +++++++++++++++++++++++++++++++++--- src/helpers/index.ts | 1 + src/helpers/misc.ts | 17 ++++ src/helpers/uuid.ts | 16 +++ src/helpers/validators.ts | 29 ++++++ src/typings/index.ts | 65 +++++++++--- yarn.lock | 80 +++++++++++++-- 13 files changed, 395 insertions(+), 38 deletions(-) create mode 100644 src/constants/store.ts create mode 100644 src/helpers/uuid.ts create mode 100644 src/helpers/validators.ts diff --git a/package.json b/package.json index b24402c..57f89fe 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,7 @@ "trailingComma": "es5" }, "dependencies": { - "basic-provider": "^1.1.0" + "basic-provider": "^1.1.0", + "eccrypto-js": "^5.2.0" } } diff --git a/src/client.ts b/src/client.ts index 9d9af4c..b926ac7 100644 --- a/src/client.ts +++ b/src/client.ts @@ -1,11 +1,19 @@ -import { IWakuProvider, IWakuSigner, IWakuStore } from "./typings"; +import { + IWakuProvider, + IWakuSigner, + IWakuStore, + IWakuClient, + JsonRpcRequest, +} from "./typings"; import { HttpConnection, WakuProvider, WakuSigner, WakuStore, } from "./controllers"; -class Waku { +import { isSignerMethod, isNetworkMethod } from "./helpers/validators"; +import { WAKU_PREFIX } from "./constants"; +class Waku implements IWakuClient { public provider: IWakuProvider; public store: IWakuStore; public signer: IWakuSigner; @@ -18,6 +26,16 @@ class Waku { this.store = store || new WakuStore(); this.signer = new WakuSigner(this.store); } + + public async request(payload: JsonRpcRequest): Promise { + if (isSignerMethod(payload.method)) { + return this.signer.request(payload); + } else if (isNetworkMethod(payload.method)) { + return this.provider.request(payload); + } + const method = payload.method.replace(WAKU_PREFIX + "_", ""); + return this[method](...payload.params); + } } export default Waku; diff --git a/src/constants/index.ts b/src/constants/index.ts index 540936a..708248c 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -1 +1,2 @@ export * from "./rpc"; +export * from "./store"; diff --git a/src/constants/rpc.ts b/src/constants/rpc.ts index e9f33c7..d94de79 100644 --- a/src/constants/rpc.ts +++ b/src/constants/rpc.ts @@ -1,3 +1,5 @@ +export const WAKU_PREFIX = "waku"; + export const NETWORK_METHODS = { waku_info: "waku_info", waku_setMaxMessageSize: "waku_setMaxMessageSize", diff --git a/src/constants/store.ts b/src/constants/store.ts new file mode 100644 index 0000000..f973983 --- /dev/null +++ b/src/constants/store.ts @@ -0,0 +1 @@ +export const STORE_KEYS_ID = "WAKU_KEYS"; diff --git a/src/controllers/provider.ts b/src/controllers/provider.ts index 1e63bad..76939f3 100644 --- a/src/controllers/provider.ts +++ b/src/controllers/provider.ts @@ -1,7 +1,7 @@ import BasicProvider from "basic-provider"; import { RPC_METHODS } from "../constants"; -import { IWakuProvider } from "../typings"; +import { IWakuProvider, JsonRpcRequest } from "../typings"; export class WakuProvider extends BasicProvider implements IWakuProvider { get isWakuProvider(): boolean { @@ -21,4 +21,8 @@ export class WakuProvider extends BasicProvider implements IWakuProvider { throw err; } } + + public async request(payload: JsonRpcRequest): Promise { + return this.send(payload.method, payload.params); + } } diff --git a/src/controllers/signer.ts b/src/controllers/signer.ts index d0a06c2..e0138ec 100644 --- a/src/controllers/signer.ts +++ b/src/controllers/signer.ts @@ -1,18 +1,180 @@ -import { IWakuSigner, IWakuStore } from "../typings"; +import { + generateKeyPair, + bufferToHex, + getPublic, + hexToBuffer, + generatePrivate, +} from "eccrypto-js"; + +import { + IWakuSigner, + IWakuStore, + KeyMap, + KeyPair, + Key, + SymKey, + JsonRpcRequest, +} from "../typings"; +import { STORE_KEYS_ID, WAKU_PREFIX } from "../constants"; +import { uuid, getFirstMatch } from "../helpers"; +import { isKeyPair, isSymKey } from "../helpers/validators"; export class WakuSigner implements IWakuSigner { - constructor(private store: IWakuStore) {} + private keyMap: KeyMap = {}; - public newKeyPair() {} - public addPrivateKey() {} - public deleteKeyPair() {} - public hasKeyPair() {} - public getPublicKey() {} - public getPrivateKey() {} - public newSymKey() {} - public addSymKey() {} - public generateSymKeyFromPassword() {} - public hasSymKey() {} - public getSymKey() {} - public deleteSymKey() {} + constructor(private store: IWakuStore) { + this.loadKeys(); + } + + // -- public ----------------------------------------------- // + + public async newKeyPair(): Promise { + await this.loadKeys(); + const key = this.genKeyPair(); + await this.addKey(key); + return key.id; + } + + public async addPrivateKey(prvKey: string): Promise { + await this.loadKeys(); + let key = this.getMatchingKey("prvKey", prvKey); + if (!key) { + key = this.genKeyPair(prvKey); + } + await this.addKey(key); + return key.id; + } + + public async deleteKeyPair(id: string): Promise { + await this.loadKeys(); + await this.removeKey(id); + return true; + } + + public async hasKeyPair(id: string): Promise { + await this.loadKeys(); + let key = this.getMatchingKey("id", id); + return isKeyPair(key); + } + + public async getPublicKey(id: string): Promise { + await this.loadKeys(); + let key = this.getMatchingKey("id", id); + if (!key) { + throw new Error(`No matching pubKey for id: ${id}`); + } + return (key as KeyPair).pubKey; + } + + public async getPrivateKey(id: string): Promise { + await this.loadKeys(); + let key = this.getMatchingKey("id", id); + if (!key) { + throw new Error(`No matching privKey for id: ${id}`); + } + return (key as KeyPair).prvKey; + } + + public async newSymKey(): Promise { + await this.loadKeys(); + const key = this.genSymKey(); + await this.addKey(key); + return key.id; + } + + public async addSymKey(symKey: string): Promise { + await this.loadKeys(); + let key = this.getMatchingKey("symKey", symKey); + if (!key) { + key = { + id: uuid(), + symKey, + }; + } + await this.addKey(key); + return key.id; + } + + public async generateSymKeyFromPassword(): Promise { + await this.loadKeys(); + // TODO: needs to accept optional "password" argument + const key = this.genSymKey(); + await this.addKey(key); + return key.id; + } + + public async hasSymKey(id: string): Promise { + await this.loadKeys(); + let key = this.getMatchingKey("id", id); + return isSymKey(key); + } + + public async getSymKey(id: string): Promise { + await this.loadKeys(); + let key = this.getMatchingKey("id", id); + if (!key) { + throw new Error(`No matching symKey for id: ${id}`); + } + return (key as SymKey).symKey; + } + + public async deleteSymKey(id: string): Promise { + await this.loadKeys(); + await this.removeKey(id); + return true; + } + + public async request(payload: JsonRpcRequest): Promise { + const method = payload.method.replace(WAKU_PREFIX + "_", ""); + return this[method](...payload.params); + } + + // -- private ----------------------------------------------- // + + private getMatchingKey(param: string, value: string): Key | undefined { + return getFirstMatch(Object.values(this.keyMap), param, value); + } + + private genKeyPair(prvKey?: string): KeyPair { + if (prvKey) { + return { + id: uuid(), + pubKey: bufferToHex(getPublic(hexToBuffer(prvKey)), true), + prvKey, + }; + } else { + const key = generateKeyPair(); + return { + id: uuid(), + pubKey: bufferToHex(key.publicKey, true), + prvKey: bufferToHex(key.privateKey, true), + }; + } + } + + private genSymKey(): SymKey { + const symKey = generatePrivate(); + return { + id: uuid(), + symKey: bufferToHex(symKey, true), + }; + } + + private async loadKeys() { + this.keyMap = await this.store.get(STORE_KEYS_ID); + } + + private async addKey(key: Key) { + this.keyMap[key.id] = key; + await this.persistKeys(); + } + + private async removeKey(id: string) { + delete this.keyMap[id]; + await this.persistKeys(); + } + + private async persistKeys() { + await this.store.set(STORE_KEYS_ID, this.keyMap); + } } diff --git a/src/helpers/index.ts b/src/helpers/index.ts index 2dfccf9..e27cc00 100644 --- a/src/helpers/index.ts +++ b/src/helpers/index.ts @@ -1,3 +1,4 @@ export * from "./json"; export * from "./local"; export * from "./misc"; +export * from "./uuid"; diff --git a/src/helpers/misc.ts b/src/helpers/misc.ts index 56c0892..9b156b3 100644 --- a/src/helpers/misc.ts +++ b/src/helpers/misc.ts @@ -13,3 +13,20 @@ export function getOrError(name: string, target: any): T { } return res; } + +export function getFirstMatch( + array: T[], + key: string, + value: any +): T | undefined { + let result: T | undefined = undefined; + const matches = array.filter( + x => typeof x[key] !== "undefined" && x[key] === value + ); + + if (!!matches && matches.length) { + result = matches[0]; + } + + return result; +} diff --git a/src/helpers/uuid.ts b/src/helpers/uuid.ts new file mode 100644 index 0000000..870a101 --- /dev/null +++ b/src/helpers/uuid.ts @@ -0,0 +1,16 @@ +export function uuid(): string { + const result: string = ((a?: any, b?: any) => { + for ( + b = a = ""; + a++ < 36; + b += + (a * 51) & 52 + ? (a ^ 15 ? 8 ^ (Math.random() * (a ^ 20 ? 16 : 4)) : 4).toString(16) + : "-" + ) { + // empty + } + return b; + })(); + return result; +} diff --git a/src/helpers/validators.ts b/src/helpers/validators.ts new file mode 100644 index 0000000..eef2bd3 --- /dev/null +++ b/src/helpers/validators.ts @@ -0,0 +1,29 @@ +import { KeyPair, SymKey } from "../typings"; +import { + NETWORK_METHODS, + SIGNER_METHODS, + MESSAGING_METHODS, +} from "../constants"; + +export function isKeyPair(value?: any): value is KeyPair { + return typeof value.prvKey !== "undefined"; +} + +export function isSymKey(value?: any): value is SymKey { + return typeof value.symKey !== "undefined"; +} + +export function isNetworkMethod(value?: string): boolean { + if (!value) return false; + return Object.keys(NETWORK_METHODS).includes(value); +} + +export function isSignerMethod(value?: string): boolean { + if (!value) return false; + return Object.keys(SIGNER_METHODS).includes(value); +} + +export function isMessagingMethod(value?: string): boolean { + if (!value) return false; + return Object.keys(MESSAGING_METHODS).includes(value); +} diff --git a/src/typings/index.ts b/src/typings/index.ts index a5d65ae..27c403e 100644 --- a/src/typings/index.ts +++ b/src/typings/index.ts @@ -1,23 +1,28 @@ import BasicProvider from "basic-provider"; -export interface IWakuProvider extends BasicProvider { +// -- interfaces ----------------------------------------------- // + +export interface IWakuController { + request(payload: JsonRpcRequest): Promise; +} +export interface IWakuProvider extends BasicProvider, IWakuController { isWakuProvider: boolean; enable(): Promise; } -export interface IWakuSigner { - newKeyPair(): any; - addPrivateKey(): any; - deleteKeyPair(): any; - hasKeyPair(): any; - getPublicKey(): any; - getPrivateKey(): any; - newSymKey(): any; - addSymKey(): any; - generateSymKeyFromPassword(): any; - hasSymKey(): any; - getSymKey(): any; - deleteSymKey(): any; +export interface IWakuSigner extends IWakuController { + newKeyPair(): Promise; + addPrivateKey(prvKey: string): Promise; + deleteKeyPair(id: string): Promise; + hasKeyPair(id: string): Promise; + getPublicKey(id: string): Promise; + getPrivateKey(id: string): Promise; + newSymKey(): Promise; + addSymKey(symKey: string): Promise; + generateSymKeyFromPassword(): Promise; + hasSymKey(id: string): Promise; + getSymKey(id: string): Promise; + deleteSymKey(id: string): Promise; } export interface IWakuStore { @@ -25,3 +30,35 @@ export interface IWakuStore { get(key: string): Promise; remove(key: string): Promise; } + +export interface IWakuClient extends IWakuController { + provider: IWakuProvider; + store: IWakuStore; + signer: IWakuSigner; +} + +// -- types ----------------------------------------------- // + +export type SymKey = { + id: string; + symKey: string; +}; + +export type KeyPair = { + id: string; + pubKey: string; + prvKey: string; +}; + +export type Key = SymKey | KeyPair; + +export type KeyMap = { + [id: string]: Key; +}; + +export type JsonRpcRequest = { + id: number; + jsonrpc: "2.0"; + method: string; + params: any; +}; diff --git a/yarn.lock b/yarn.lock index 2dee804..7ef10f5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1407,6 +1407,11 @@ acorn@^7.1.0, acorn@^7.1.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.2.0.tgz#17ea7e40d7c8640ff54a694c889c26f31704effe" integrity sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ== +aes-js@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.1.2.tgz#db9aabde85d5caabbfc0d4f2a4446960f627146a" + integrity sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ== + ajv-errors@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" @@ -1832,6 +1837,13 @@ bindings@^1.5.0: dependencies: file-uri-to-path "1.0.0" +bip66@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/bip66/-/bip66-1.1.5.tgz#01fa8748785ca70955d5011217d1b3139969ca22" + integrity sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI= + dependencies: + safe-buffer "^5.0.1" + bluebird@3.5.5: version "3.5.5" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.5.tgz#a8d0afd73251effbbd5fe384a77d73003c17a71f" @@ -1842,7 +1854,7 @@ bluebird@^3.5.5: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.4.0: +bn.js@4.11.8, bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.8, bn.js@^4.4.0: version "4.11.8" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== @@ -1893,7 +1905,7 @@ browser-resolve@^1.11.3: dependencies: resolve "1.1.7" -browserify-aes@^1.0.0, browserify-aes@^1.0.4: +browserify-aes@^1.0.0, browserify-aes@^1.0.4, browserify-aes@^1.0.6: version "1.2.0" resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== @@ -2652,6 +2664,15 @@ domexception@^1.0.1: dependencies: webidl-conversions "^4.0.2" +drbg.js@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/drbg.js/-/drbg.js-1.0.1.tgz#3e36b6c42b37043823cdbc332d58f31e2445480b" + integrity sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs= + dependencies: + browserify-aes "^1.0.6" + create-hash "^1.1.2" + create-hmac "^1.1.4" + duplexify@^3.4.2, duplexify@^3.6.0: version "3.7.1" resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" @@ -2670,6 +2691,18 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" +eccrypto-js@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/eccrypto-js/-/eccrypto-js-5.2.0.tgz#eb3b36e9978d316fedf50be46492bb0d3e240cf5" + integrity sha512-pPb6CMapJ1LIzjLWxMqlrnfaEFap7qkk9wcO/b4AVSdxBQYlpOqvlPpq5SpUI4FdmfdhVD34AjN47fM8fryC4A== + dependencies: + aes-js "3.1.2" + enc-utils "2.1.0" + hash.js "1.1.7" + js-sha3 "0.8.0" + randombytes "2.1.0" + secp256k1 "3.8.0" + electron-to-chromium@^1.3.413: version "1.3.435" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.435.tgz#22a7008e8f5a317a6d2d80802bddacebb19ae025" @@ -2708,6 +2741,15 @@ emojis-list@^3.0.0: resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== +enc-utils@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/enc-utils/-/enc-utils-2.1.0.tgz#f6c28c3d4bb38fb409a93185848cf361f4fde142" + integrity sha512-VD0eunGDyzhojePzkORWDnW88gi6tIeGb5Z6QVHugux6mMAPiXyw94fb/7WdDQEWhKMSoYRyzFFUebCqeH20PA== + dependencies: + bn.js "4.11.8" + is-typedarray "1.0.0" + typedarray-to-buffer "3.1.5" + end-of-stream@^1.0.0, end-of-stream@^1.1.0: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" @@ -3608,7 +3650,7 @@ hash-base@^3.0.0: readable-stream "^3.6.0" safe-buffer "^5.2.0" -hash.js@^1.0.0, hash.js@^1.0.3: +hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3: version "1.1.7" resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== @@ -3991,7 +4033,7 @@ is-symbol@^1.0.2: dependencies: has-symbols "^1.0.1" -is-typedarray@~1.0.0: +is-typedarray@1.0.0, is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= @@ -4465,6 +4507,11 @@ jpjs@^1.2.1: resolved "https://registry.yarnpkg.com/jpjs/-/jpjs-1.2.1.tgz#f343833de8838a5beba1f42d5a219be0114c44b7" integrity sha512-GxJWybWU4NV0RNKi6EIqk6IRPOTqd/h+U7sbtyuD7yUISUzV78LdHnq2xkevJsTlz/EImux4sWj+wfMiwKLkiw== +js-sha3@0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" + integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -5012,7 +5059,7 @@ mute-stream@0.0.8: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== -nan@^2.12.1: +nan@^2.12.1, nan@^2.14.0: version "2.14.1" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== @@ -5783,7 +5830,7 @@ querystring@0.2.0: resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= -randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: +randombytes@2.1.0, randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== @@ -6271,6 +6318,20 @@ schema-utils@^1.0.0: ajv-errors "^1.0.0" ajv-keywords "^3.1.0" +secp256k1@3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-3.8.0.tgz#28f59f4b01dbee9575f56a47034b7d2e3b3b352d" + integrity sha512-k5ke5avRZbtl9Tqx/SA7CbY3NF6Ro+Sj9cZxezFzuBlLDmyqPiL8hJJ+EmzD8Ig4LUDByHJ3/iPOVoRixs/hmw== + dependencies: + bindings "^1.5.0" + bip66 "^1.1.5" + bn.js "^4.11.8" + create-hash "^1.2.0" + drbg.js "^1.0.1" + elliptic "^6.5.2" + nan "^2.14.0" + safe-buffer "^5.1.2" + semver-compare@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" @@ -7067,6 +7128,13 @@ type-fest@^0.8.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== +typedarray-to-buffer@3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"