diff --git a/ethers-ext/.eslintrc.js b/ethers-ext/.eslintrc.js index 593d82b79..cb32e39c9 100644 --- a/ethers-ext/.eslintrc.js +++ b/ethers-ext/.eslintrc.js @@ -38,9 +38,10 @@ module.exports = { "import/order": ["warn", { "alphabetize": { "order": "asc", "caseInsensitive": true }, "pathGroups": [ - { "pattern": "@klaytn/**", "group": "external", "position": "after" }, + { "pattern": "@klaytn/**", "group": "parent", "position": "after" }, ], "newlines-between": "always", + "pathGroupsExcludedImportTypes": ["@klaytn/**"], }], "import/no-unresolved": [ "error", // eslint-plugin-import cannot resolve subpaths https://github.com/firebase/firebase-admin-node/discussions/1359 @@ -94,5 +95,16 @@ module.exports = { "prefer-const": "off", } }, - ] + { // browser examples use browser globals + "files": ["example/browser-html/*"], + "rules": { + "no-undef": "off", + "no-unused-vars": "off", + "no-constant-condition": "off", + } + }, + ], + "ignorePatterns": [ + "example/browser-html/ethers-ext.bundle.js", + ], }; diff --git a/ethers-ext/.gitignore b/ethers-ext/.gitignore index b770fb2b1..9535ae191 100644 --- a/ethers-ext/.gitignore +++ b/ethers-ext/.gitignore @@ -44,3 +44,6 @@ yarn.lock # eslint .eslintcache + +# TypeDoc +docs diff --git a/ethers-ext/README.md b/ethers-ext/README.md index 9f90c34e2..4cc323786 100644 --- a/ethers-ext/README.md +++ b/ethers-ext/README.md @@ -2,172 +2,165 @@ Ethers.js Extension for Klaytn offers: -- Drop-in replacement to `ethers.Wallet` that handles both Ethereum and Klaytn transactions +- Drop-in replacement to `ethers.Wallet` that handles both Ethereum and Klaytn transaction types involving AccountKey and TxTypes. -- Drop-in replacement to `ethers.JsonRpcProvider` that provides Ethereum RPC as well as +- Drop-in replacement to `ethers.JsonRpcProvider` that provides accesses to both Ethereum RPCs and Klaytn-specific RPCs. -- AccountStore to manage Klaytn account keys. +- Drop-in replacement to `ethers.Web3Provider` to work with both MetaMask (`window.ethereum`) and Kaikas (`window.klaytn`) ## Install -``` -npm install --save @klaytn/ethers-ext -``` - -## Usage - -See [example](./example) and [test](./test). - - -## Build - -- Install dependencies +### Node.js +- Install + ```sh + npm install --save @klaytn/ethers-ext ``` - npm install +- ESM or TypeScript + ```ts + import { Wallet, JsonRpcProvider } from "@klaytn/ethers-ext"; + const provider = new JsonRpcProvider("https://public-en-baobab.klaytn.net"); + const wallet = new Wallet("", provider); ``` - -- Build the library - - ``` - npm run build +- CommonJS + ```js + const { Wallet, JsonRpcProvider } = require("@klaytn/ethers-ext"); + const provider = new JsonRpcProvider("https://public-en-baobab.klaytn.net"); + const wallet = new Wallet("", provider); ``` -- Run examples +### Browser - ``` - node example/rpc/rpc.js - ``` +It is not recommended to use CDNs in production, But you can use below for quick prototyping. -## Core classes - -```mermaid -classDiagram - FieldType ..|> FieldTypeBytes - FieldType ..|> FieldTypeSignatureTuples - FieldType ..|> FieldTypeAccountKey - FieldType ..|> etc - class FieldType { - <> - canonicalize(any): any - emptyValue(): any - } - class FieldTypeBytes { - canonicalize(any): string - emptyValue(): string - } - class FieldTypeSignatureTuples { - canonicalize( SignatureLike[]): SignatureTuple[] - emptyValue(): SignatureTuple[] - } - class FieldTypeAccountKey { - canonicalize(TypedAccountKey | string | any): string - emptyValue(): string - } +```html + + ``` -```mermaid -classDiagram - FieldSet <|-- KlaytnTx - KlaytnTx <|-- TxTypeValueTransfer - KlaytnTx <|-- TxTypeFeeDelegatedValueTransfer - KlaytnTx <|-- other TxTypes - FieldSet <|-- AccountKey - AccountKey <|-- AccountKeyLegacy - AccountKey <|-- AccountKeyPublic - AccountKey <|-- other AccountKey - class FieldSet { - type: number - typeName: string - fieldTypes: string -> FieldType - setFields(any) - setFieldsFromArray( string[], any[] ) - getField( string ): any - getFields( string[] ): any[] - toObject(): any - } - class KlaytnTx { - sigRLP(): string - sigFeePayerRLP(): string - senderTxHashRLP(): string - txHashRLP(): string - addSenderSig(sig) - addFeePayerSig(sig) - setFieldsFromRLP(string): void - } - class AccountKey { - toRLP(): string - } -``` +## Usage -```mermaid -classDiagram - FieldSetFactory <|.. KlaytnTxFactory - FieldSetFactory <|.. AccountKeyFactory - class FieldSetFactory { - private registry: [number] -> FieldSet - private requiredFields: string[] - add(typeof T) - has(type?): boolean - lookup(type?): typeof T - fromObject(any): T - } - class KlaytnTxFactory { - fromRLP(string): KlaytnTx - } - class AccountKeyFactory { - } -``` +See [example](./example) and [test](./test). + +## Class extension design -## ethers extension classes +If diagram does not render, view it [here](https://mermaid.live/edit#pako:eNrVV02P0zAQ_SuVTyB1q35vW3FZtMsBqLSiICQIqmbtaTdqYgfbXTWU_nfcJLRx4jRZISHIpfXz84w9M36294QKhmRGaABK3fqwlhB6vGU-DiGqCCi2UD-iVK19ih-_hJ3hy4W_5ii_eiRtd9K2R77lRxy_SIonn5kuC6WPSDcfJXAFVPuCv3hZGCWibQAaL1AUclbRfaiY9GcIAtTnSadtx6Sp4BypLrpco75hTKJSpcmY5c8NDmt0dV1ahgbt09ZKivCOUxlHGtlb1Zy3iDltsvYj90NEi3mz4OaRyOBPPEkksr8SKZPwk8MLvGWAa6DxotrRMvEUR8huQUOxVzyhlKZkayqsIs73Wb2fQ_wbKUS3KlGvQWHZSB5taChLbdlWocORdZO-tCJcOWi00_BhUHacRx1ercA38XK30yg5BGVPxR6HN1_NUcMc1MbGJX7fotIO_we3Ri5xp8s6mWpL5RKrN8iJUqeRJ2IDsTyH9vIea1L7Nq-hfNUOKOqYQxBu1BvEe4jdZdmMWOH9va_0c7i1qmvpamUV1Mnoc8rlgrD-GyVVr8tn6h8LdIlXd3I4FL2gk8UsAgt9bkMMH7brgpQeZ8GBU7TxTQCxjXBzFbEvQUZchBExG9W7SIjA49WV4pbu5uqal-n_eNGldRUPhfKJ8A78DSiX8Kd_rMtv69XPqyv7alnHsm9bttHswEjoDmu2oCSskjVrwGmV-QlY14g8O9_hmrJzUHGDWAHJn_W8ftglP1ZBpgGyrOeopRwn9NJ1gJM2CVGG4DPzDkrqwCPGQogemZm_DFewDczTwOMHQ4WtFkfJJ7MVBArbZBsxo47Z0-mERsC_CGG1yWxPdmTWm_Y6_elg0r3u9Qe98bQ7apOYzMajznDS7Y-G3eFkOBiOpoc2-ZFY6HauB6Nhfzzp9Ue98XV_MmkTZL4Wcp693Y4_h18MVzCG) ```mermaid classDiagram - ethers_Wallet <|-- KlaytnWallet - ethers_Signer <|-- ethers_Wallet - class ethers_Signer { - provider - abstract getAddress() - abstract signMessage() - abstract signTransaction() - sendTransaction() - } - class ethers_Wallet { - address - privateKey - getAddress() - signMessage() - signTransaction() - checkTransaction() - populateTransaction() - sendTransaction() - } - class KlaytnWallet { - signTransaction() - checkTransaction() - populateTransaction() - sendTransaction() - } - - ethers_Provider <|-- ethers_BaseProvider - ethers_BaseProvider <|-- ethers_JsonRpcProvider - ethers_JsonRpcProvider <|-- KlaytnJsonRpcProvider - class ethers_Provider { - abstract sendTransaction() - abstract call() - abstract estimateGas() - } - class ethers_BaseProvider { - sendTransaction() - waitForTransaction() - } - class ethers_JsonRpcProvider { - perform() - send() - prepareRequest() // "eth_sendRawTransaction" - } - class KlaytnJsonRpcProvider { - sendTransaction() - prepareRequest() // "klay_sendRawTransaction" - } + namespace ethers { + class ethers_Signer["ethers.Signer"] { + provider + checkTransaction() + populateTransaction() + sendTransaction() + } + class ethers_Wallet["ethers.Wallet"] { + connect() + getAddress() + signMessage() + signTransaction() + static fromEncryptedJson() + static fromEncryptedJsonSync() + } + class ethers_JsonRpcSigner["ethers.JsonRpcSigner"] { + connect() + connectUnchecked() + getAddress() + signMessage() + signTransaction() + sendUncheckedTransaction() + _legacySignMessage() + _signTypedData() + override sendTransaction() + } + + class ethers_Provider["ethers.Provider"] { + } + class ethers_BaseProvider["ethers.BaseProvider"] { + } + class ethers_JsonRpcProvider["ethers.JsonRpcProvider"] { + getSigner() + send() + } + class ethers_Web3Provider["ethers.Web3Provider"] { + override send() + } + class ethers_ExternalProvider["ethers.ExternalProvider"] { + isMetaMask + request() + } + } + namespace ethers_ext { + class Wallet { + override getAddress() + override checkTransaction() + override populateTransaction() + override signTransaction() + override sendTransaction() + override static fromEncryptedJson() + override static fromEncryptedJsonSync() + signTransactionAsFeePayer() + sendTransactionAsFeePayer() + static fromEncryptedJsonList() + static fromEncryptedJsonListSync() + } + class JsonRpcSigner { + override connectUnchecked() + override getAddress() + override signMessage() + override checkTransaction() + override populateTransaction() + override signTransaction() + override _legacySignMessage() + override _signTypedData() + override sendTransaction() + override sendUncheckedTransaction() + } + + class JsonRpcProvider { + admin + debug + governance + klay + net + personal + txpool + + override getSigner() + override send() + } + class Web3Provider { + admin + debug + governance + klay + net + personal + txpool + + override getSigner() + } + class ExternalProvider { + isKaikas + } + } + + ethers_Signer <|-- ethers_Wallet + ethers_Signer <|-- ethers_JsonRpcSigner + + ethers_Wallet <|-- Wallet + ethers_JsonRpcSigner <|-- JsonRpcSigner + + + ethers_Provider <|-- ethers_BaseProvider + ethers_BaseProvider <|-- ethers_JsonRpcProvider + ethers_JsonRpcProvider <|-- ethers_Web3Provider + + ethers_JsonRpcProvider <|-- JsonRpcProvider + ethers_Web3Provider <|-- Web3Provider + ethers_ExternalProvider <|-- ExternalProvider + ``` diff --git a/ethers-ext/example/README.md b/ethers-ext/example/README.md index 87f5c4c83..9f58ffbcf 100644 --- a/ethers-ext/example/README.md +++ b/ethers-ext/example/README.md @@ -2,6 +2,7 @@ - [accountKey](./accountKey) Klaytn AccountKey types - [accountStore](./accountStore) AccountStore usage +- [browser-html](./browser-html) Browser extension wallets (e.g. Kaikas) interaction in plain HTML - [rpc](./rpc) Klaytn node RPC wrappers - [smartContract](./smartContract) Smart contract usage - [transactions](./transactions) Klaytn transaction types diff --git a/ethers-ext/example/browser-html/README.md b/ethers-ext/example/browser-html/README.md new file mode 100644 index 000000000..2ff6df158 --- /dev/null +++ b/ethers-ext/example/browser-html/README.md @@ -0,0 +1,13 @@ +# Running the browser extension example + +Run a HTTP server to serve the HTML and JS files. Use python3 http.server for example: + +``` +python3 -m http.server 3000 +``` + +Then open `http://localhost:3000` with the browser. + +Note that the browser extension wallets (e.g. MetaMask and Kaikas) does not work in the `file:///` page. +Therefore you cannot run this example by double-clicking the `index.html`. + diff --git a/ethers-ext/example/browser-html/ethers-ext.bundle.js b/ethers-ext/example/browser-html/ethers-ext.bundle.js new file mode 120000 index 000000000..31460ddd2 --- /dev/null +++ b/ethers-ext/example/browser-html/ethers-ext.bundle.js @@ -0,0 +1 @@ +../../dist/ethers-ext.bundle.js \ No newline at end of file diff --git a/ethers-ext/example/browser-html/index.html b/ethers-ext/example/browser-html/index.html new file mode 100644 index 000000000..4a790e693 --- /dev/null +++ b/ethers-ext/example/browser-html/index.html @@ -0,0 +1,54 @@ + + + + + + @klaytn/ethers-ext in browser demo + + + +

+

+
+

+ +

+
+

For MetaMask and Kaikas

+

+

+ + +

+
+

For Kaikas

+

+ + +

+

+ + +

+
+

+

accounts:
+
chainId:
+

+

+

message signature:
+
recovered signer address:
+

+

+

signed tx:
+
txhash:
+

+ + + + + + + + + diff --git a/ethers-ext/example/browser-html/main.js b/ethers-ext/example/browser-html/main.js new file mode 100644 index 000000000..3a1c89301 --- /dev/null +++ b/ethers-ext/example/browser-html/main.js @@ -0,0 +1,214 @@ +var provider = null; +var accounts = null; + +// https://baobab.klaytnscope.com/account/0xa9eF4a5BfB21e92C06da23Ed79294DaB11F5A6df?tabId=contractCode +var contractAddress = "0xa9eF4a5BfB21e92C06da23Ed79294DaB11F5A6df"; +var contractCalldata = "0xd09de08a"; // function increment() + +function isKaikas() { + return provider && provider.provider.isKaikas; +} + +// https://docs.ethers.org/v5/getting-started/#getting-started--connecting +async function connect(injectedProvider) { + if (!injectedProvider) { + alert("Please install wallet"); + return; + } + + // Wrap the window.{ethereum,klaytn} object with Web3Provider. + provider = new ethers_ext.providers.Web3Provider(injectedProvider); + // Uncomment to use the original ethers.js Web3Provider: + // provider = new ethers.providers.Web3Provider(injectedProvider); + + // Detect user network + // https://docs.metamask.io/wallet/how-to/connect/detect-network/ + const chainId = await provider.send("eth_chainId"); + console.log("chainId", chainId); + $("#textChainId").html(chainId); + + injectedProvider.on("networkChanged", (chainId) => { + console.log("chainId changed", chainId); + $("#textChainId").html(chainId); + provider = new ethers_ext.providers.Web3Provider(injectedProvider); + }); + + // Detect user account + // https://docs.metamask.io/wallet/how-to/connect/access-accounts/ + await provider.send("eth_requestAccounts"); + + const accounts = await provider.listAccounts(); // internally eth_accounts + console.log("accounts", accounts); + $("#textAccounts").html(accounts); + + injectedProvider.on("accountsChanged", async (accounts) => { + console.log("accounts changed", accounts); + $("#textAccounts").html(accounts); + }); +} +async function connectMM() { + $("text").html(""); // Clear all text + await connect(window.ethereum); +} +async function connectKK() { + $("text").html(""); // Clear all text + await connect(window.klaytn); +} + +// https://docs.metamask.io/wallet/how-to/add-network/ +// EIP-3085 wallet_addEthereumChain +// EIP-3326 wallet_switchEthereumChain +async function switchNetwork(networkSpec) { + console.log("switching to", networkSpec); + try { + await provider.send("wallet_switchEthereumChain", [{ chainId: networkSpec.chainId }]); + } catch (e) { + await provider.send("wallet_addEthereumChain", [networkSpec]); + } +} +async function switchBaobab() { + await switchNetwork({ + chainId: "0x3e9", + chainName: "Klaytn Baobab", + nativeCurrency: { + name: "KLAY", + symbol: "KLAY", + decimals: 18, + }, + rpcUrls: ["https://public-en-baobab.klaytn.net"], + blockExplorerUrls: ["https://baobab.klaytnscope.com/"], + }); +} + +async function signMsg() { + try { + if (isKaikas()) { + const { hexlify, toUtf8Bytes } = ethers.utils; + const signer = provider.getSigner(); + const message = "Hello dapp"; + const hexMessage = hexlify(toUtf8Bytes(message)); + + const signature = await provider.send("eth_sign", [await signer.getAddress(), hexMessage]); + console.log("signature", signature); + $("#textSignature").html(signature); + + const recoveredAddress = await provider.send("klay_recoverFromMessage", [await signer.getAddress(), hexMessage, signature, "latest"]); + console.log("recoveredAddress", recoveredAddress); + $("#textRecoveredAddress").html(recoveredAddress); + } else { + const signer = provider.getSigner(); + const message = "Hello dapp"; + + const signature = await signer.signMessage(message); + console.log("signature", signature); + $("#textSignature").html(signature); + + const recoveredAddress = ethers.utils.verifyMessage(message, signature); + console.log("recoveredAddress", recoveredAddress); + $("#textRecoveredAddress").html(recoveredAddress); + } + } catch (err) { + console.error(err); + $("#textSignature").html(`Error: ${err.message}`); + } +} + +async function doSendTx(makeTxRequest) { + try { + const signer = provider.getSigner(); + const address = await signer.getAddress(); + const txRequest = await makeTxRequest(address); + + const sentTx = await signer.sendTransaction(txRequest); + console.log("sentTx", sentTx); + const txhash = sentTx.hash; + const explorerUrl = "https://baobab.klaytnscope.com/tx/"; + $("#textTxhash").html(`${txhash}`); + } catch (err) { + console.error(err); + $("#textTxhash").html(`Error: ${err.message}`); + } +} +async function sendLegacyVT() { + doSendTx(async (address) => { + return { + to: address, // send to myself + value: 0, + }; + }); +} +async function sendLegacySC() { + doSendTx(async () => { + return { + to: contractAddress, + data: contractCalldata, + }; + }); +} +async function sendKlaytnVT() { + doSendTx(async (address) => { + return { + type: ethers_ext.TxType.ValueTransfer, // 0x08 + to: address, // send to myself + value: 0, + }; + }); +} +async function sendKlaytnSC() { + doSendTx(async () => { + return { + type: ethers_ext.TxType.SmartContractExecution, // 0x30 + to: contractAddress, + data: contractCalldata, + }; + }); +} + +// This operation is usually done in the backend by the dApp operator. +// We do it here with hardcoded private key for demonstration purpose. +async function doSendTxAsFeePayer(signedTx) { + const httpProvider = new ethers_ext.JsonRpcProvider("https://public-en-baobab.klaytn.net"); + const feePayerPriv = "0xb3cf575dea0081563fe5482de2fe4425e025502b1f4ae7e02b2540ac0a5beda1"; + const feePayerWallet = new ethers_ext.Wallet(feePayerPriv, httpProvider); + + const sentTx = await feePayerWallet.sendTransactionAsFeePayer(signedTx); + console.log("sentTx", sentTx); + const txhash = sentTx.hash; + const explorerUrl = "https://baobab.klaytnscope.com/tx/"; + $("#textTxhash").html(`${txhash}`); +} + +async function doSignTx(makeTxRequest) { + try { + const signer = provider.getSigner(); + const address = await signer.getAddress(); + const txRequest = await makeTxRequest(address); + + const signedTx = await signer.signTransaction(txRequest); + console.log("signedTx", signedTx); + $("#textSignedTx").html(`${signedTx}`); + + await doSendTxAsFeePayer(signedTx); + } catch (err) { + console.error(err); + $("#textTxhash").html(`Error: ${err.message}`); + } +} +async function sendFeeDelegatedVT() { + doSignTx(async (address) => { + return { + type: ethers_ext.TxType.FeeDelegatedValueTransfer, // 0x09 + to: address, // send to myself + value: 0, + }; + }); +} +async function sendFeeDelegatedSC() { + doSignTx(async () => { + return { + type: ethers_ext.TxType.FeeDelegatedSmartContractExecution, // 0x09 + to: contractAddress, + data: contractCalldata, + }; + }); +} \ No newline at end of file diff --git a/ethers-ext/package-lock.json b/ethers-ext/package-lock.json index 78e8a19d8..d40eedbe5 100644 --- a/ethers-ext/package-lock.json +++ b/ethers-ext/package-lock.json @@ -1,21 +1,38 @@ { "name": "@klaytn/ethers-ext", - "version": "0.9.7-beta", + "version": "0.9.8-beta", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@klaytn/ethers-ext", - "version": "0.9.7-beta", + "version": "0.9.8-beta", "license": "MIT", "dependencies": { - "@klaytn/js-ext-core": "^0.9.7-beta", - "@klaytn/web3rpc": "^0.9.7", + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/json-wallets": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.1", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/providers": "^5.7.2", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wallet": "^5.7.0", + "@ethersproject/web": "^5.7.1", + "@klaytn/js-ext-core": "^0.9.8-beta", + "@klaytn/web3rpc": "^0.9.8", "lodash": "^4.17.21" }, "devDependencies": { - "@klaytn/ethers-ext": "^0.9.7-beta", - "@types/chai": "^4.3.4", + "@types/chai": "^4.3.7", "@types/chai-as-promised": "^7.1.5", "@types/lodash": "^4.14.192", "@types/mocha": "^10.0.4", @@ -25,11 +42,13 @@ "eslint": "^8.45.0", "eslint-plugin-import": "^2.27.5", "mocha": "^10.2.0", + "ts-loader": "^9.5.1", "ts-node": "^10.9.1", - "typescript": "^5.0.4" - }, - "peerDependencies": { - "ethers": "^5.7.2" + "typedoc": "^0.25.4", + "typescript": "^5.0.4", + "webpack": "^5.89.0", + "webpack-cli": "^5.1.4", + "webpack-visualizer-plugin2": "^1.1.0" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -55,13 +74,13 @@ } }, "node_modules/@babel/cli": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.22.9.tgz", - "integrity": "sha512-nb2O7AThqRo7/E53EGiuAkMaRbb7J5Qp3RvN+dmua1U+kydm0oznkhqbTEG15yk26G/C3yL6OdZjzgl+DMXVVA==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.23.4.tgz", + "integrity": "sha512-j3luA9xGKCXVyCa5R7lJvOMM+Kc2JEnAEIgz2ggtjQ/j5YUVgfsg/WsG95bbsgq7YLHuiCOzMnoSasuY16qiCw==", "dependencies": { "@jridgewell/trace-mapping": "^0.3.17", "commander": "^4.0.1", - "convert-source-map": "^1.1.0", + "convert-source-map": "^2.0.0", "fs-readdir-recursive": "^1.1.0", "glob": "^7.2.0", "make-dir": "^2.1.0", @@ -82,69 +101,128 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/cli/node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "node_modules/@babel/cli/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "peer": true, + "dependencies": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, "engines": { - "node": ">=6.0.0" + "node": ">=6.9.0" + } + }, + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "peer": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/@babel/cli/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "peer": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } }, - "node_modules/@babel/cli/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.18", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", - "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "peer": true, "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "color-name": "1.1.3" } }, - "node_modules/@babel/code-frame": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", - "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "peer": true + }, + "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "peer": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "peer": true, "dependencies": { - "@babel/highlight": "^7.22.5" + "has-flag": "^3.0.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=4" } }, "node_modules/@babel/compat-data": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz", - "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", "peer": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.9.tgz", - "integrity": "sha512-G2EgeufBcYw27U4hhoIwFcgc1XU7TlXJ3mv04oOv1WCuo900U/anZSPzEqNjwdjgffkk2Gs0AN0dW1CKVLcG7w==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.5.tgz", + "integrity": "sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g==", "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.5", - "@babel/generator": "^7.22.9", - "@babel/helper-compilation-targets": "^7.22.9", - "@babel/helper-module-transforms": "^7.22.9", - "@babel/helpers": "^7.22.6", - "@babel/parser": "^7.22.7", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.8", - "@babel/types": "^7.22.5", - "convert-source-map": "^1.7.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.5", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.5", + "@babel/parser": "^7.23.5", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.5", + "@babel/types": "^7.23.5", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", + "json5": "^2.2.3", "semver": "^6.3.1" }, "engines": { @@ -156,12 +234,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.9.tgz", - "integrity": "sha512-KtLMbmicyuK2Ak/FTCJVbDnkN1SlT8/kceFTiuDiiRUUSMnHMidxSCdG4ndkTOHHpoomWe/4xkvHkEOncwjYIw==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.5.tgz", + "integrity": "sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA==", "peer": true, "dependencies": { - "@babel/types": "^7.22.5", + "@babel/types": "^7.23.5", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -170,67 +248,49 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/generator/node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "peer": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/generator/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "peer": true - }, "node_modules/@babel/generator/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.18", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", - "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", "peer": true, "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.9.tgz", - "integrity": "sha512-7qYrNM6HjpnPHJbopxmb8hSPoZ0gsX8IvUS32JGVoy+pU9e5N0nLr1VjJoR6kA4d9dmGLxNYOjeB8sUDal2WMw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", + "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", "peer": true, "dependencies": { "@babel/compat-data": "^7.22.9", - "@babel/helper-validator-option": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", "browserslist": "^4.21.9", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", - "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "peer": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", - "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "peer": true, "dependencies": { - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" @@ -249,28 +309,28 @@ } }, "node_modules/@babel/helper-module-imports": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", - "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", "peer": true, "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz", - "integrity": "sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", "peer": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", "@babel/helper-simple-access": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.5" + "@babel/helper-validator-identifier": "^7.22.20" }, "engines": { "node": ">=6.9.0" @@ -304,54 +364,54 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", "peer": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "peer": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", - "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", "peer": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.6.tgz", - "integrity": "sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.5.tgz", + "integrity": "sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg==", "peer": true, "dependencies": { - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.6", - "@babel/types": "^7.22.5" + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.5", + "@babel/types": "^7.23.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", - "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "peer": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.22.5", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { @@ -430,9 +490,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.22.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.7.tgz", - "integrity": "sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz", + "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==", "peer": true, "bin": { "parser": "bin/babel-parser.js" @@ -442,33 +502,33 @@ } }, "node_modules/@babel/template": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", - "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "peer": true, "dependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.22.8", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.8.tgz", - "integrity": "sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.5.tgz", + "integrity": "sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w==", "peer": true, "dependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/generator": "^7.22.7", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.7", - "@babel/types": "^7.22.5", + "@babel/parser": "^7.23.5", + "@babel/types": "^7.23.5", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -477,27 +537,19 @@ } }, "node_modules/@babel/types": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz", - "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.5.tgz", + "integrity": "sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w==", "peer": true, "dependencies": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@colors/colors": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", - "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", - "engines": { - "node": ">=0.1.90" - } - }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -510,14 +562,13 @@ "node": ">=12" } }, - "node_modules/@dabh/diagnostics": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", - "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", - "dependencies": { - "colorspace": "1.1.x", - "enabled": "2.0.x", - "kuler": "^2.0.0" + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true, + "engines": { + "node": ">=10.0.0" } }, "node_modules/@eslint-community/eslint-utils": { @@ -613,33 +664,6 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/@ethersproject/abi": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", - "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "peer": true, - "dependencies": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, "node_modules/@ethersproject/abstract-provider": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", @@ -654,7 +678,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/bignumber": "^5.7.0", "@ethersproject/bytes": "^5.7.0", @@ -679,7 +702,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/abstract-provider": "^5.7.0", "@ethersproject/bignumber": "^5.7.0", @@ -724,7 +746,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/bytes": "^5.7.0" } @@ -743,7 +764,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/bytes": "^5.7.0", "@ethersproject/properties": "^5.7.0" @@ -805,34 +825,6 @@ "@ethersproject/bignumber": "^5.7.0" } }, - "node_modules/@ethersproject/contracts": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz", - "integrity": "sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "peer": true, - "dependencies": { - "@ethersproject/abi": "^5.7.0", - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0" - } - }, "node_modules/@ethersproject/hash": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", @@ -847,7 +839,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/abstract-signer": "^5.7.0", "@ethersproject/address": "^5.7.0", @@ -874,7 +865,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/abstract-signer": "^5.7.0", "@ethersproject/basex": "^5.7.0", @@ -904,7 +894,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/abstract-signer": "^5.7.0", "@ethersproject/address": "^5.7.0", @@ -969,7 +958,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/logger": "^5.7.0" } @@ -988,7 +976,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/bytes": "^5.7.0", "@ethersproject/sha2": "^5.7.0" @@ -1026,7 +1013,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/abstract-provider": "^5.7.0", "@ethersproject/abstract-signer": "^5.7.0", @@ -1064,7 +1050,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/bytes": "^5.7.0", "@ethersproject/logger": "^5.7.0" @@ -1103,7 +1088,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/bytes": "^5.7.0", "@ethersproject/logger": "^5.7.0", @@ -1133,30 +1117,6 @@ "hash.js": "1.1.7" } }, - "node_modules/@ethersproject/solidity": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", - "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "peer": true, - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, "node_modules/@ethersproject/strings": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", @@ -1171,7 +1131,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/bytes": "^5.7.0", "@ethersproject/constants": "^5.7.0", @@ -1238,7 +1197,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/abstract-provider": "^5.7.0", "@ethersproject/abstract-signer": "^5.7.0", @@ -1271,7 +1229,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/base64": "^5.7.0", "@ethersproject/bytes": "^5.7.0", @@ -1294,7 +1251,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/bytes": "^5.7.0", "@ethersproject/hash": "^5.7.0", @@ -1362,7 +1318,6 @@ "version": "0.3.3", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "peer": true, "dependencies": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -1384,11 +1339,20 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "peer": true, "engines": { "node": ">=6.0.0" } }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", @@ -1403,40 +1367,10 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, - "node_modules/@klaytn/ethers-ext": { - "version": "0.9.7-beta", - "resolved": "https://registry.npmjs.org/@klaytn/ethers-ext/-/ethers-ext-0.9.7-beta.tgz", - "integrity": "sha512-qZ2cjmw0VX1eNfPeaZbEJz1fLeICeKhKIAUINz3xJqAiMd4jSYrHv4VEoNZ1iz08DJI15vVsHMXWmByTsotzXg==", - "dev": true, - "dependencies": { - "@klaytn/ethers-ext": "^0.9.3-beta", - "@klaytn/web3rpc": "^0.9.0", - "bn.js": "^5.2.1", - "eth-lib": "^0.1.29", - "lodash": "^4.17.21", - "uuid": "^9.0.1" - }, - "peerDependencies": { - "ethers": "^5.7.2" - } - }, - "node_modules/@klaytn/ethers-ext/node_modules/@klaytn/ethers-ext": { - "version": "0.9.3-beta", - "resolved": "https://registry.npmjs.org/@klaytn/ethers-ext/-/ethers-ext-0.9.3-beta.tgz", - "integrity": "sha512-As3iP/KhxG6+EVbnEln4QtF5A/M5HI7uGFzbFXFSQCd4LpQlLovQcI31fjaD9tgCw4DA4agAqHNcnBPBnX6j6A==", - "dev": true, - "dependencies": { - "@klaytn/web3rpc": "^0.9.0", - "lodash": "^4.17.21" - }, - "peerDependencies": { - "ethers": "^5.7.2" - } - }, "node_modules/@klaytn/js-ext-core": { - "version": "0.9.7-beta", - "resolved": "https://registry.npmjs.org/@klaytn/js-ext-core/-/js-ext-core-0.9.7-beta.tgz", - "integrity": "sha512-dgoO8zPuPA3LQRdUic9VW2c1UIjRpnP8BbKxEWjmrjmZ6GF0rYCqIu1onV7qvq0O8dDCKg7/bGDC4rpBnhFlxQ==", + "version": "0.9.8-beta", + "resolved": "https://registry.npmjs.org/@klaytn/js-ext-core/-/js-ext-core-0.9.8-beta.tgz", + "integrity": "sha512-DtkNocCL7faKvbUquiQCV2Bnyp5sa6ye3BP0zHvmDHJfVbNjgbVZiN2xqK6HDt+WBskf9KFKAgJo9LSiSfLVQw==", "dependencies": { "@ethersproject/address": "^5.7.0", "@ethersproject/bignumber": "^5.7.0", @@ -1444,15 +1378,14 @@ "@ethersproject/rlp": "^5.7.0", "@ethersproject/transactions": "^5.7.0", "@ethersproject/units": "^5.7.0", - "build": "^0.1.4", "elliptic": "^6.5.4", "lodash": "^4.17.21" } }, "node_modules/@klaytn/web3rpc": { - "version": "0.9.7", - "resolved": "https://registry.npmjs.org/@klaytn/web3rpc/-/web3rpc-0.9.7.tgz", - "integrity": "sha512-D/ZTjaQY6oF65DNJu8evaOLPoCioCDiy9uqkIPOi1gwLmYNEMqFhy9NbtPPjkXFyKfj1fAHzgByyrWmNd7GyBA==", + "version": "0.9.8", + "resolved": "https://registry.npmjs.org/@klaytn/web3rpc/-/web3rpc-0.9.8.tgz", + "integrity": "sha512-KJXukas+FOmDCHj03AgnoMK0YTtwbHhilZnv8pmmM4f17OoSVwqx4vfAuiRMnaFa+D5i0SGmhUkMhXVDba0Zcg==", "dependencies": { "@babel/cli": "^7.0.0", "superagent": "^5.3.0" @@ -1524,9 +1457,9 @@ "dev": true }, "node_modules/@types/chai": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.4.tgz", - "integrity": "sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw==", + "version": "4.3.11", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.11.tgz", + "integrity": "sha512-qQR1dr2rGIHYlJulmr8Ioq3De0Le9E4MJ5AiaeAETJJpndT1uUNHsGFK3L/UIu+rbkQSdj8J/w2bCsBZc/Y5fQ==", "dev": true }, "node_modules/@types/chai-as-promised": { @@ -1538,6 +1471,32 @@ "@types/chai": "*" } }, + "node_modules/@types/eslint": { + "version": "8.44.8", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.8.tgz", + "integrity": "sha512-4K8GavROwhrYl2QXDXm0Rv9epkA8GBFu0EI+XrrnnuCl7u8CWBRusX7fXJfanhZTDWSAL24gDI/UqXyUM0Injw==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, "node_modules/@types/json-schema": { "version": "7.0.12", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", @@ -1563,11 +1522,10 @@ "dev": true }, "node_modules/@types/node": { - "version": "18.15.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz", - "integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==", - "dev": true, - "peer": true + "version": "18.15.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.13.tgz", + "integrity": "sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==", + "dev": true }, "node_modules/@types/semver": { "version": "7.5.0", @@ -1575,11 +1533,6 @@ "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", "dev": true }, - "node_modules/@types/triple-beam": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", - "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==" - }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.1.0.tgz", @@ -1870,33 +1823,231 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "node_modules/@webassemblyjs/ast": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", + "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", "dev": true, "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" } }, - "node_modules/acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true }, - "node_modules/acorn-jsx": { - "version": "5.3.2", + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", + "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dev": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", + "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dev": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", + "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", + "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", + "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", + "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", + "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webpack-cli/configtest": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", + "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/info": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", + "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/serve": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", + "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-assertions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "dev": true, + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, @@ -1916,8 +2067,7 @@ "node_modules/aes-js": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", - "peer": true + "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==" }, "node_modules/ajv": { "version": "6.12.6", @@ -1935,6 +2085,15 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, "node_modules/ansi-colors": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", @@ -1953,6 +2112,12 @@ "node": ">=8" } }, + "node_modules/ansi-sequence-parser": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz", + "integrity": "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==", + "dev": true + }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -2006,12 +2171,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "dev": true - }, "node_modules/array-includes": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", @@ -2096,24 +2255,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, "node_modules/assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", @@ -2123,17 +2264,6 @@ "node": "*" } }, - "node_modules/async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" - }, - "node_modules/async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "dev": true - }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -2151,40 +2281,15 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", - "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", - "dev": true - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "dev": true, - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, "node_modules/bech32": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", - "peer": true + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" }, "node_modules/binary-extensions": { "version": "2.2.0", @@ -2200,60 +2305,6 @@ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" }, - "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", - "dev": true, - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/body-parser/node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dev": true, - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -2304,7 +2355,6 @@ "url": "https://github.com/sponsors/ai" } ], - "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001503", "electron-to-chromium": "^1.4.431", @@ -2318,41 +2368,12 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/buffer-to-arraybuffer": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", - "integrity": "sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ==", + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, - "node_modules/build": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/build/-/build-0.1.4.tgz", - "integrity": "sha512-KwbDJ/zrsU8KZRRMfoURG14cKIAStUlS8D5jBDvtrZbwO5FEkYqc3oB8HIhRiyD64A48w1lc+sOmQ+mmBw5U/Q==", - "dependencies": { - "cssmin": "0.3.x", - "jsmin": "1.x", - "jxLoader": "*", - "moo-server": "*", - "promised-io": "*", - "timespan": "2.x", - "uglify-js": "1.x", - "walker": "1.x", - "winston": "*", - "wrench": "1.3.x" - }, - "engines": { - "node": ">v0.4.12" - } - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -2403,14 +2424,7 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ], - "peer": true - }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "dev": true + ] }, "node_modules/chai": { "version": "4.3.7", @@ -2506,6 +2520,15 @@ "fsevents": "~2.3.2" } }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, "node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -2517,13 +2540,18 @@ "wrap-ansi": "^7.0.0" } }, - "node_modules/color": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", - "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, "dependencies": { - "color-convert": "^1.9.3", - "color-string": "^1.6.0" + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, "node_modules/color-convert": { @@ -2541,38 +2569,14 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/color-string": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", - "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", - "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "node_modules/color/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, - "node_modules/colorspace": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", - "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", - "dependencies": { - "color": "^3.1.3", - "text-hex": "1.0.x" - } + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true }, "node_modules/combined-stream": { "version": "1.0.8", @@ -2594,80 +2598,28 @@ } }, "node_modules/component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", + "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dev": true, - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" - }, - "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" }, "node_modules/cookiejar": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==" }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dev": true, - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -2688,25 +2640,11 @@ "node": ">= 8" } }, - "node_modules/cssmin": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/cssmin/-/cssmin-0.3.2.tgz", - "integrity": "sha512-bynxGIAJ8ybrnFobjsQotIjA8HFDDgPwbeUWNXXXfR+B4f9kkxdcUyagJoQCSUOfMV+ZZ6bMn8bvbozlCzUGwQ==", - "bin": { - "cssmin": "bin/cssmin" - } - }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } + "node_modules/d3": { + "version": "3.5.17", + "resolved": "https://registry.npmjs.org/d3/-/d3-3.5.17.tgz", + "integrity": "sha512-yFk/2idb8OHPKkbAL8QaOaqENNoMhIaSHZerk3oQsECwkObkCpJyjYwCe+OHiq6UEdhe1m8ZGARRRO3ljFjlKg==", + "dev": true }, "node_modules/debug": { "version": "4.3.4", @@ -2741,31 +2679,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", - "dev": true, - "dependencies": { - "mimic-response": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/deep-eql": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", - "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", + "node_modules/deep-eql": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", "dev": true, "dependencies": { "type-detect": "^4.0.0" @@ -2804,25 +2721,6 @@ "node": ">=0.4.0" } }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "dev": true, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, "node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -2856,33 +2754,10 @@ "node": ">=6.0.0" } }, - "node_modules/dom-walk": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", - "dev": true - }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "dev": true, - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "dev": true - }, "node_modules/electron-to-chromium": { "version": "1.4.468", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.468.tgz", - "integrity": "sha512-6M1qyhaJOt7rQtNti1lBA0GwclPH+oKCmsra/hkcWs5INLxfXXD/dtdnaKUYQu/pjOBP/8Osoe4mAcNvvzoFag==", - "peer": true + "integrity": "sha512-6M1qyhaJOt7rQtNti1lBA0GwclPH+oKCmsra/hkcWs5INLxfXXD/dtdnaKUYQu/pjOBP/8Osoe4mAcNvvzoFag==" }, "node_modules/elliptic": { "version": "6.5.4", @@ -2909,18 +2784,29 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "node_modules/enabled": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", - "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" + "node_modules/enhanced-resolve": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "node_modules/envinfo": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.0.tgz", + "integrity": "sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg==", "dev": true, + "bin": { + "envinfo": "dist/cli.js" + }, "engines": { - "node": ">= 0.8" + "node": ">=4" } }, "node_modules/es-abstract": { @@ -2976,6 +2862,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es-module-lexer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", + "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==", + "dev": true + }, "node_modules/es-set-tostringtag": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", @@ -3024,12 +2916,6 @@ "node": ">=6" } }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true - }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -3350,226 +3236,15 @@ "node": ">=0.10.0" } }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eth-lib": { - "version": "0.1.29", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz", - "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "nano-json-stream-parser": "^0.1.2", - "servify": "^0.1.12", - "ws": "^3.0.0", - "xhr-request-promise": "^0.1.2" - } - }, - "node_modules/eth-lib/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/eth-lib/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/eth-lib/node_modules/ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", - "dev": true, - "dependencies": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } - }, - "node_modules/ethers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", - "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "peer": true, - "dependencies": { - "@ethersproject/abi": "5.7.0", - "@ethersproject/abstract-provider": "5.7.0", - "@ethersproject/abstract-signer": "5.7.0", - "@ethersproject/address": "5.7.0", - "@ethersproject/base64": "5.7.0", - "@ethersproject/basex": "5.7.0", - "@ethersproject/bignumber": "5.7.0", - "@ethersproject/bytes": "5.7.0", - "@ethersproject/constants": "5.7.0", - "@ethersproject/contracts": "5.7.0", - "@ethersproject/hash": "5.7.0", - "@ethersproject/hdnode": "5.7.0", - "@ethersproject/json-wallets": "5.7.0", - "@ethersproject/keccak256": "5.7.0", - "@ethersproject/logger": "5.7.0", - "@ethersproject/networks": "5.7.1", - "@ethersproject/pbkdf2": "5.7.0", - "@ethersproject/properties": "5.7.0", - "@ethersproject/providers": "5.7.2", - "@ethersproject/random": "5.7.0", - "@ethersproject/rlp": "5.7.0", - "@ethersproject/sha2": "5.7.0", - "@ethersproject/signing-key": "5.7.0", - "@ethersproject/solidity": "5.7.0", - "@ethersproject/strings": "5.7.0", - "@ethersproject/transactions": "5.7.0", - "@ethersproject/units": "5.7.0", - "@ethersproject/wallet": "5.7.0", - "@ethersproject/web": "5.7.1", - "@ethersproject/wordlists": "5.7.0" - } - }, - "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", - "dev": true, - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express/node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "dev": true, - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/express/node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dev": true, - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/express/node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "dev": true, - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, "engines": { - "node": ">= 0.8" + "node": ">=0.8.x" } }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "dev": true, - "engines": [ - "node >=0.6.0" - ] - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -3609,6 +3284,15 @@ "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "engines": { + "node": ">= 4.9.1" + } + }, "node_modules/fastq": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", @@ -3618,11 +3302,6 @@ "reusify": "^1.0.4" } }, - "node_modules/fecha": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", - "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" - }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -3647,39 +3326,6 @@ "node": ">=8" } }, - "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "dev": true, - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -3724,11 +3370,6 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, - "node_modules/fn.name": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", - "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" - }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -3738,15 +3379,6 @@ "is-callable": "^1.1.3" } }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/form-data": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", @@ -3769,24 +3401,6 @@ "url": "https://ko-fi.com/tunnckoCore/commissions" } }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/fs-readdir-recursive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", @@ -3862,9 +3476,9 @@ } }, "node_modules/get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true, "engines": { "node": "*" @@ -3900,15 +3514,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0" - } - }, "node_modules/glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", @@ -3940,6 +3545,12 @@ "node": ">= 6" } }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, "node_modules/glob/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -3960,16 +3571,6 @@ "node": "*" } }, - "node_modules/global": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "dev": true, - "dependencies": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, "node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -4035,35 +3636,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", - "dev": true, - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -4170,49 +3754,6 @@ "minimalistic-crypto-utils": "^1.0.1" } }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dev": true, - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -4238,6 +3779,25 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -4275,13 +3835,13 @@ "node": ">= 0.4" } }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", "dev": true, "engines": { - "node": ">= 0.10" + "node": ">=10.13.0" } }, "node_modules/is-array-buffer": { @@ -4298,11 +3858,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - }, "node_modules/is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -4400,12 +3955,6 @@ "node": ">=8" } }, - "node_modules/is-function": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", - "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==", - "dev": true - }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -4472,6 +4021,18 @@ "node": ">=8" } }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -4500,17 +4061,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-string": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", @@ -4556,12 +4106,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true - }, "node_modules/is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", @@ -4598,11 +4142,28 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "dev": true + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } }, "node_modules/js-sha3": { "version": "0.8.0", @@ -4612,8 +4173,7 @@ "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "peer": true + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "node_modules/js-yaml": { "version": "4.1.0", @@ -4627,12 +4187,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true - }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -4645,21 +4199,10 @@ "node": ">=4" } }, - "node_modules/jsmin": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/jsmin/-/jsmin-1.0.1.tgz", - "integrity": "sha512-OPuL5X/bFKgVdMvEIX3hnpx3jbVpFCrEM8pKPXjFkZUqg521r41ijdyTz7vACOhW6o1neVlcLyd+wkbK5fNHRg==", - "bin": { - "jsmin": "bin/jsmin" - }, - "engines": { - "node": ">=0.1.93" - } - }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, "node_modules/json-schema-traverse": { @@ -4674,12 +4217,6 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true - }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -4692,48 +4229,21 @@ "node": ">=6" } }, - "node_modules/jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "dev": true, - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/jxLoader": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jxLoader/-/jxLoader-0.1.1.tgz", - "integrity": "sha512-ClEvAj3K68y8uKhub3RgTmcRPo5DfIWvtxqrKQdDPyZ1UVHIIKvVvjrAsJFSVL5wjv0rt5iH9SMCZ0XRKNzeUA==", - "dependencies": { - "js-yaml": "0.3.x", - "moo-server": "1.3.x", - "promised-io": "*", - "walker": "1.x" - }, - "engines": { - "node": ">v0.4.10" - } + "node_modules/jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true }, - "node_modules/jxLoader/node_modules/js-yaml": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-0.3.7.tgz", - "integrity": "sha512-/7PsVDNP2tVe2Z1cF9kTEkjamIwz4aooDpRKmN1+g/9eePCgcxsv4QDvEbxO0EH+gdDD7MLyDoR6BASo3hH51g==", + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, "engines": { - "node": "> 0.4.11" + "node": ">=0.10.0" } }, - "node_modules/kuler": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", - "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" - }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -4747,6 +4257,15 @@ "node": ">= 0.8.0" } }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "engines": { + "node": ">=6.11.5" + } + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -4789,20 +4308,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/logform": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.6.0.tgz", - "integrity": "sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ==", + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, "dependencies": { - "@colors/colors": "1.6.0", - "@types/triple-beam": "^1.3.2", - "fecha": "^4.2.0", - "ms": "^2.1.1", - "safe-stable-stringify": "^2.3.1", - "triple-beam": "^1.3.0" + "js-tokens": "^3.0.0 || ^4.0.0" }, - "engines": { - "node": ">= 12.0.0" + "bin": { + "loose-envify": "cli.js" } }, "node_modules/loupe": { @@ -4823,6 +4338,12 @@ "yallist": "^3.0.2" } }, + "node_modules/lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", + "dev": true + }, "node_modules/make-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", @@ -4849,27 +4370,22 @@ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dependencies": { - "tmpl": "1.0.5" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "node_modules/marked": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", + "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", "dev": true, + "bin": { + "marked": "bin/marked.js" + }, "engines": { - "node": ">= 0.6" + "node": ">= 12" } }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, "node_modules/merge2": { @@ -4932,24 +4448,6 @@ "node": ">= 0.6" } }, - "node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==", - "dev": true, - "dependencies": { - "dom-walk": "^0.1.0" - } - }, "node_modules/minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -4981,6 +4479,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, "node_modules/mocha": { "version": "10.2.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", @@ -5030,23 +4540,10 @@ "node": ">=0.3.1" } }, - "node_modules/moo-server": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/moo-server/-/moo-server-1.3.0.tgz", - "integrity": "sha512-9A8/eor2DXwpv1+a4pZAAydqLFVrWoKoO1fzdzqLUhYVXAO1Kgd1FR2gFZi7YdHzF0s4W8cDNwCfKJQrvLqxDw==", - "engines": { - "node": ">v0.4.10" - } - }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/nano-json-stream-parser": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz", - "integrity": "sha512-9MqxMH/BSJC7dnLsEMPyfN5Dvoo49IsPFYMcHw3Bcfc2kN0lpHRBSzlMSVx4HGyJ7s9B31CyBTVehWJoQ8Ctew==", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "node_modules/nanoid": { @@ -5073,20 +4570,16 @@ "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", "dev": true }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true }, "node_modules/node-releases": { "version": "2.0.13", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", - "peer": true + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==" }, "node_modules/normalize-path": { "version": "3.0.0", @@ -5097,15 +4590,6 @@ "node": ">=0.10.0" } }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -5167,18 +4651,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -5187,14 +4659,6 @@ "wrappy": "1" } }, - "node_modules/one-time": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", - "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", - "dependencies": { - "fn.name": "1.x.x" - } - }, "node_modules/optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -5242,6 +4706,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -5254,21 +4727,6 @@ "node": ">=6" } }, - "node_modules/parse-headers": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.5.tgz", - "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==", - "dev": true - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -5301,12 +4759,6 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", - "dev": true - }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -5325,17 +4777,10 @@ "node": "*" } }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "dev": true - }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "peer": true + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" }, "node_modules/picomatch": { "version": "2.3.1", @@ -5357,47 +4802,89 @@ "node": ">=6" } }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, "engines": { - "node": ">= 0.8.0" + "node": ">=8" } }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, "engines": { - "node": ">= 0.6.0" + "node": ">=8" } }, - "node_modules/promised-io": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/promised-io/-/promised-io-0.3.6.tgz", - "integrity": "sha512-bNwZusuNIW4m0SPR8jooSyndD35ggirHlxVl/UhIaZD/F0OBv9ebfc6tNmbpZts3QXHggkjIBH8lvtnzhtcz0A==" + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" + "p-limit": "^2.2.0" }, "engines": { - "node": ">= 0.10" + "node": ">=8" } }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } }, "node_modules/punycode": { "version": "2.3.0", @@ -5422,20 +4909,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/query-string": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", - "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", - "dev": true, - "dependencies": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -5465,30 +4938,39 @@ "safe-buffer": "^5.1.0" } }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "node_modules/react": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", + "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", "dev": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + }, "engines": { - "node": ">= 0.6" + "node": ">=0.10.0" } }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "node_modules/react-dom": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", + "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", "dev": true, "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "scheduler": "^0.20.2" }, - "engines": { - "node": ">= 0.8" + "peerDependencies": { + "react": "17.0.2" } }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -5514,6 +4996,18 @@ "node": ">=8.10.0" } }, + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, "node_modules/regexp.prototype.flags": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", @@ -5531,71 +5025,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "dev": true, - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/request/node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/request/node_modules/qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/request/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "bin": { - "uuid": "bin/uuid" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -5622,6 +5051,27 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -5730,25 +5180,38 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/safe-stable-stringify": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", - "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", - "engines": { - "node": ">=10" + "node_modules/scheduler": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "dev": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" } }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } }, "node_modules/scrypt-js": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", - "peer": true + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" }, "node_modules/semver": { "version": "6.3.1", @@ -5758,104 +5221,28 @@ "semver": "bin/semver.js" } }, - "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "node_modules/serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", "dev": true, "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" + "randombytes": "^2.1.0" } }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", "dev": true, "dependencies": { - "ms": "2.0.0" + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" } }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/send/node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "dev": true, - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/servify": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz", - "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==", - "dev": true, - "dependencies": { - "body-parser": "^1.16.0", - "cors": "^2.8.1", - "express": "^4.14.0", - "request": "^2.79.0", - "xhr": "^2.3.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true - }, - "node_modules/shebang-command": { + "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", @@ -5876,6 +5263,18 @@ "node": ">=8" } }, + "node_modules/shiki": { + "version": "0.14.6", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.6.tgz", + "integrity": "sha512-R4koBBlQP33cC8cpzX0hAoOURBHJILp4Aaduh2eYi+Vj8ZBqtK/5SWNEHBS3qwUMu8dqOtI/ftno3ESfNeVW9g==", + "dev": true, + "dependencies": { + "ansi-sequence-parser": "^1.1.0", + "jsonc-parser": "^3.2.0", + "vscode-oniguruma": "^1.7.0", + "vscode-textmate": "^8.0.0" + } + }, "node_modules/side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", @@ -5889,45 +5288,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/simple-get": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.2.tgz", - "integrity": "sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw==", - "dev": true, - "dependencies": { - "decompress-response": "^3.3.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "node_modules/simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", - "dependencies": { - "is-arrayish": "^0.3.1" - } - }, "node_modules/slash": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", @@ -5936,52 +5296,29 @@ "node": ">=6" } }, - "node_modules/sshpk": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", - "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", "dev": true, - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", - "engines": { - "node": "*" + "node": ">= 8" } }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, - "engines": { - "node": ">= 0.8" + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } }, - "node_modules/strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==", + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "engines": { "node": ">=0.10.0" @@ -6166,38 +5503,97 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/text-hex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", - "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } }, - "node_modules/timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==", + "node_modules/terser": { + "version": "5.24.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.24.0.tgz", + "integrity": "sha512-ZpGR4Hy3+wBEzVEnHvstMvqpD/nABNelQn/z2r0fjVWGQsN3bpOLzQlqDxmb4CDZnXq5lpjnQ+mHQLAOpfM5iw==", "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, - "node_modules/timespan": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/timespan/-/timespan-2.3.0.tgz", - "integrity": "sha512-0Jq9+58T2wbOyLth0EU+AUb6JMGCLaTWIykJFa7hyAybjVH9gpVMTfUAwo5fWAvtFt2Tjh/Elg8JtgNpnMnM8g==", + "node_modules/terser-webpack-plugin": { + "version": "5.3.9", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", + "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.17", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.16.8" + }, "engines": { - "node": ">= 0.2.0" + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } } }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==" + "node_modules/terser-webpack-plugin/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/terser-webpack-plugin/node_modules/serialize-javascript": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", + "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true }, "node_modules/to-fast-properties": { "version": "2.0.0", @@ -6220,48 +5616,71 @@ "node": ">=8.0" } }, - "node_modules/toidentifier": { + "node_modules/ts-api-utils": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.1.tgz", + "integrity": "sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==", "dev": true, "engines": { - "node": ">=0.6" + "node": ">=16.13.0" + }, + "peerDependencies": { + "typescript": ">=4.2.0" } }, - "node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "node_modules/ts-loader": { + "version": "9.5.1", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz", + "integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==", "dev": true, "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4", + "source-map": "^0.7.4" }, "engines": { - "node": ">=0.8" + "node": ">=12.0.0" + }, + "peerDependencies": { + "typescript": "*", + "webpack": "^5.0.0" } }, - "node_modules/triple-beam": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", - "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==", + "node_modules/ts-loader/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, "engines": { - "node": ">= 14.0.0" + "node": ">=10" } }, - "node_modules/ts-api-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.1.tgz", - "integrity": "sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==", + "node_modules/ts-loader/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, - "engines": { - "node": ">=16.13.0" + "dependencies": { + "lru-cache": "^6.0.0" }, - "peerDependencies": { - "typescript": ">=4.2.0" + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, + "node_modules/ts-loader/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/ts-node": { "version": "10.9.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", @@ -6329,24 +5748,6 @@ "json5": "lib/cli.js" } }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -6380,19 +5781,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/typed-array-buffer": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", @@ -6458,6 +5846,42 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/typedoc": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.25.4.tgz", + "integrity": "sha512-Du9ImmpBCw54bX275yJrxPVnjdIyJO/84co0/L9mwe0R3G4FSR6rQ09AlXVRvZEGMUg09+z/usc8mgygQ1aidA==", + "dev": true, + "dependencies": { + "lunr": "^2.3.9", + "marked": "^4.3.0", + "minimatch": "^9.0.3", + "shiki": "^0.14.1" + }, + "bin": { + "typedoc": "bin/typedoc" + }, + "engines": { + "node": ">= 16" + }, + "peerDependencies": { + "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x" + } + }, + "node_modules/typedoc/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/typescript": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", @@ -6471,20 +5895,6 @@ "node": ">=12.20" } }, - "node_modules/uglify-js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-1.3.5.tgz", - "integrity": "sha512-YPX1DjKtom8l9XslmPFQnqWzTBkvI4N0pbkzLuPZZ4QTyig0uQqvZz9NgUdfEV+qccJzi7fVcGWdESvRIjWptQ==", - "bin": { - "uglifyjs": "bin/uglifyjs" - } - }, - "node_modules/ultron": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", - "dev": true - }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -6500,15 +5910,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/update-browserslist-db": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", @@ -6527,7 +5928,6 @@ "url": "https://github.com/sponsors/ai" } ], - "peer": true, "dependencies": { "escalade": "^3.1.1", "picocolors": "^1.0.0" @@ -6548,74 +5948,202 @@ "punycode": "^2.1.0" } }, - "node_modules/url-set-query": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", - "integrity": "sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg==", - "dev": true - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "node_modules/vscode-oniguruma": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", + "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==", + "dev": true + }, + "node_modules/vscode-textmate": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", + "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==", + "dev": true + }, + "node_modules/watchpack": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", + "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", "dev": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, "engines": { - "node": ">= 0.4.0" + "node": ">=10.13.0" + } + }, + "node_modules/webpack": { + "version": "5.89.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.89.0.tgz", + "integrity": "sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.0", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.9.0", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.15.0", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.7", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } } }, - "node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "node_modules/webpack-cli": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", + "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", "dev": true, - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], + "dependencies": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^2.1.1", + "@webpack-cli/info": "^2.0.2", + "@webpack-cli/serve": "^2.0.5", + "colorette": "^2.0.14", + "commander": "^10.0.1", + "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^5.7.3" + }, "bin": { - "uuid": "dist/bin/uuid" + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "5.x.x" + }, + "peerDependenciesMeta": { + "@webpack-cli/generators": { + "optional": true + }, + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + } } }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true + "node_modules/webpack-cli/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "engines": { + "node": ">=14" + } }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "node_modules/webpack-merge": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", "dev": true, + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" + }, "engines": { - "node": ">= 0.8" + "node": ">=10.0.0" } }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack-visualizer-plugin2": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/webpack-visualizer-plugin2/-/webpack-visualizer-plugin2-1.1.0.tgz", + "integrity": "sha512-pB2Z9a12m+LwjrfptyR4ReEPc0llOjsb2lXVLEJ4yOnRCBtLeWW+TZrZihUZhJDSW9tc60UXnj9/orgyagLOkg==", "dev": true, - "engines": [ - "node >=0.6.0" - ], "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" + "d3": "^3.5.6", + "mkdirp": "^0.5.1", + "prop-types": "^15.7.2", + "react": "^17.0.1", + "react-dom": "^17.0.1" + }, + "engines": { + "npm": ">=5.0.0" } }, - "node_modules/walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "node_modules/webpack/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, "dependencies": { - "makeerror": "1.0.12" + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/webpack/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" } }, "node_modules/which": { @@ -6668,39 +6196,11 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/winston": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.11.0.tgz", - "integrity": "sha512-L3yR6/MzZAOl0DsysUXHVjOwv8mKZ71TrA/41EIduGpOOV5LQVodqN+QdQ6BS6PJ/RdIshZhq84P/fStEZkk7g==", - "dependencies": { - "@colors/colors": "^1.6.0", - "@dabh/diagnostics": "^2.0.2", - "async": "^3.2.3", - "is-stream": "^2.0.0", - "logform": "^2.4.0", - "one-time": "^1.0.0", - "readable-stream": "^3.4.0", - "safe-stable-stringify": "^2.3.1", - "stack-trace": "0.0.x", - "triple-beam": "^1.3.0", - "winston-transport": "^4.5.0" - }, - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/winston-transport": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.6.0.tgz", - "integrity": "sha512-wbBA9PbPAHxKiygo7ub7BYRiKxms0tpfU2ljtWzb3SjRjv5yl6Ozuy/TkXf00HTAt+Uylo3gSkNwzc4ME0wiIg==", - "dependencies": { - "logform": "^2.3.2", - "readable-stream": "^3.6.0", - "triple-beam": "^1.3.0" - }, - "engines": { - "node": ">= 12.0.0" - } + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true }, "node_modules/workerpool": { "version": "6.2.1", @@ -6730,20 +6230,10 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, - "node_modules/wrench": { - "version": "1.3.9", - "resolved": "https://registry.npmjs.org/wrench/-/wrench-1.3.9.tgz", - "integrity": "sha512-srTJQmLTP5YtW+F5zDuqjMEZqLLr/eJOZfDI5ibfPfRMeDh3oBUefAscuH0q5wBKE339ptH/S/0D18ZkfOfmKQ==", - "deprecated": "wrench.js is deprecated! You should check out fs-extra (https://github.com/jprichardson/node-fs-extra) for any operations you were using wrench for. Thanks for all the usage over the years.", - "engines": { - "node": ">=0.1.97" - } - }, "node_modules/ws": { "version": "7.4.6", "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", - "peer": true, "engines": { "node": ">=8.3.0" }, @@ -6760,51 +6250,6 @@ } } }, - "node_modules/xhr": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", - "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", - "dev": true, - "dependencies": { - "global": "~4.4.0", - "is-function": "^1.0.1", - "parse-headers": "^2.0.0", - "xtend": "^4.0.0" - } - }, - "node_modules/xhr-request": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", - "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", - "dev": true, - "dependencies": { - "buffer-to-arraybuffer": "^0.0.5", - "object-assign": "^4.1.1", - "query-string": "^5.0.1", - "simple-get": "^2.7.0", - "timed-out": "^4.0.1", - "url-set-query": "^1.0.0", - "xhr": "^2.0.4" - } - }, - "node_modules/xhr-request-promise": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz", - "integrity": "sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==", - "dev": true, - "dependencies": { - "xhr-request": "^1.1.0" - } - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "engines": { - "node": ">=0.4" - } - }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/ethers-ext/package.json b/ethers-ext/package.json index ac755a3b4..ea2c69ad7 100644 --- a/ethers-ext/package.json +++ b/ethers-ext/package.json @@ -1,6 +1,21 @@ { "name": "@klaytn/ethers-ext", "version": "0.9.8-beta", + "license": "MIT", + "description": "ethers.js extension for Klaytn blockchain", + "keywords": [ + "ethereum", + "ethers", + "ethersjs", + "klaytn", + "klaytn sdk", + "klaytn api" + ], + "homepage": "https://github.com/klaytn/web3klaytn/tree/dev/ethers-ext", + "repository": { + "type": "git", + "url": "https://github.com/klaytn/web3klaytn" + }, "main": "dist/index.js", "types": "dist/index.d.ts", "files": [ @@ -8,7 +23,9 @@ "./src" ], "scripts": { - "build": "tsc", + "build": "npm run build:esm && npm run build:bundle", + "build:esm": "tsc", + "build:bundle": "webpack --mode production", "watch": "tsc -w", "lint": "npm run lint:check", "lint:check": "eslint example src test --cache --quiet", @@ -16,13 +33,8 @@ "test": "mocha --timeout 10000 -r ts-node/register \"test/**/*.ts\"", "prepublishOnly": "npm run build" }, - "license": "MIT", - "peerDependencies": { - "ethers": "^5.7.2" - }, "devDependencies": { - "@klaytn/ethers-ext": "^0.9.7-beta", - "@types/chai": "^4.3.4", + "@types/chai": "^4.3.7", "@types/chai-as-promised": "^7.1.5", "@types/lodash": "^4.14.192", "@types/mocha": "^10.0.4", @@ -32,12 +44,35 @@ "eslint": "^8.45.0", "eslint-plugin-import": "^2.27.5", "mocha": "^10.2.0", + "ts-loader": "^9.5.1", "ts-node": "^10.9.1", - "typescript": "^5.0.4" + "typedoc": "^0.25.4", + "typescript": "^5.0.4", + "webpack": "^5.89.0", + "webpack-cli": "^5.1.4", + "webpack-visualizer-plugin2": "^1.1.0" }, "dependencies": { - "@klaytn/js-ext-core": "^0.9.7-beta", - "@klaytn/web3rpc": "^0.9.7", + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/json-wallets": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.1", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/providers": "^5.7.2", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wallet": "^5.7.0", + "@ethersproject/web": "^5.7.1", + "@klaytn/js-ext-core": "^0.9.8-beta", + "@klaytn/web3rpc": "^0.9.8", "lodash": "^4.17.21" } } diff --git a/ethers-ext/src/accountStore.ts b/ethers-ext/src/accountStore.ts index 86798903f..3e076e384 100644 --- a/ethers-ext/src/accountStore.ts +++ b/ethers-ext/src/accountStore.ts @@ -1,9 +1,10 @@ +import { getAddress } from "@ethersproject/address"; import { BigNumber } from "@ethersproject/bignumber"; import { JsonRpcProvider } from "@ethersproject/providers"; -import { SigningKey } from "@ethersproject/signing-key"; +import { SigningKey, computePublicKey } from "@ethersproject/signing-key"; import { computeAddress } from "@ethersproject/transactions"; + import { HexStr } from "@klaytn/js-ext-core"; -import { computePublicKey, getAddress } from "ethers/lib/utils"; import { Wallet } from "./signer"; diff --git a/ethers-ext/src/index.ts b/ethers-ext/src/index.ts index e0912204c..3c96b3458 100644 --- a/ethers-ext/src/index.ts +++ b/ethers-ext/src/index.ts @@ -1,3 +1,4 @@ +// Pass-through js-ext-core exports export * from "@klaytn/js-ext-core/util"; export { AccountKey, @@ -7,7 +8,16 @@ export { parseTransaction, } from "@klaytn/js-ext-core"; +// ethers-ext classes and functions export * from "./accountStore"; export * from "./keystore"; -export * from "./provider"; export * from "./signer"; + +// Follow ethers v6 convention like `ethers.JsonRpcProvider` +export * from "./provider"; +// Follow ethers v5 convention like `ethers.providers.JsonRpcProvider` +import { JsonRpcProvider, Web3Provider } from "./provider"; +export const providers = { + JsonRpcProvider, + Web3Provider, +}; \ No newline at end of file diff --git a/ethers-ext/src/keystore.ts b/ethers-ext/src/keystore.ts index b8bd6e141..2ea22e098 100644 --- a/ethers-ext/src/keystore.ts +++ b/ethers-ext/src/keystore.ts @@ -1,9 +1,10 @@ import { getAddress } from "@ethersproject/address"; import { Bytes } from "@ethersproject/bytes"; import { ProgressCallback, decryptKeystore, decryptKeystoreSync } from "@ethersproject/json-wallets"; -import { isKIP3Json, splitKeystoreKIP3 } from "@klaytn/js-ext-core"; import _ from "lodash"; +import { isKIP3Json, splitKeystoreKIP3 } from "@klaytn/js-ext-core"; + // Decrypted keystore private keys. export interface KeystoreAccountList { address: string; diff --git a/ethers-ext/src/provider.ts b/ethers-ext/src/provider.ts index cc756496d..c4e633af5 100644 --- a/ethers-ext/src/provider.ts +++ b/ethers-ext/src/provider.ts @@ -1,10 +1,16 @@ import { Networkish } from "@ethersproject/networks"; -import { JsonRpcProvider as EthersJsonRpcProvider } from "@ethersproject/providers"; +import { + JsonRpcProvider as EthersJsonRpcProvider, + Web3Provider as EthersWeb3Provider, + JsonRpcSigner as EthersJsonRpcSigner } from "@ethersproject/providers"; import { ConnectionInfo } from "@ethersproject/web"; + import { asyncOpenApi, AsyncNamespaceApi } from "@klaytn/js-ext-core"; // @ts-ignore: package @klaytn/web3rpc has no .d.ts file. import { AdminApi, DebugApi, GovernanceApi, KlayApi, NetApi, PersonalApi, TxpoolApi } from "@klaytn/web3rpc"; +import { JsonRpcSigner } from "./signer"; + /* eslint-disable no-multi-spaces */ export class JsonRpcProvider extends EthersJsonRpcProvider { // API methods other than eth_ namespaces @@ -31,4 +37,35 @@ export class JsonRpcProvider extends EthersJsonRpcProvider { this.personal = asyncOpenApi(send, PersonalApi); this.txpool = asyncOpenApi(send, TxpoolApi); } +} + +export class Web3Provider extends EthersWeb3Provider { + // API methods other than eth_ namespaces + admin: AsyncNamespaceApi; + debug: AsyncNamespaceApi; + governance: AsyncNamespaceApi; + klay: AsyncNamespaceApi; + net: AsyncNamespaceApi; + personal: AsyncNamespaceApi; + txpool: AsyncNamespaceApi; + + constructor(provider: any, network?: any) { + super(provider, network); + + const send = (method: string, params: any) => { + return this.send(method, params); + }; + + this.admin = asyncOpenApi(send, AdminApi); + this.debug = asyncOpenApi(send, DebugApi); + this.governance = asyncOpenApi(send, GovernanceApi); + this.klay = asyncOpenApi(send, KlayApi); + this.net = asyncOpenApi(send, NetApi); + this.personal = asyncOpenApi(send, PersonalApi); + this.txpool = asyncOpenApi(send, TxpoolApi); + } + + override getSigner(addressOrIndex?: string | number | undefined): EthersJsonRpcSigner { + return new JsonRpcSigner(this, addressOrIndex); + } } \ No newline at end of file diff --git a/ethers-ext/src/signer.ts b/ethers-ext/src/signer.ts index 9b7cc320f..d42096163 100644 --- a/ethers-ext/src/signer.ts +++ b/ethers-ext/src/signer.ts @@ -1,68 +1,59 @@ -import { Provider, TransactionRequest, TransactionResponse } from "@ethersproject/abstract-provider"; -import { ExternallyOwnedAccount } from "@ethersproject/abstract-signer"; -import { JsonRpcProvider as EthersJsonRpcProvider } from "@ethersproject/providers"; +import { + Signer as EthersSigner, + TypedDataDomain, + TypedDataField, +} from "@ethersproject/abstract-signer"; +import { getAddress } from "@ethersproject/address"; +import { Bytes, hexlify } from "@ethersproject/bytes"; +import { _TypedDataEncoder } from "@ethersproject/hash"; +import { ProgressCallback } from "@ethersproject/json-wallets"; +import { keccak256 } from "@ethersproject/keccak256"; +import { Logger } from "@ethersproject/logger"; +import { Deferrable } from "@ethersproject/properties"; +import { + Web3Provider as EthersWeb3Provider, + JsonRpcProvider as EthersJsonRpcProvider, + JsonRpcSigner as EthersJsonRpcSigner, + Provider, + TransactionRequest, + TransactionResponse, +} from "@ethersproject/providers"; +import { toUtf8Bytes } from "@ethersproject/strings"; import { Wallet as EthersWallet } from "@ethersproject/wallet"; -import { poll } from "@ethersproject/web"; -import { KlaytnTxFactory, HexStr, isFeePayerSigTxType, parseTransaction } from "@klaytn/js-ext-core"; -import { BigNumber } from "ethers"; -import { Bytes, BytesLike, Deferrable, Logger, ProgressCallback, SigningKey, computeAddress, keccak256, resolveProperties } from "ethers/lib/utils"; import _ from "lodash"; -import { decryptKeystoreList, decryptKeystoreListSync } from "./keystore"; - -// @ethersproject/abstract-signer/src.ts/index.ts:allowedTransactionKeys -const ethersAllowedTransactionKeys: Array = [ - "accessList", "ccipReadEnabled", "chainId", "customData", "data", "from", "gasLimit", "gasPrice", "maxFeePerGas", "maxPriorityFeePerGas", "nonce", "to", "type", "value", -]; - -// ethers.js may strip or reject some Klaytn-specific transaction fields. -// To prserve transaction fields around super method calls, use -// saveCustomFields and restoreCustomFields. -function saveCustomFields(tx: Deferrable): any { - // Save fields that are not allowed in ethers.js - const savedFields: any = {}; - for (const key in tx) { - // 'from' may not be corresponded to the public key of the private key in a decoupled account. - if (ethersAllowedTransactionKeys.indexOf(key) === -1 || key == "from") { - savedFields[key] = _.get(tx, key); - _.unset(tx, key); - } - } - - // Save txtype that is not supported in ethers.js. - // and disguise as legacy (type 0) transaction. - // - // Why disguise as legacy type? - // Signer.populateTransaction() will not fill gasPrice - // unless tx type is explicitly Legacy (type=0) or EIP-2930 (type=1). - // Klaytn tx types, however, always uses gasPrice. - if (_.isNumber(tx.type) && KlaytnTxFactory.has(tx.type)) { - savedFields["type"] = tx.type; - tx.type = 0; - } - - return savedFields; -} - -function restoreCustomFields(tx: Deferrable, savedFields: any) { - for (const key in savedFields) { - _.set(tx, key, savedFields[key]); - } -} +import { + HexStr, + KlaytnTxFactory, + parseTransaction, + getRpcTxObject, + isKlaytnTxType, + isFeePayerSigTxType, +} from "@klaytn/js-ext-core"; -async function getTransactionRequest(transactionOrRLP: Deferrable | string): Promise { - if (_.isString(transactionOrRLP)) { - return parseTransaction(transactionOrRLP) as TransactionRequest; - } else { - const tx = transactionOrRLP; - return resolveProperties(tx); - } -} - -type PrivateKeyLike = BytesLike | ExternallyOwnedAccount | SigningKey; +import { decryptKeystoreList, decryptKeystoreListSync } from "./keystore"; +import { + eip155sign, + getTransactionRequest, + resolveType, + populateFrom, + populateFromSync, + populateTo, + populateNonce, + populateGasLimit, + populateGasPrice, + populateChainId, + populateFeePayerAndSignatures, + resolveTypeForKaikas, + pollTransactionInPool, +} from "./txutil"; +import { PrivateKeyLike, ExternalProvider } from "./types"; + + +const logger = new Logger("@klaytn/ethers-ext"); export class Wallet extends EthersWallet { - // Override Wallet factories accepting keystores to support KIP-3 (v4) format + // Override Wallet factories accepting keystores to support both v3 and v4 (KIP-3) formats static override async fromEncryptedJson(json: string, password: string | Bytes, progress?: ProgressCallback): Promise { const { address, privateKey } = await decryptKeystoreList(json, password, progress); return new Wallet(address, privateKey); @@ -73,7 +64,7 @@ export class Wallet extends EthersWallet { return new Wallet(address, privateKey); } - // New Wallet[] factories accepting keystores supporting KIP-3 (v4) format + // New Wallet[] factories accepting keystores supporting v4 (KIP-3) format static async fromEncryptedJsonList(json: string, password: string | Bytes, progress?: ProgressCallback): Promise { const { address, privateKeyList } = await decryptKeystoreList(json, password, progress); return _.map(privateKeyList, (privateKey) => new Wallet(address, privateKey)); @@ -93,22 +84,28 @@ export class Wallet extends EthersWallet { addressOrPrivateKey: string | PrivateKeyLike, privateKeyOrProvider?: PrivateKeyLike | Provider, provider?: Provider) { - // First argument is an address. if (HexStr.isHex(addressOrPrivateKey, 20)) { - const address = HexStr.from(addressOrPrivateKey); - const privateKey = privateKeyOrProvider as PrivateKeyLike; - super(privateKey, provider); - this.klaytnAddr = address; - } else { // First argument is a private key. - const privateKey = addressOrPrivateKey as PrivateKeyLike; + // First argument is an address. new KlaytnWallet(address, privateKey, provider?) + const _address = HexStr.from(addressOrPrivateKey); + const _privateKey = privateKeyOrProvider as PrivateKeyLike; + const _provider = provider; + + super(_privateKey, _provider); + this.klaytnAddr = _address; + } else { + // First argument is a private key. new KlaytnWallet(privateKey, provider?) + const _privateKey = addressOrPrivateKey as PrivateKeyLike; const _provider = privateKeyOrProvider as Provider; - super(privateKey, _provider); + + super(_privateKey, _provider); } } - getAddress(legacy?: boolean): Promise { + // If the Wallet is created as a decoupled account, and `legacy` is false, returns the decoupled address. + // Otherwise, returns the address derived from the private key. + override getAddress(legacy?: boolean): Promise { if (legacy || !this.klaytnAddr) { - return Promise.resolve(computeAddress(this.publicKey)); + return super.getAddress(); } else { return Promise.resolve(this.klaytnAddr); } @@ -119,6 +116,11 @@ export class Wallet extends EthersWallet { return super.getAddress(); } + // @deprecated in favor of parseTransaction + decodeTxFromRLP(rlp: string): any { + return parseTransaction(rlp); + } + async isDecoupled(): Promise { if (!this.klaytnAddr) { return false; @@ -127,91 +129,62 @@ export class Wallet extends EthersWallet { } } - // Fill legacy address for Ethereum TxTypes, and (possibly) decoupled address for Klaytn TxTypes. - checkTransaction(transaction: Deferrable): Deferrable { + // Fill 'from' if not set. Check 'from' against the private key or decoupled address. + override checkTransaction(transaction: Deferrable): Deferrable { const tx = _.clone(transaction); - const legacy = !KlaytnTxFactory.has(tx.type); - const expectedFrom = this.getAddress(legacy); - if (!tx.from) { - tx.from = expectedFrom; - } else { - tx.from = Promise.all([ - Promise.resolve(tx.from), - expectedFrom, - ]).then(([from, expectedFrom]) => { - if (from?.toLowerCase() != expectedFrom?.toLowerCase()) { - throw new Error(`from address mismatch tx=${JSON.stringify(transaction)} addr=${expectedFrom}`); - } - return from; - }); - } + const useLegacyFrom = !isKlaytnTxType(resolveType(tx.type as number)); + const expectedFrom = this.getAddress(useLegacyFrom); + populateFromSync(tx, expectedFrom); + return tx; } async populateTransaction(transaction: Deferrable): Promise { + return this._populateTransaction(transaction, false); + } + + // If asFeePayer is true, skip the 'from' address check. + private async _populateTransaction(transaction: Deferrable, asFeePayer: boolean): Promise { const tx = await getTransactionRequest(transaction); - // Not a Klaytn TxType; fallback to ethers.Wallet - if (!KlaytnTxFactory.has(tx.type)) { + // Not a Klaytn TxType; fallback to ethers.Signer.populateTransaction() + if (!isKlaytnTxType(resolveType(tx.type))) { return super.populateTransaction(tx); } - // Fill 'from' field. - if (!tx.from) { - tx.from = await this.getAddress(); - } - - // If the account address is decoupled from private key, - // the ethers.Wallet.populateTransaction() may fill the nonce of the wrong address. - if (!tx.nonce) { - tx.nonce = await this.provider.getTransactionCount(tx.from); - } - - // Sometimes estimateGas underestimates the required gas limit. - // Therefore adding some buffer to the RPC result. - // Other cases: - // - ethers.js uses estimateGas result as-is. - // - Metamask multiplies by 1 or 1.5 depending on chainId - // (https://github.com/MetaMask/metamask-extension/blob/v11.3.0/ui/ducks/send/helpers.js#L126) - // TODO: To minimize buffer, add constant intrinsic gas overhead instead of multiplier. - if (!tx.gasLimit) { - const bufferMultiplier = 2.5; - const gasLimit = await this.provider.estimateGas(tx); - tx.gasLimit = Math.ceil(gasLimit.toNumber() * bufferMultiplier); + // If the current Wallet acts as feePayer, then tx.from is unrelated to this.getAddress(). + // Skip the check, and does not fill up here. If tx.from was empty, then an error is generated + // at signTransaction(), not here. + if (!asFeePayer) { + await populateFrom(tx, await this.getAddress()); } - - // Leave rest of the fields to ethers - const savedFields = saveCustomFields(tx); - const populatedTx = await super.populateTransaction(tx); - restoreCustomFields(populatedTx, savedFields); - - return populatedTx; - } - - // @deprecated in favor of parseTransaction - decodeTxFromRLP(rlp :string): any { - return parseTransaction(rlp); + await populateTo(tx, this.provider); + await populateNonce(tx, this.provider, await this.getAddress()); + await populateGasLimit(tx, this.provider); + await populateGasPrice(tx, this.provider); + await populateChainId(tx, this.provider); + return tx; } // Sign as a sender // tx.sigs += Sign(tx.sigRLP(), wallet.privateKey) // return tx.txHashRLP() or tx.senderTxHashRLP(); - async signTransaction(transaction: Deferrable): Promise { + override async signTransaction(transaction: Deferrable): Promise { const tx = await getTransactionRequest(transaction); - // Not a Klaytn TxType; fallback to ethers.Wallet - if (!KlaytnTxFactory.has(tx.type)) { + // Not a Klaytn TxType; fallback to ethers.Wallet.signTransaction() + if (!isKlaytnTxType(resolveType(tx.type))) { return super.signTransaction(tx); } // Because RLP-encoded tx may not contain chainId, fill up here. - tx.chainId ??= await this._chainIdFromTx(tx); + await populateChainId(tx, this.provider); + const chainId = tx.chainId!; // chainId should have been determined in populateChainId. const klaytnTx = KlaytnTxFactory.fromObject(tx); - const sigHash = keccak256(klaytnTx.sigRLP()); - const sig = this._eip155sign(sigHash, tx.chainId); + const sig = eip155sign(this._signingKey(), sigHash, chainId); klaytnTx.addSenderSig(sig); if (isFeePayerSigTxType(klaytnTx.type)) { @@ -224,99 +197,338 @@ export class Wallet extends EthersWallet { // Sign as a fee payer // tx.feepayerSigs += Sign(tx.sigFeePayerRLP(), wallet.privateKey) // return tx.txHashRLP(); - async signTransactionAsFeePayer(transaction: Deferrable): Promise { - const tx = await getTransactionRequest(transaction); + async signTransactionAsFeePayer(transactionOrRLP: Deferrable | string): Promise { + const tx = await getTransactionRequest(transactionOrRLP); - // Not a Klaytn TxType; not supported - if (!KlaytnTxFactory.has(tx.type)) { - throw new Error(`feePayer signature not supported for tx type ${tx.type}`); + // Not a Klaytn FeePayerSig TxType; not supported + if (!isFeePayerSigTxType(resolveType(tx.type))) { + throw new Error(`signTransactionAsFeePayer not supported for tx type ${tx.type}`); } + // Because RLP-encoded tx may contain dummy fee payer fields, fix here. + await populateFeePayerAndSignatures(tx, await this.getAddress()); // Because RLP-encoded tx may not contain chainId, fill up here. - tx.chainId ??= await this._chainIdFromTx(tx); - - // Automatically populate 'feePayer' field, just like how 'from' field is populated. - // @ts-ignore: feePayer field does not exist in ethers.TransactionRequest type - tx.feePayer ??= await this.getAddress(); + await populateChainId(tx, this.provider); + const chainId = tx.chainId!; // chainId should have been determined in populateChainId. const klaytnTx = KlaytnTxFactory.fromObject(tx); - if (!isFeePayerSigTxType(klaytnTx.type)) { - klaytnTx.throwTypeError("feePayer signature not supported"); - } const sigFeePayerHash = keccak256(klaytnTx.sigFeePayerRLP()); - const sig = this._eip155sign(sigFeePayerHash, tx.chainId); + const sig = eip155sign(this._signingKey(), sigFeePayerHash, chainId); klaytnTx.addFeePayerSig(sig); return klaytnTx.txHashRLP(); } - async sendTransaction(transaction: Deferrable): Promise { - this._checkProvider("sendTransaction"); + override async sendTransaction(transaction: Deferrable): Promise { + const tx = await getTransactionRequest(transaction); + if (!isKlaytnTxType(resolveType(tx.type))) { + return super.sendTransaction(tx); + } - const populatedTx = await this.populateTransaction(transaction); + const populatedTx = await this._populateTransaction(tx, false); const signedTx = await this.signTransaction(populatedTx); + return await this._sendKlaytnRawTransaction(signedTx); + } + + async sendTransactionAsFeePayer(transactionOrRLP: Deferrable | string): Promise { + const tx = await getTransactionRequest(transactionOrRLP); - if (!KlaytnTxFactory.has(populatedTx.type)) { - return await this.provider.sendTransaction(signedTx); + // Not a Klaytn FeePayerSig TxType; not supported + if (!isFeePayerSigTxType(resolveType(tx.type))) { + throw new Error(`sendTransactionAsFeePayer not supported for tx type ${tx.type}`); + } + + const populatedTx = await this._populateTransaction(tx, true); + const signedTx = await this.signTransactionAsFeePayer(populatedTx); + return await this._sendKlaytnRawTransaction(signedTx); + } + + async _sendKlaytnRawTransaction(signedTx: string): Promise { + if (!(this.provider instanceof EthersJsonRpcProvider)) { + throw new Error("Provider is not JsonRpcProvider: cannot send klay_sendRawTransaction"); } else { - return await this._sendRawTransaction(signedTx); + const txhash = await this.provider.send("klay_sendRawTransaction", [signedTx]); + return await pollTransactionInPool(txhash, this.provider); } } +} - async sendTransactionAsFeePayer(transaction: Deferrable): Promise { - this._checkProvider("sendTransactionAsFeePayer"); - const populatedTx = await this.populateTransaction(transaction); - const signedTx = await this.signTransactionAsFeePayer(populatedTx); +// EthersJsonRpcSigner cannot be subclassed because of the constructorGuard. +// Instead, we re-create the class by copying the implementation. +export class JsonRpcSigner extends EthersSigner implements EthersJsonRpcSigner { + readonly provider: EthersJsonRpcProvider; + _index: number; + _address: string; + + // Equivalent to EthersJsonRpcSigner.constructor, but without constructorGuard. + // @ethersproject/providers/src.ts/json-rpc-provider.ts:JsonRpcSigner.constructor + constructor(provider: EthersJsonRpcProvider, addressOrIndex?: string | number) { + super(); + + this.provider = provider; + + if (addressOrIndex == null) { + addressOrIndex = 0; + } + + if (typeof (addressOrIndex) === "string") { + this._address = getAddress(addressOrIndex); + this._index = null as unknown as number; + } else if (typeof (addressOrIndex) === "number") { + this._address = null as unknown as string; + this._index = addressOrIndex; + } else { + throw new Error(`invalid address or index '${addressOrIndex}'`); + } + } - return await this._sendRawTransaction(signedTx); + isKaikas(): boolean { + if (this.provider instanceof EthersWeb3Provider) { + // The EIP-1193 provider, usually injected as window.ethereum or window.klaytn. + const injectedProvider = this.provider.provider as ExternalProvider; + return injectedProvider.isKaikas === true; + } + return false; } - _eip155sign(digest: string, chainId?: number) { - const sig = this._signingKey().signDigest(digest); - if (chainId) { - sig.v = sig.recoveryParam + chainId * 2 + 35; + // @ethersproject/providers/src.ts/json-rpc-provider.ts:JsonRpcSigner.getAddress + override async getAddress(): Promise { + if (this._address) { + return Promise.resolve(this._address); } - return sig; + + return this.provider.send("eth_accounts", []).then((accounts) => { + if (accounts.length <= this._index) { + logger.throwError("unknown account #" + this._index, Logger.errors.UNSUPPORTED_OPERATION, { + operation: "getAddress" + }); + } + return this.provider.formatter.address(accounts[this._index]); + }); + } + + // @ethersproject/providers/src.ts/json-rpc-provider.ts:JsonRpcSigner.connect + override connect(_provider: Provider): EthersJsonRpcSigner { + return logger.throwError("cannot alter JSON-RPC Signer connection", Logger.errors.UNSUPPORTED_OPERATION, { + operation: "connect" + }); + } + + // @ethersproject/providers/src.ts/json-rpc-provider.ts:JsonRpcSigner.connectUnchecked + connectUnchecked(): EthersJsonRpcSigner { + return new UncheckedJsonRpcSigner(this.provider, this._address || this._index); } - // Extract chainId from tx signatures. - // If no signatures, query provider. - async _chainIdFromTx(tx: any): Promise { - function extractFromSig(field: any[]): number | undefined { - if (_.isArray(field) && field.length > 0 && - _.isArray(field[0]) && field[0].length == 3) { - const v = BigNumber.from(field[0][0]).toNumber(); - return (v - 35) / 2; + // If underlying EIP-1193 provider is Kaikas, return the KIP-97 signed message in which + // the message is prefixed with "\x19Klaytn Signed Message:\n" + len(message) before signing. + // https://kips.klaytn.foundation/KIPs/kip-97 + // + // Otherwise, return the ERC-191 signed message in which the message is prefixed with + // "\x19Ethereum Signed Message:\n" + len(message) before signing. + // https://eips.ethereum.org/EIPS/eip-191 + // + // @ethersproject/providers/src.ts/json-rpc-provider.ts:JsonRpcSigner.signMessage + override async signMessage(message: string | Bytes): Promise { + const data = ((typeof (message) === "string") ? toUtf8Bytes(message) : message); + const address = await this.getAddress(); + + try { + if (this.isKaikas()) { + // KIP-97 states that the prefixed message signature should be accessible + // through the personal_sign method, but Kaikas provides it as eth_sign. + return await this.provider.send("eth_sign", [address.toLowerCase(), hexlify(data)]); + } else { + // Otherwise, use the standard personal_sign for ERC-191. + return await this.provider.send("personal_sign", [hexlify(data), address.toLowerCase()]); } - return undefined; + } catch (error: any) { + catchUserRejectedSigning(error, "signMessage", address, message); + throw error; + } + } + + // Return the signature of the message without prefix via the eth_sign method. + // This operation is deprecated in favor of signMessage (ERC-191 or KIP-97). + // + // Some providers may support this operation for backward compatibility, or reject it. + // In Kaikas, eth_sign is reserved for KIP-97 purpose, so the legacy sign message is decisively not supported. + // - If the provider is Kaikas, always throw an error. + // - If the provider is not Kaikas, try the eth_sign method. + // - If the provider rejects the operation, throw an error. + // - If the provider accepts the operation, return the signature. + // https://docs.metamask.io/wallet/concepts/signing-methods/#eth_sign + // https://support.metamask.io/hc/en-us/articles/14764161421467-What-is-eth-sign-and-why-is-it-a-risk- + async _legacySignMessage(message: Bytes | string): Promise { + if (this.isKaikas()) { + logger.throwError("Kaikas does not support the prefix-less legacy sign message", Logger.errors.UNSUPPORTED_OPERATION, { + operation: "_legacySignMessage" + }); + } + + // @ethersproject/providers/src.ts/json-rpc-provider.ts:JsonRpcSigner._legacySignMessage + const data = ((typeof (message) === "string") ? toUtf8Bytes(message) : message); + const address = await this.getAddress(); + + try { + return await this.provider.send("eth_sign", [address.toLowerCase(), hexlify(data)]); + } catch (error: any) { + catchUserRejectedSigning(error, "_legacySignMessage", address, message); + throw error; + } + } + + // Return the signature of the structured data according to EIP-712 via the eth_signTypedData_v4 method. + // https://eips.ethereum.org/EIPS/eip-712 + // https://docs.metamask.io/wallet/how-to/sign-data/#use-eth_signtypeddata_v4 + async _signTypedData(domain: TypedDataDomain, types: Record>, value: Record): Promise { + if (this.isKaikas()) { + logger.throwError("Kaikas does not support the EIP-712 typed structured data signing", Logger.errors.UNSUPPORTED_OPERATION, { + operation: "_signTypedData" + }); } - return ( - extractFromSig(tx.txSignatures) ?? - extractFromSig(tx.feePayerSignatures) ?? - this.getChainId()); + // @ethersproject/providers/src.ts/json-rpc-provider.ts:JsonRpcSigner._signTypedData + // Populate any ENS names (in-place) + const populated = await _TypedDataEncoder.resolveNames(domain, types, value, (name: string) => { + return this.provider.resolveName(name) as Promise; + }); + + const address = await this.getAddress(); + + try { + return await this.provider.send("eth_signTypedData_v4", [ + address.toLowerCase(), + JSON.stringify(_TypedDataEncoder.getPayload(populated.domain, types, populated.value)) + ]); + } catch (error: any) { + catchUserRejectedSigning(error, "_signTypedData", address, { domain: populated.domain, types, value: populated.value }); + throw error; + } } - async _sendRawTransaction(signedTx: string): Promise { - if (!(this.provider instanceof EthersJsonRpcProvider)) { - throw new Error("Klaytn typed transaction can only be broadcasted to a Klaytn JSON-RPC server"); - } else { - const txhash = await this.provider.send("klay_sendRawTransaction", [signedTx]); + override checkTransaction(transaction: Deferrable): Deferrable { + const tx = _.clone(transaction); + const expectedFrom = this.getAddress(); + populateFromSync(tx, expectedFrom); + return tx; + } + + override async populateTransaction(transaction: Deferrable): Promise { + const tx = await getTransactionRequest(transaction); + + // Not a Klaytn TxType; fallback to ethers.Signer.populateTransaction() + if (!isKlaytnTxType(resolveType(tx.type))) { + return super.populateTransaction(tx); + } + + await populateFrom(tx, await this.getAddress()); + await populateTo(tx, this.provider); + await populateNonce(tx, this.provider, await this.getAddress()); + await populateGasLimit(tx, this.provider); + await populateGasPrice(tx, this.provider); + await populateChainId(tx, this.provider); + return tx; + } + + // Return the signed transaction as a string but do not send it. + override async signTransaction(transaction: Deferrable): Promise { + if (!this.isKaikas()) { + return logger.throwError("signing transactions is only supported in Kaikas", Logger.errors.UNSUPPORTED_OPERATION, { + operation: "signTransaction" + }); + } + + const tx = await getTransactionRequest(transaction); + await populateFrom(tx, await this.getAddress()); + await populateGasLimit(tx, this.provider); + await populateTo(tx, this.provider); + + const rpcTx = getRpcTxObject(tx); + if (this.isKaikas()) { + rpcTx.type = resolveTypeForKaikas(rpcTx.type); + } + + try { + // Kaikas returns the web3-style signed transaction object. + const signedTx = await this.provider.send("klay_signTransaction", [rpcTx]); + return Promise.resolve(signedTx.rawTransaction); + } catch (error: any) { + catchUserRejectedTransaction(error, "signTransaction", transaction); + throw error; + } + } + + override async sendTransaction(transaction: Deferrable): Promise { + const txhash = await this.sendUncheckedTransaction(transaction); + return pollTransactionInPool(txhash, this.provider); + } + + async sendUncheckedTransaction(transaction: Deferrable): Promise { + const tx = await getTransactionRequest(transaction); + await populateFrom(tx, await this.getAddress()); + await populateGasLimit(tx, this.provider); + await populateTo(tx, this.provider); + + const rpcTx = getRpcTxObject(tx); + if (this.isKaikas()) { + rpcTx.type = resolveTypeForKaikas(rpcTx.type); + } - // Retry until the transaction shows up in the txpool - // Using poll() like in the ethers.JsonRpcProvider.sendTransaction - // https://github.com/ethers-io/ethers.js/blob/v5.7/packages/providers/src.ts/json-rpc-provider.ts#L283 - const pollFunc = async () => { - const tx = await this.provider.getTransaction(txhash); - if (tx == null) { - return undefined; // retry - } else { - return tx; // success - } - }; - return poll(pollFunc) as Promise; + try { + if (this.isKaikas()) { + return await this.provider.send("klay_sendTransaction", [rpcTx]); + } else { + return await this.provider.send("eth_sendTransaction", [rpcTx]); + } + } catch (error: any) { + catchUserRejectedTransaction(error, "sendTransaction", tx); + throw error; } } + + async unlock(password: string): Promise { + const address = await this.getAddress(); + return this.provider.send("personal_unlockAccount", [address.toLowerCase(), password, null]); + } } + +// Variant of JsonRpcSigner where it does not wait for the transaction to be in the txpool. +// @ethersproject/providers/src.ts/json-rpc-provider.ts:UncheckedJsonRpcSigner +class UncheckedJsonRpcSigner extends JsonRpcSigner { + override async sendTransaction(transaction: Deferrable): Promise { + const txhash = await this.sendUncheckedTransaction(transaction); + return Promise.resolve({ + hash: txhash, + nonce: null, + gasLimit: null, + gasPrice: null, + data: null, + value: null, + chainId: null, + confirmations: 0, + from: null, + wait: (confirmations?: number) => { return this.provider.waitForTransaction(txhash, confirmations); } + } as unknown as TransactionResponse); // forcefully cast to TransactionResponse + } +} + +function catchUserRejectedSigning(error: any, action: string, from: string, messageData: any) { + if (typeof(error.message) === "string" && error.message.match(/user denied/i)) { + logger.throwError("user rejected signing", Logger.errors.ACTION_REJECTED, { + action, + from, + messageData, + }); + } +} + +function catchUserRejectedTransaction(error: any, action: string, transaction: any) { + if (typeof (error.message) === "string" && error.message.match(/user denied/i)) { + logger.throwError("user rejected transaction", Logger.errors.ACTION_REJECTED, { + action, + transaction, + }); + } +} \ No newline at end of file diff --git a/ethers-ext/src/txutil.ts b/ethers-ext/src/txutil.ts new file mode 100644 index 000000000..349ff7792 --- /dev/null +++ b/ethers-ext/src/txutil.ts @@ -0,0 +1,219 @@ +import { Provider, TransactionResponse } from "@ethersproject/abstract-provider"; +import { BigNumber } from "@ethersproject/bignumber"; +import { Signature } from "@ethersproject/bytes"; +import { AddressZero } from "@ethersproject/constants"; +import { Logger } from "@ethersproject/logger"; +import { Deferrable, resolveProperties } from "@ethersproject/properties"; +import { SigningKey } from "@ethersproject/signing-key"; +import { poll } from "@ethersproject/web"; +import _ from "lodash"; + +import { HexStr, TxType, isKlaytnTxType, parseTransaction } from "@klaytn/js-ext-core"; + +import { TransactionRequest } from "./types"; + +const logger = new Logger("@klaytn/ethers-ext"); + + +// Normalize transaction request in Object or RLP format +export async function getTransactionRequest(transactionOrRLP: Deferrable | string): Promise { + if (_.isString(transactionOrRLP)) { + return parseTransaction(transactionOrRLP) as TransactionRequest; + } else { + return resolveProperties(transactionOrRLP); + } +} + +// TODO: replace with js-ext-core parseTxType +export function resolveType(type?: number | string): number { + if (!type) { + return 0; + } + if (_.isNumber(type)) { + return type; + } + if (_.isString(type)) { + // Try the hex string, e.g. "0x08" + if (HexStr.isHex(type)) { + return HexStr.toNumber(type); + } + } + throw new Error(`Unrecognized tx type '${type}'. Must be a number.'`); +} + +// TODO: replace with js-ext-core getKaikasTxType +// Convert tx.type field to what Kaikas wants. +// - If unspecified, keep it as-is. undefined => undefined +// - Ethereum types are kept as-is. 0,1,2 => 0,1,2 +// - Klaytn types are converted to string. 8 => "VALUE_TRANSFER" +export function resolveTypeForKaikas(type?: string | number): string | number | undefined { + // Skip type == 0 or undefined + if (!type) { + return undefined; + } + + if (_.isString(type)) { + if (HexStr.isHex(type)) { + // Try the hex string, e.g. "0x08" + return resolveTypeForKaikas(HexStr.toNumber(type)); + } else { + // Pass-through if type is already string. Let Kaikas handle it. + return type; + } + } + + if (_.isNumber(type)) { + if (!isKlaytnTxType(type)) { + // Pass-through Ethereum TxTypes as number + return type; + } + + const camelName: string | undefined = TxType[type]; + if (camelName) { + // "ValueTransfer" => "VALUE_TRANSFER" + return _.snakeCase(camelName).toUpperCase(); + } + } + + throw new Error(`Unrecognized tx type '${type}'.`); +} + +// Below populateX() methods are partial replacements to: +// - ethers.Signer.checkTransaction() +// - ethers.Signer.populateTransaction() +// - ethers.JsonRpcSigner.sendUncheckedTransaction() + +// populateFromSync is a synchronous method so it can be used in checkTransaction(). +export function populateFromSync(tx: Deferrable, expectedFrom: string | Promise) { + // See @ethersproject/abstract-signer/src/index.ts:Signer.checkTransaction() + if (!tx.from) { + tx.from = expectedFrom; + } else { + tx.from = Promise.all([ + Promise.resolve(tx.from), + expectedFrom, + ]).then(([from, expectedFrom]) => { + if (from?.toLowerCase() != expectedFrom?.toLowerCase()) { + logger.throwArgumentError(`from address mismatch (wallet address=${expectedFrom}) (tx.from=${from})`, "transaction", tx); + } + return from; + }); + } +} + +export async function populateFrom(tx: TransactionRequest, expectedFrom: string) { + populateFromSync(tx, expectedFrom); + tx.from = await tx.from; +} + +export async function populateTo(tx: TransactionRequest, provider: Provider) { + if (!tx.to) { + tx.to = AddressZero; + } else { + const address = await provider.resolveName(tx.to); + if (address == null) { + logger.throwArgumentError("provided ENS name resolves to null", "tx.to", tx.to); + } + } +} + +export async function populateNonce(tx: TransactionRequest, provider: Provider, fromAddress: string) { + if (!tx.nonce) { + tx.nonce = await provider.getTransactionCount(fromAddress); + } +} + +export async function populateGasLimit(tx: TransactionRequest, provider: Provider) { + if (!tx.gasLimit) { + // Sometimes Klaytn node's eth_estimateGas may return insufficient amount. + // To avoid this, add buffer to the estimated gas. + // References: + // - ethers.js uses estimateGas result as-is. + // - Metamask multiplies by 1 or 1.5 depending on chainId + // (https://github.com/MetaMask/metamask-extension/blob/v11.3.0/ui/ducks/send/helpers.js#L126) + // TODO: To minimize buffer, add constant intrinsic gas overhead instead of multiplier. + try { + const bufferMultiplier = 2.5; + const gasLimit = await provider.estimateGas(tx); + tx.gasLimit = Math.ceil(gasLimit.toNumber() * bufferMultiplier); + } catch (error) { + logger.throwError("cannot estimate gas; transaction may fail or may require manual gas limit", Logger.errors.UNPREDICTABLE_GAS_LIMIT, { + error: error, + tx: tx + }); + } + } +} + +export async function populateGasPrice(tx: TransactionRequest, provider: Provider) { + if (!tx.gasPrice) { + tx.gasPrice = await provider.getGasPrice(); + } +} + +export function eip155sign(key: SigningKey, digest: string, chainId: number): Signature { + const sig = key.signDigest(digest); + sig.v = sig.recoveryParam + chainId * 2 + 35; + return sig; +} + +// TODO: replace with js-ext-core getChainIdFromSignatureTuples +// Extract chainId from tx.txSignatures[] or tx.feePayerSignatures[]. +// It works because Klaytn TxType always follows EIP-155. +function chainIdFromSig(signatures?: any[]): number | undefined { + if (_.isArray(signatures) && signatures.length > 0) { + const signature = signatures[0]; + if (_.isArray(signature) && signature.length == 3) { + const v = BigNumber.from(signature[0]).toNumber(); + if (v >= 35) { + return (v + (v % 2) - 36) / 2; + } + } + } + return undefined; +} + +export async function populateChainId(tx: TransactionRequest, provider: Provider) { + if (!tx.chainId) { + tx.chainId = ( + chainIdFromSig(tx.txSignatures) ?? + chainIdFromSig(tx.feePayerSignatures) ?? + (await provider.getNetwork()).chainId); + } +} + +export async function populateFeePayerAndSignatures(tx: TransactionRequest, expectedFeePayer: string) { + // A SenderTxHashRLP returned from caver may have dummy feePayer even if SenderTxHashRLP shouldn't have feePayer. + // So ignore AddressZero in the feePayer field. + if (!tx.feePayer || tx.feePayer == AddressZero) { + tx.feePayer = expectedFeePayer; + } else { + if (tx.feePayer.toLowerCase() != expectedFeePayer.toLowerCase()) { + logger.throwArgumentError("feePayer address mismatch", "transaction", tx); + } + } + + // A SenderTxHashRLP returned from caver may have dummy feePayerSignatures if SenderTxHashRLP shouldn't have feePayerSignatures. + // So ignore [ '0x01', '0x', '0x' ] in the feePayerSignatures field. + if (_.isArray(tx.feePayerSignatures)) { + tx.feePayerSignatures = tx.feePayerSignatures.filter((sig) => { + return !(_.isArray(sig) && sig.length == 3 && sig[0] == "0x01" && sig[1] == "0x" && sig[2] == "0x"); + }); + } +} + +// Poll for `eth_getTransaction` until the transaction is found in the transaction pool. +export async function pollTransactionInPool(txhash: string, provider: Provider): Promise { + // Retry until the transaction shows up in the txpool + // Using poll() like in the ethers.JsonRpcSigner.sendTransaction + // https://github.com/ethers-io/ethers.js/blob/v5.7/packages/providers/src.ts/json-rpc-provider.ts#L283 + const pollFunc = async () => { + const tx = await provider.getTransaction(txhash); + if (tx == null) { + return undefined; // retry + } else { + return tx; // success + } + }; + return poll(pollFunc) as Promise; +} \ No newline at end of file diff --git a/ethers-ext/src/types.ts b/ethers-ext/src/types.ts new file mode 100644 index 000000000..a8b1832d4 --- /dev/null +++ b/ethers-ext/src/types.ts @@ -0,0 +1,20 @@ +import { TransactionRequest as EthersTransactionRequest } from "@ethersproject/abstract-provider"; +import { ExternallyOwnedAccount } from "@ethersproject/abstract-signer"; +import { BytesLike } from "@ethersproject/bytes"; +import { ExternalProvider as EthersExternalProvider } from "@ethersproject/providers"; +import { SigningKey } from "@ethersproject/signing-key"; + + +export interface TransactionRequest extends EthersTransactionRequest { + txSignatures?: any[]; + feePayer?: string; + feePayerSignatures?: any[]; +} + +// Used in Wallet constructor. +export type PrivateKeyLike = BytesLike | ExternallyOwnedAccount | SigningKey; + +// Represents window.ethereum (MetaMask) and window.klaytn (Kaikas) +export interface ExternalProvider extends EthersExternalProvider { + isKaikas?: boolean; // Exists in window.klaytn that is injected by Kaikas +} \ No newline at end of file diff --git a/ethers-ext/test/provider.spec.ts b/ethers-ext/test/provider.spec.ts index f90482e41..d8c9747c1 100644 --- a/ethers-ext/test/provider.spec.ts +++ b/ethers-ext/test/provider.spec.ts @@ -1,4 +1,5 @@ import { assert } from "chai"; +import { describe } from "mocha"; import { MockKlaytnProvider } from "./mock_provider"; diff --git a/ethers-ext/test/signer.spec.ts b/ethers-ext/test/signer.spec.ts index 727df5809..3069adf8b 100644 --- a/ethers-ext/test/signer.spec.ts +++ b/ethers-ext/test/signer.spec.ts @@ -1,12 +1,12 @@ +import { AddressZero } from "@ethersproject/constants"; import { keccak256 } from "@ethersproject/keccak256"; -import { parseTransaction } from "@klaytn/js-ext-core"; import chai, { assert, expect } from "chai"; import chaiAsPromised from "chai-as-promised"; import { Wallet as EthersWallet } from "ethers"; import _ from "lodash"; import { describe, it } from "mocha"; -import { Wallet as KlaytnWallet } from "../src"; +import { KlaytnTxFactory, Wallet as KlaytnWallet, parseTransaction } from "../src"; import { MockEthersProvider, MockKlaytnProvider } from "./mock_provider"; @@ -25,12 +25,16 @@ const nonce = 2; const gasPrice = 25e9; const gasLimit = 50000; const chainId = 1001; -const txHashRLP = "0x08f87a8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0bf845f84325a0f3d0cd43661cabf53425535817c5058c27781f478cb5459874feaa462ed3a29aa06748abe186269ff10b8100a4b7d7fea274b53ea2905acbf498dc8b5ab1bf4fbc"; -const senderTxHashRLP = "0x09f87a8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0bf845f84325a09f8e49e2ad84b0732984398749956e807e4b526c786af3c5f7416b293e638956a06bf88342092f6ff9fabe31739b2ebfa1409707ce54a54693e91a6b9bb77df0e7"; -const txSignatures = [["0x25", "0x9f8e49e2ad84b0732984398749956e807e4b526c786af3c5f7416b293e638956", "0x6bf88342092f6ff9fabe31739b2ebfa1409707ce54a54693e91a6b9bb77df0e7"]]; + +const txHashRLP = "0x08f87e028505d21dba0082c3509470997970c51812dc3a010c7d01b50e0d17dc79c8809490f79bf6eb2c4f870365e785982e1f101e93b906f847f8458207f5a0e16b4d0efd52c217dc3d868834cd1dc7a36f793acf8f4558a3de0eb9a62869fba02fe50e20b55ea59a41678eab633696db728c65755e5fe1d72cb4c006fafad67b"; +const senderTxHashRLP_fit = "0x09f880821922850ba43b740082cd149470997970c51812dc3a010c7d01b50e0d17dc79c88094f39fd6e51aad88f6f4ce6ab8827279cfffb92266f847f8458207f5a003b5e4371caae44de62e9b2c799b9744d46e84c3309b704cfa276cc6659671f8a0453a40c726a6f5e6fb32e54fc3279508c48cb54e589982c3f01580209a8b0c02"; +const senderTxHashRLP_pad = "0x09f89a821922850ba43b740082cd149470997970c51812dc3a010c7d01b50e0d17dc79c88094f39fd6e51aad88f6f4ce6ab8827279cfffb92266f847f8458207f5a003b5e4371caae44de62e9b2c799b9744d46e84c3309b704cfa276cc6659671f8a0453a40c726a6f5e6fb32e54fc3279508c48cb54e589982c3f01580209a8b0c02940000000000000000000000000000000000000000c4c3018080"; +const txSignatures = [["0x7f5", "0x9f8e49e2ad84b0732984398749956e807e4b526c786af3c5f7416b293e638956", "0x6bf88342092f6ff9fabe31739b2ebfa1409707ce54a54693e91a6b9bb77df0e7"]]; + const block = JSON.parse('{"difficulty":"0x1","extraData":"0x","gasLimit":"0xe8d4a50fff","gasUsed":"0x0","hash":"0xe6a28d57db4dec9eacad5e6ce3d90fef900ab65760c579c46567b4bbb3803bc2","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0x571e53df607be97431a5bbefca1dffe5aef56f4d","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0000000000000000","number":"0x12d687","parentHash":"0x720ed13d78e8b0f2c20f4129b9b69dcbad49eebecfc2bb22e792be5ea28ecbfc","receiptsRoot":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x33b","stateRoot":"0xd3db6e4adfc526b5028764512e338d0ff3d8bc76e02593a763ac747ed8a22112","timestamp":"0x5d261b95","totalDifficulty":"0x12d688","transactions":[],"transactionsRoot":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","uncles":[]}'); const txJson = JSON.parse('{"blockHash":"0x1d59ff54b1eb26b013ce3cb5fc9dab3705b415a67127a003c3e61eb445bb8df2","blockNumber":"0x5daf3b","hash":"0x88df016429689c079f3b2f6ad39fa052532c56795b733da78a91ebe6a713944b","from":"0xa7d9ddbe1f17865597fbd27ec712455208b6b76d","gas":"0xc350","gasPrice":"0x4a817c800","input":"0x68656c6c6f21","nonce":"0x15","r":"0x1b5e176d927f8e9ab405058b2d2457392da3e20f328b16ddabcebc33eaac5fea","s":"0x4ba69724e8f69de52f0125ad8b3c5c2cef33019bac3249e2c0a2192766d1721c","to":"0xf02c1c8e6114b1dbe8937a39260b5b0a374432bb","transactionIndex":"0x41","type":"0x0","v":"0x25","value":"0xf3dbb76162000"}'); + describe("Wallet", () => { let EP: MockEthersProvider; let KP: MockKlaytnProvider; @@ -119,9 +123,6 @@ describe("Wallet", () => { }); // populateTransaction must fill all missing fields - // - from, nonce, gasPrice, gasLimit correctly added as resolved (not Promise) types - // - Only check field existence because values depend on network state. - // - Original tx object remain untouched describe("populateTransaction", () => { async function testOK(W: EthersWallet, tx: any) { let res = await W.populateTransaction(tx); @@ -167,10 +168,11 @@ describe("Wallet", () => { }); it("as fee payer", async () => { for (let W of [KW, KWD]) { - await testOK_AsFeePayer(W, { type: 9, from: (await W.getAddress()), to, feePayer, value, nonce, gasPrice, gasLimit, chainId, txSignatures }); + await testOK_AsFeePayer(W, { type: 9, from, to, feePayer: (await W.getAddress()), value, nonce, gasPrice, gasLimit, chainId, txSignatures }); } for (let W of [KW, KWD]) { - await testOK_AsFeePayer(W, senderTxHashRLP); + await testOK_AsFeePayer(W, senderTxHashRLP_fit); + await testOK_AsFeePayer(W, senderTxHashRLP_pad); } }); }); @@ -186,11 +188,14 @@ describe("Wallet", () => { assert.isDefined(res.hash); assert.isDefined(res.wait); } - async function testOK_AsFeePayer(W: KlaytnWallet, tx: any) { + async function testOK_AsFeePayer(W: KlaytnWallet, tx: any, expectedFrom?: string) { let res = await W.sendTransactionAsFeePayer(tx); assert.isDefined(res); assert.isDefined(res.hash); assert.isDefined(res.wait); + + expectedFrom ??= await W.getAddress(); + assert.equal(parseTransaction(sentRawTx).from, expectedFrom); } it("as sender", async () => { @@ -201,12 +206,16 @@ describe("Wallet", () => { await testOK(W, { type: 9, to, feePayer, value }); } }); + // 'from' address differs from W.getAddress() + // because W is the fee payer, not the sender. + // The sentRawTx must have the original 'from' address, not fee payer's. it("as fee payer", async () => { for (let W of [KW, KWD]) { - await testOK_AsFeePayer(W, { type: 9, to, feePayer, value, nonce, gasPrice, gasLimit, chainId, txSignatures }); + await testOK_AsFeePayer(W, { type: 9, from, to, feePayer: (await W.getAddress()), value, nonce, gasPrice, gasLimit, chainId, txSignatures }, from); } for (let W of [KW, KWD]) { - await testOK_AsFeePayer(W, senderTxHashRLP); + await testOK_AsFeePayer(W, senderTxHashRLP_fit, from); + await testOK_AsFeePayer(W, senderTxHashRLP_pad, from); } }); }); diff --git a/ethers-ext/webpack.config.js b/ethers-ext/webpack.config.js new file mode 100644 index 000000000..5ad51949b --- /dev/null +++ b/ethers-ext/webpack.config.js @@ -0,0 +1,28 @@ +const path = require("path"); + +module.exports = { + entry: "./src/index.ts", + module: { + rules: [ + { + test: /\.ts$/, + use: 'ts-loader', + exclude: /node_modules/, + }, + ], + }, + resolve: { + extensions: ['.tsx', '.ts', '.js'], + fallback: { + "querystring": false, // referenced in web3rpc/ApiClient, which is unused. + }, + }, + output: { + // Output dist/ethers-ext.bundle.js + filename: 'ethers-ext.bundle.js', + path: path.resolve(__dirname, 'dist'), + // Define window.ethers_ext + library: "ethers_ext", + libraryTarget: "window", + }, +}; diff --git a/js-ext-core/package.json b/js-ext-core/package.json index 671ff9cd9..05f4cf2cf 100644 --- a/js-ext-core/package.json +++ b/js-ext-core/package.json @@ -33,6 +33,7 @@ "@types/elliptic": "^6.4.16", "@types/jest": "^29.5.7", "@types/lodash": "^4.14.199", + "@types/mocha": "^10.0.6", "@types/node": "^20.8.10", "@typescript-eslint/eslint-plugin": "^6.1.0", "chai": "^4.3.7", diff --git a/js-ext-core/src/tx/factory.ts b/js-ext-core/src/tx/factory.ts index c22b4755c..13fd867e8 100644 --- a/js-ext-core/src/tx/factory.ts +++ b/js-ext-core/src/tx/factory.ts @@ -143,7 +143,7 @@ class _KlaytnTxFactory extends FieldSetFactory { fields.data = fields.input; } // In TxTypeSmartContractDeploy, force 'to' = 0x for compatibility - if (HexStr.fromNumber(fields.type) == HexStr.fromNumber(TxType.SmartContractDeploy) || + if (HexStr.fromNumber(fields.type) == HexStr.fromNumber(TxType.SmartContractDeploy) || HexStr.fromNumber(fields.type) == HexStr.fromNumber(TxType.FeeDelegatedSmartContractDeploy) || HexStr.fromNumber(fields.type) == HexStr.fromNumber(TxType.FeeDelegatedSmartContractDeployWithRatio)) { fields.to = "0x"; diff --git a/js-ext-core/src/util/const.ts b/js-ext-core/src/util/const.ts index b4050625f..c4005249a 100644 --- a/js-ext-core/src/util/const.ts +++ b/js-ext-core/src/util/const.ts @@ -1,3 +1,7 @@ +import _ from "lodash"; + +import { HexStr } from "./data"; + // Klaytn Type Enumeration export enum TxType { // Basic @@ -25,19 +29,68 @@ export enum TxType { FeeDelegatedCancelWithRatio = 0x3a, } -export function isKlaytnTxType(type: number): boolean { - return (type in TxType); +// Parse Klaytn TxType in various formats including number (8), +// hex string (0x08), camel case string ("ValueTransfer"), and snake case string ("VALUE_TRANSFER"). +export function parseTxType(type?: number | string): number { + if (type == undefined) { + return 0; + } + + if (_.isNumber(type)) { + return type; + } + + if (_.isString(type) && type.length > 0) { + // Try the hex string, e.g. "0x08" + if (HexStr.isHex(type)) { + return HexStr.toNumber(type); + } + // Try camel case string, e.g. "ValueTransfer", "TxTypeValueTransfer" + // or snake case string, e.g. "VALUE_TRANSFER" + let name = type; + if (name.startsWith("TxType")) { + name = name.substring(6); + } + name = _.upperFirst(_.camelCase(name)); + if (_.has(TxType, name)) { + return _.get(TxType, name); + } + } + + throw new Error(`Unrecognized tx type '${type}'. Expected a number.'`); +} + +// Convert Klaytn TxType to what Kaikas wallet (https://docs.kaikas.io/) understands. +// Pass-through undefined and non-Klaytn TxTypes. +// Convert Klaytn TxTypes to upper and snake case string (e.g. "VALUE_TRANSFER"). +export function getKaikasTxType(type?: number | string): number | string | undefined { + const num = parseTxType(type); + if (!isKlaytnTxType(num)) { + return num; + } else { + const name = TxType[num]; + return _.snakeCase(name).toUpperCase(); + } +} + +// Returns true for Klaytn TxType. +export function isKlaytnTxType(type?: number): boolean { + return !!type && (type in TxType); } -export function isBasicTxType(type: number): boolean { - return (type in TxType) && ((type & 0x3) == 0x0); +// Returns true for Klaytn Basic (i.e. not fee delegated) TxType. +export function isBasicTxType(type?: number): boolean { + return !!type && (type in TxType) && ((type & 0x3) == 0x0); } -export function isFeeDelegationTxType(type: number): boolean { - return (type in TxType) && ((type & 0x3) == 0x1); +// Returns true for Klaytn Fee Delegated TxType. +export function isFeeDelegationTxType(type?: number): boolean { + return !!type && (type in TxType) && ((type & 0x3) == 0x1); } -export function isPartialFeeDelegationTxType(type: number): boolean { - return (type in TxType) && ((type & 0x3) == 0x2); +// Returns true for Klaytn Partial Fee Delegated (i.e. with ratio) TxType. +export function isPartialFeeDelegationTxType(type?: number): boolean { + return !!type && (type in TxType) && ((type & 0x3) == 0x2); } -export function isFeePayerSigTxType(type: number): boolean { +// Returns true for Klaytn TxType with feePayer feature (i.e. fee delegation or partial fee delegation). +export function isFeePayerSigTxType(type?: number): boolean { return isFeeDelegationTxType(type) || isPartialFeeDelegationTxType(type); } @@ -51,13 +104,14 @@ export enum AccountKeyType { RoleBased = 0x05 } -export function isKlaytnAccountKeyType(type: number): boolean { - return (type in AccountKeyType); +// Returns true for Klaytn AccountKeyType. +export function isKlaytnAccountKeyType(type?: number): boolean { + return !!type && (type in AccountKeyType); } -// Returns true if it can be embedded in an AccountKeyRoleBased -export function isEmbeddableAccountKeyType(type: number): boolean { - // any of AccountKeyNil, AccountKeyLegacy, AccountKeyPublic, AccountKeyFail, and AccountKeyWeightedMultiSig. - return (type in AccountKeyType) && (type != AccountKeyType.RoleBased); +// Returns true for AccountKeyTypes that can be embedded in an AccountKeyRoleBased +// (i.e. AccountKeyNil, AccountKeyLegacy, AccountKeyPublic, AccountKeyFail, and AccountKeyWeightedMultiSig) +export function isEmbeddableAccountKeyType(type?: number): boolean { + return !!type && (type in AccountKeyType) && (type != AccountKeyType.RoleBased); } export const CodeFormatEVM = 0x00; diff --git a/js-ext-core/src/util/ec.ts b/js-ext-core/src/util/ec.ts index 4c3dcd88a..ba2c8d8f0 100644 --- a/js-ext-core/src/util/ec.ts +++ b/js-ext-core/src/util/ec.ts @@ -1,4 +1,4 @@ -import { splitSignature } from "@ethersproject/bytes"; +import { SignatureLike as EthersSignatureLike, Signature, splitSignature } from "@ethersproject/bytes"; import { ec } from "elliptic"; import _ from "lodash"; @@ -33,19 +33,11 @@ export function getCompressedPublicKey(pub: any): string { // All elements must be string for RLP encoding. export type SignatureTuple = [string, string, string]; -// Commonly used signature object. -export interface SignatureObject { - r: string; - s: string; - v?: number; - recoveryParam?: number; -} - // All kinds of ECDSA signatures returned from various libraries. export type SignatureLike = - SignatureTuple | - SignatureObject | - string; + EthersSignatureLike | // { r, s, v } or { r, s, recoveryParam } + string | // compact signature + string[]; // [v, r, s] // If the sig is an array, the first element 'v' must be one of: // - pre-EIP-155 v: {27, 28} @@ -65,18 +57,51 @@ export type SignatureLike = // "0x75c2c3e5f7b0a182c767137c488649cd5104a5e747371fd922d618e328e5c508", // ] export function getSignatureTuple(sig: SignatureLike): SignatureTuple { - // For array, pass through splitSignature() for sanity check - if (_.isArray(sig) && sig.length == 3) { + // Pass through splitSignature() for sanity check + let obj: Signature; + if (_.isArray(sig)) { + if (sig.length != 3) { + throw new Error("Signature tuple must have 3 elements [v,r,s]"); + } const numV = HexStr.toNumber(sig[0]); - sig = { v: numV, r: sig[1], s: sig[2] }; + obj = splitSignature({ v: numV, r: sig[1], s: sig[2] }); + } else { + obj = splitSignature(sig); } - const split = splitSignature(sig); // R and S must not have leading zeros // c.f. https://github.com/ethers-io/ethers.js/blob/v5/packages/transactions/src.ts/index.ts#L298 return [ - HexStr.fromNumber(split.v), - HexStr.stripZeros(split.r), - HexStr.stripZeros(split.s), + HexStr.fromNumber(obj.v), + HexStr.stripZeros(obj.r), + HexStr.stripZeros(obj.s), ]; } + +// Extract chainId from tx.txSignatures[] or tx.feePayerSignatures[]. +// It works because Klaytn TxType signatures are always EIP-155. +// Returns undefined if chainId cannot be extracted. Use other methods like RPC to get chainId. +export function getChainIdFromSignatureTuples(signatures?: any[]): number | undefined { + if (!_.isArray(signatures) || signatures.length == 0) { + return undefined; + } + + const signature = signatures[0]; + if (!_.isArray(signature) || signature.length != 3) { + return undefined; + } + + const strV = signature[0]; + if (!HexStr.isHex(strV)) { + return undefined; + } + + // v = 2 * chainId + {35, 36} + // v + (v % 2) = 2 * chainId + 36 + const v = HexStr.toNumber(strV); + if (v >= 35) { + return (v + (v % 2) - 36) / 2; + } else { + return undefined; + } +} diff --git a/js-ext-core/test/util.spec.ts b/js-ext-core/test/util.spec.ts index ca85ac6c5..b028e18a8 100644 --- a/js-ext-core/test/util.spec.ts +++ b/js-ext-core/test/util.spec.ts @@ -1,6 +1,7 @@ import { BigNumber } from "@ethersproject/bignumber"; import { formatUnits as formatEthUnits, parseUnits as parseEthUnits, formatEther, parseEther } from "@ethersproject/units"; import { assert } from "chai"; +import { describe, it } from "mocha"; /* eslint-disable */ // @ts-ignore: package @klaytn/web3rpc has no .d.ts file. //import { ApiClient, KlayApi } from "@klaytn/web3rpc"; @@ -8,6 +9,8 @@ import { assert } from "chai"; import { TxType, + parseTxType, + getKaikasTxType, isBasicTxType, isFeeDelegationTxType, isKlaytnTxType, @@ -23,11 +26,12 @@ import { HexStr, isKIP3Json, splitKeystoreKIP3, + getChainIdFromSignatureTuples, } from "../src"; describe("util", () => { - it("TxType", () => { + it("const", () => { // Eth types are not Klaytn TxType assert.isFalse(isKlaytnTxType(0)); assert.isFalse(isBasicTxType(0)); @@ -48,9 +52,25 @@ describe("util", () => { assert.isFalse(isBasicTxType(ty)); assert.isFalse(isFeeDelegationTxType(ty)); assert.isTrue(isPartialFeeDelegationTxType(ty)); + + assert.equal(parseTxType(), 0); + assert.equal(parseTxType(0), 0); + assert.equal(parseTxType(2), 2); + assert.equal(parseTxType(8), 8); + assert.equal(parseTxType("0x09"), 9); + assert.equal(parseTxType("FeeDelegatedValueTransferWithRatio"), 0x0a); + assert.equal(parseTxType("TxTypeValueTransferMemo"), 0x10); + assert.equal(parseTxType("SMART_CONTRACT_EXECUTION"), 0x30); + + assert.equal(getKaikasTxType(), 0); + assert.equal(getKaikasTxType(0), 0); + assert.equal(getKaikasTxType(2), 2); + assert.equal(getKaikasTxType(8), "VALUE_TRANSFER"); + assert.equal(getKaikasTxType("0x09"), "FEE_DELEGATED_VALUE_TRANSFER"); + assert.equal(getKaikasTxType("SMART_CONTRACT_EXECUTION"), "SMART_CONTRACT_EXECUTION"); }); - it.only("getCompressedPublicKey", () => { + it("getCompressedPublicKey", () => { const testcases = [ { x: "dc9dccbd788c00fa98f7f4082f2f714e799bc0c29d63f04d48b54fe6250453cd", y: "af06ca34ae8714cf3dae06bacdb78c7c2d4054bd38961d40853cd5f15955da79" }, { x: "0xdc9dccbd788c00fa98f7f4082f2f714e799bc0c29d63f04d48b54fe6250453cd", y: "0xaf06ca34ae8714cf3dae06bacdb78c7c2d4054bd38961d40853cd5f15955da79" }, @@ -88,11 +108,30 @@ describe("util", () => { ]; for (const tc of testcases) { - let tuple = getSignatureTuple(tc as any); + let tuple = getSignatureTuple(tc); assert.deepEqual(tuple, canonical); } }); + it("getChainIdFromSignatureTuples", () => { + const oddV = [ + [ + "0x7f5", + "0xe77a78c4a972f883e05df3a143a3b42cb08b8c082c3f7582f89e27c7062b6d2a", + "0x506da8080866d5a9ae40197917d0a5268a7bb5d33a3093b780c8134b55777ccf", + ], + ]; + const evenV = [ + [ + "0x7f6", + "0x3c72041cdb99c5d9902dd5784361e5fe91b205fa109db8b58097d8ed983e15f5", + "0x11716a098568b68eac778acf256bbbfececdff02478a620de696339ec86473a0", + ] + ]; + assert.equal(getChainIdFromSignatureTuples(oddV), 1001); + assert.equal(getChainIdFromSignatureTuples(evenV), 1001); + }); + it("getRpcTxObject", () => { let tx = { chainId: 42, @@ -221,7 +260,7 @@ describe("util", () => { //* // (3) Test mock const send = (_method: string, _params: any[]) => Promise.resolve("0x1234"); - //*/ + //* / // Uncomment to test with real OpenApi generated codes. /* // (1) @klaytn/web3rpc @@ -234,14 +273,15 @@ describe("util", () => { constructor(apiClient: any) { this.apiClient = apiClient; } + blockNumber(_opts: any, callback: any) { - const bodyParams = { method: 'klay_blockNumber', params: [] }; - this.apiClient.callApi('/', 'POST', null, null, null, null, bodyParams, - [], ['application/json'], ['application/json'], {}, null, callback); + const bodyParams = { method: "klay_blockNumber", params: [] }; + this.apiClient.callApi("/", "POST", null, null, null, null, bodyParams, + [], ["application/json"], ["application/json"], {}, null, callback); } - }; + } const KlayApi = MockKlayApi as any; - //*/ + //* / const klay = asyncOpenApi(send, KlayApi); const ret = await klay.blockNumber();