From 441476b42884cccf8baa72473842da77719c8ec1 Mon Sep 17 00:00:00 2001 From: Adam Carpenter Date: Thu, 7 Jul 2022 10:07:32 -0600 Subject: [PATCH 01/14] Preflight file setup needs cleanup --- packages/core/src/types.ts | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 0fa259bb9..29311536a 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -211,6 +211,37 @@ export interface UpdateNotification { } } +export interface PreflightEvent { + eventCode: string + contractCall?: ContractCall + balance: string + txDetails?: { + to?: string + from?: string + value: string | number + } + status?: string +} + +export interface ContractCall { + methodName: string + params: string[] +} + +export interface TransactionOptions { + sendTransaction?: () => Promise + estimateGas?: () => Promise + gasPrice?: () => Promise + balance?: string + contractCall?: ContractCall + txDetails?: { + to?: string + from?: string + value: string + } +} + + // ==== ACTIONS ==== // export type Action = | AddChainsAction From 00598c02e9c2b266dc5b8c6f99342e783208dc91 Mon Sep 17 00:00:00 2001 From: Adam Carpenter Date: Thu, 7 Jul 2022 10:07:38 -0600 Subject: [PATCH 02/14] Preflight file setup needs cleanup --- packages/core/src/preflight-notifications.ts | 300 +++++++++++++++++++ 1 file changed, 300 insertions(+) create mode 100644 packages/core/src/preflight-notifications.ts diff --git a/packages/core/src/preflight-notifications.ts b/packages/core/src/preflight-notifications.ts new file mode 100644 index 000000000..557d8665e --- /dev/null +++ b/packages/core/src/preflight-notifications.ts @@ -0,0 +1,300 @@ +import BigNumber from 'bignumber.js' +import { nanoid } from 'nanoid' +import { get } from 'svelte/store' + +import { transactions, app, notifications } from './stores' +import { transactionEventToNotification } from './notify' +import { argsEqual, localNetwork } from './utilities' + +import type { EthereumTransactionData } from 'bnc-sdk' + +import type { + PreflightEvent, + ContractCall, + TransactionOptions +} from './types' + +let transactionQueue: EthereumTransactionData[] +transactions.subscribe( + (store: EthereumTransactionData[]) => (transactionQueue = store) +) + +export function handlePreFlightEvent( + blocknative, + preflightEvent: PreflightEvent +) { + const { eventCode, contractCall, balance, txDetails, status } = preflightEvent + + let contract + + if (contractCall) { + contract = { + methodName: contractCall.methodName, + parameters: contractCall.params + } + } + + blocknative.event({ + categoryCode: contractCall ? 'activeContract' : 'activeTransaction', + eventCode, + transaction: txDetails, + wallet: { balance }, + contract: contractCall ? contract : undefined + }) + + const transaction = { + ...txDetails, + eventCode, + status, + contractCall: contract ? contractCall : undefined + } + + handleTransactionEvent({ + transaction: transaction + }) +} + +export function handleTransactionEvent(event) { + const { transaction, emitterResult } = event + const currentId = transaction.id + const transactionId = transaction.hash || transaction.txid + + // returns a boolean indicating whether this transaction state is a new state + // for an existing transaction or is a new transaction + const predicate = (txInState: EthereumTransactionData) => { + return ( + (txInState.id && txInState.id === currentId) || + txInState.hash === transaction.hash || + txInState.replaceHash === transaction.hash + ) + } + + // replace UUID used for pre-hash identitification with hash or txid(bitcoin) + if ( + (transactionId && + transactionId !== currentId && + transaction.eventCode === 'txSent') || + !currentId + ) { + transaction.id = transactionId + } + + transactions.updateQueue(transaction, predicate) + + if (transaction.replaceHash) { + // remove pending notification for replaceHash if exists, + // this happens is pending comes before speedup event + notifications.remove(transaction.replaceHash, 'txPool') + } + + // create notification if dev hasn't opted out and not connected to a local network + if (emitterResult !== false && !localNetwork(get(app).networkId)) { + const transactionObj = transactionQueue.find(predicate) + + if (transactionObj) { + transactionEventToNotification(transactionObj, emitterResult) + } + } +} + +export function duplicateTransactionCandidate( + transaction: EthereumTransactionData, + contract: ContractCall +) { + const duplicate: EthereumTransactionData | undefined | boolean = + transactionQueue.find((tx: EthereumTransactionData) => { + if (contract && typeof tx.contractCall === 'undefined') return false + if (tx.status === 'confirmed' || tx.status === 'failed') return + + const sameMethod = contract + ? contract.methodName === + (tx.contractCall && tx.contractCall.methodName) + : true + + const sameParams = contract + ? argsEqual(contract.params, tx.contractCall && tx.contractCall.params) + : true + + const sameVal = tx.value == transaction.value + + const sameTo = contract + ? sameMethod + : tx.to && + tx.to.toLowerCase() === transaction.to && + transaction.to.toLowerCase() + + return sameMethod && sameParams && sameVal && sameTo + }) + + return duplicate +} + +export function preflightTransaction( + blocknative, + options: TransactionOptions +): Promise { + return new Promise((resolve, reject) => { + // wrap in set timeout to put to the end of the event queue + + // Might not be necessary to timeout?? + // Instead call transactionHandler + setTimeout(async () => { + const { + sendTransaction, + estimateGas, + gasPrice, + balance, + contractCall, + txDetails + } = options + + // if `balance` or `estimateGas` or `gasPrice` is not provided, + // then sufficient funds check is disabled + // if `txDetails` is not provided, + // then duplicate transaction check is disabled + // if dev doesn't want notify to intiate the transaction + // and `sendTransaction` is not provided, then transaction + // rejected notification is disabled + // to disable hints for `txAwaitingApproval`, `txConfirmReminder` + // or any other notification, then return false from listener functions + + const [gas, price] = await gasEstimates(estimateGas, gasPrice) + const id = nanoid() + const value = new BigNumber((txDetails && txDetails.value) || 0) + + const calculated = { + value: value.toString(10), + gas: gas && gas.toString(10), + gasPrice: price && price.toString(10) + } + + const txObject = txDetails + ? { + ...txDetails, + ...calculated, + id + } + : { ...calculated, id } + + // check sufficient balance if required parameters are available + if (balance && gas && price) { + const transactionCost = gas.times(price).plus(value) + + // if transaction cost is greater than the current balance + if (transactionCost.gt(new BigNumber(balance))) { + const eventCode = 'nsfFail' + + handlePreFlightEvent(blocknative, { + eventCode, + contractCall, + balance, + txDetails: txObject + }) + + return reject('User has insufficient funds') + } + } + + // check if it is a duplicate transaction + if (txDetails && duplicateTransactionCandidate(txDetails, contractCall)) { + const eventCode = 'txRepeat' + + handlePreFlightEvent(blocknative, { + eventCode, + contractCall, + balance, + txDetails: txObject + }) + } + + const { + txApproveReminderTimeout + } = get(app) + + // check previous transactions awaiting approval + if (transactionQueue.find(tx => tx.status === 'awaitingApproval')) { + const eventCode = 'txAwaitingApproval' + + handlePreFlightEvent(blocknative, { + eventCode, + contractCall, + balance, + txDetails: txObject + }) + } + + // confirm reminder after timeout + setTimeout(() => { + const awaitingApproval = transactionQueue.find( + tx => tx.id === id && tx.status === 'awaitingApproval' + ) + + if (awaitingApproval) { + const eventCode = 'txConfirmReminder' + + handlePreFlightEvent(blocknative, { + eventCode, + contractCall, + balance, + txDetails: txObject + }) + } + }, txApproveReminderTimeout) + + handlePreFlightEvent(blocknative, { + eventCode: 'txRequest', + status: 'awaitingApproval', + contractCall, + balance, + txDetails: txObject + }) + + // if not provided with sendTransaction function, + // resolve with id so dev can initiate transaction + // dev will need to call notify.hash(txHash, id) with this id + // to link up the preflight with the postflight notifications + if (!sendTransaction) { + return resolve(id) + } + }, 10) + }) +} + +function gasEstimates( + gasFunc: () => Promise, + gasPriceFunc: () => Promise +) { + if (!gasFunc || !gasPriceFunc) { + return Promise.resolve([]) + } + + const gasProm = gasFunc() + if (!gasProm.then) { + throw new Error('The `estimateGas` function must return a Promise') + } + + const gasPriceProm = gasPriceFunc() + if (!gasPriceProm.then) { + throw new Error('The `gasPrice` function must return a Promise') + } + + return Promise.all([gasProm, gasPriceProm]) + .then(([gasResult, gasPriceResult]) => { + if (typeof gasResult !== 'string') { + throw new Error( + `The Promise returned from calling 'estimateGas' must resolve with a value of type 'string'. Received a value of: ${gasResult} with a type: ${typeof gasResult}` + ) + } + + if (typeof gasPriceResult !== 'string') { + throw new Error( + `The Promise returned from calling 'gasPrice' must resolve with a value of type 'string'. Received a value of: ${gasPriceResult} with a type: ${typeof gasPriceResult}` + ) + } + + return [new BigNumber(gasResult), new BigNumber(gasPriceResult)] + }) + .catch(error => { + throw new Error(`There was an error getting gas estimates: ${error}`) + }) +} From 363356c42c67257c7ad46048de09a60ac2c65c28 Mon Sep 17 00:00:00 2001 From: Adam Carpenter Date: Fri, 8 Jul 2022 11:06:18 -0600 Subject: [PATCH 03/14] Making progress --- packages/core/src/notify.ts | 2 - packages/core/src/preflight-notifications.ts | 316 ++++++-------- packages/core/src/types.ts | 20 - yarn.lock | 413 ++++++++----------- 4 files changed, 284 insertions(+), 467 deletions(-) diff --git a/packages/core/src/notify.ts b/packages/core/src/notify.ts index 31557c1b2..6e085efe0 100644 --- a/packages/core/src/notify.ts +++ b/packages/core/src/notify.ts @@ -139,8 +139,6 @@ export function eventToType(eventCode: string | undefined): NotificationType { case 'txRepeat': case 'txAwaitingApproval': case 'txConfirmReminder': - case 'txStallPending': - case 'txStallConfirmed': case 'txStuck': return 'hint' case 'txError': diff --git a/packages/core/src/preflight-notifications.ts b/packages/core/src/preflight-notifications.ts index 557d8665e..8a97545bc 100644 --- a/packages/core/src/preflight-notifications.ts +++ b/packages/core/src/preflight-notifications.ts @@ -1,158 +1,34 @@ import BigNumber from 'bignumber.js' import { nanoid } from 'nanoid' -import { get } from 'svelte/store' +import defaultCopy from './i18n/en.json' +import { addNotification, removeNotification } from './store/actions' -import { transactions, app, notifications } from './stores' -import { transactionEventToNotification } from './notify' -import { argsEqual, localNetwork } from './utilities' +import type { Network } from 'bnc-sdk' -import type { EthereumTransactionData } from 'bnc-sdk' +import type { Notification, TransactionOptions } from './types' +import { state } from './store' +import { eventToType } from './notify' +import { networkToChainId } from './utils' -import type { - PreflightEvent, - ContractCall, - TransactionOptions -} from './types' +const notifications = state.get().notifications -let transactionQueue: EthereumTransactionData[] -transactions.subscribe( - (store: EthereumTransactionData[]) => (transactionQueue = store) -) - -export function handlePreFlightEvent( - blocknative, - preflightEvent: PreflightEvent -) { - const { eventCode, contractCall, balance, txDetails, status } = preflightEvent - - let contract - - if (contractCall) { - contract = { - methodName: contractCall.methodName, - parameters: contractCall.params - } - } - - blocknative.event({ - categoryCode: contractCall ? 'activeContract' : 'activeTransaction', - eventCode, - transaction: txDetails, - wallet: { balance }, - contract: contractCall ? contract : undefined - }) - - const transaction = { - ...txDetails, - eventCode, - status, - contractCall: contract ? contractCall : undefined - } - - handleTransactionEvent({ - transaction: transaction - }) -} - -export function handleTransactionEvent(event) { - const { transaction, emitterResult } = event - const currentId = transaction.id - const transactionId = transaction.hash || transaction.txid - - // returns a boolean indicating whether this transaction state is a new state - // for an existing transaction or is a new transaction - const predicate = (txInState: EthereumTransactionData) => { - return ( - (txInState.id && txInState.id === currentId) || - txInState.hash === transaction.hash || - txInState.replaceHash === transaction.hash - ) - } - - // replace UUID used for pre-hash identitification with hash or txid(bitcoin) - if ( - (transactionId && - transactionId !== currentId && - transaction.eventCode === 'txSent') || - !currentId - ) { - transaction.id = transactionId - } - - transactions.updateQueue(transaction, predicate) - - if (transaction.replaceHash) { - // remove pending notification for replaceHash if exists, - // this happens is pending comes before speedup event - notifications.remove(transaction.replaceHash, 'txPool') - } - - // create notification if dev hasn't opted out and not connected to a local network - if (emitterResult !== false && !localNetwork(get(app).networkId)) { - const transactionObj = transactionQueue.find(predicate) - - if (transactionObj) { - transactionEventToNotification(transactionObj, emitterResult) - } - } -} - -export function duplicateTransactionCandidate( - transaction: EthereumTransactionData, - contract: ContractCall -) { - const duplicate: EthereumTransactionData | undefined | boolean = - transactionQueue.find((tx: EthereumTransactionData) => { - if (contract && typeof tx.contractCall === 'undefined') return false - if (tx.status === 'confirmed' || tx.status === 'failed') return - - const sameMethod = contract - ? contract.methodName === - (tx.contractCall && tx.contractCall.methodName) - : true - - const sameParams = contract - ? argsEqual(contract.params, tx.contractCall && tx.contractCall.params) - : true - - const sameVal = tx.value == transaction.value - - const sameTo = contract - ? sameMethod - : tx.to && - tx.to.toLowerCase() === transaction.to && - transaction.to.toLowerCase() - - return sameMethod && sameParams && sameVal && sameTo - }) - - return duplicate -} - -export function preflightTransaction( - blocknative, +export function preflightNotification( options: TransactionOptions -): Promise { +): Promise { return new Promise((resolve, reject) => { // wrap in set timeout to put to the end of the event queue // Might not be necessary to timeout?? // Instead call transactionHandler setTimeout(async () => { - const { - sendTransaction, - estimateGas, - gasPrice, - balance, - contractCall, - txDetails - } = options + const { sendTransaction, estimateGas, gasPrice, balance, txDetails } = + options // if `balance` or `estimateGas` or `gasPrice` is not provided, // then sufficient funds check is disabled // if `txDetails` is not provided, // then duplicate transaction check is disabled - // if dev doesn't want notify to intiate the transaction + // if dev doesn't want notify to initiate the transaction // and `sendTransaction` is not provided, then transaction // rejected notification is disabled // to disable hints for `txAwaitingApproval`, `txConfirmReminder` @@ -162,20 +38,6 @@ export function preflightTransaction( const id = nanoid() const value = new BigNumber((txDetails && txDetails.value) || 0) - const calculated = { - value: value.toString(10), - gas: gas && gas.toString(10), - gasPrice: price && price.toString(10) - } - - const txObject = txDetails - ? { - ...txDetails, - ...calculated, - id - } - : { ...calculated, id } - // check sufficient balance if required parameters are available if (balance && gas && price) { const transactionCost = gas.times(price).plus(value) @@ -184,82 +46,140 @@ export function preflightTransaction( if (transactionCost.gt(new BigNumber(balance))) { const eventCode = 'nsfFail' - handlePreFlightEvent(blocknative, { - eventCode, - contractCall, - balance, - txDetails: txObject - }) + const newNotification = buildNotification(eventCode, id) + addNotification(newNotification) return reject('User has insufficient funds') } } - // check if it is a duplicate transaction - if (txDetails && duplicateTransactionCandidate(txDetails, contractCall)) { - const eventCode = 'txRepeat' - - handlePreFlightEvent(blocknative, { - eventCode, - contractCall, - balance, - txDetails: txObject - }) - } - - const { - txApproveReminderTimeout - } = get(app) - // check previous transactions awaiting approval - if (transactionQueue.find(tx => tx.status === 'awaitingApproval')) { + if (notifications.find(tx => tx.eventCode === 'awaitingApproval')) { const eventCode = 'txAwaitingApproval' - handlePreFlightEvent(blocknative, { - eventCode, - contractCall, - balance, - txDetails: txObject - }) + const newNotification = buildNotification(eventCode, id) + addNotification(newNotification) } - // confirm reminder after timeout + // confirm reminder after 20 seconds timeout setTimeout(() => { - const awaitingApproval = transactionQueue.find( - tx => tx.id === id && tx.status === 'awaitingApproval' + const awaitingApproval = notifications.find( + tx => tx.id === id && tx.eventCode === 'awaitingApproval' ) if (awaitingApproval) { const eventCode = 'txConfirmReminder' - handlePreFlightEvent(blocknative, { - eventCode, - contractCall, - balance, - txDetails: txObject - }) + const newNotification = buildNotification(eventCode, id) + addNotification(newNotification) } - }, txApproveReminderTimeout) + }, 20000) - handlePreFlightEvent(blocknative, { - eventCode: 'txRequest', - status: 'awaitingApproval', - contractCall, - balance, - txDetails: txObject - }) + const eventCode = 'txRequest' + const newNotification = buildNotification(eventCode, id) + addNotification(newNotification) - // if not provided with sendTransaction function, + // if not provided with sendTransaction function, // resolve with id so dev can initiate transaction // dev will need to call notify.hash(txHash, id) with this id // to link up the preflight with the postflight notifications if (!sendTransaction) { return resolve(id) } + // get result and handle errors + let hash + try { + hash = await sendTransaction() + } catch (error) { + type CatchError = { + message: string + stack: string + } + const { eventCode, errorMsg } = extractMessageFromError( + error as CatchError + ) + + const newNotification = buildNotification(eventCode, id) + addNotification(newNotification) + + return reject(errorMsg) + } + + // Remove preflight notification if a resolves to hash + // and let the SDK take over + if (hash) { + removeNotification(id) + } + + reject( + 'sendTransaction function must resolve to a transaction hash that is of type String.' + ) }, 10) }) } +const buildNotification = (eventCode: string, id: string): Notification => { + return { + eventCode, + type: eventToType(eventCode), + id, + key: createKey(id, eventCode), + message: createMessageText(eventCode), + startTime: Date.now(), + network: Object.keys(networkToChainId).find( + key => networkToChainId[key] === state.get().chains[0].id + ) as Network, + autoDismiss: 0 + } +} + +const createKey = (id: string, eventCode: string): string => { + return `${id}-${eventCode}` +} + +const createMessageText = (eventCode: string): string => { + const notificationDefaultMessages = defaultCopy.notify + + const notificationMessageType = notificationDefaultMessages.transaction + + return notificationDefaultMessages.transaction[ + eventCode as keyof typeof notificationMessageType + ] +} + +export function extractMessageFromError(error: { + message: string + stack: string +}): { eventCode: string; errorMsg: string } { + if (!error.stack || !error.message) { + return { + eventCode: 'txError', + errorMsg: 'An unknown error occured' + } + } + + const message = error.stack || error.message + + if (message.includes('User denied transaction signature')) { + return { + eventCode: 'txSendFail', + errorMsg: 'User denied transaction signature' + } + } + + if (message.includes('transaction underpriced')) { + return { + eventCode: 'txUnderpriced', + errorMsg: 'Transaction is under priced' + } + } + + return { + eventCode: 'txError', + errorMsg: message + } +} + function gasEstimates( gasFunc: () => Promise, gasPriceFunc: () => Promise diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 85a612abb..0795b7ab9 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -207,32 +207,12 @@ export interface UpdateNotification { } } -export interface PreflightEvent { - eventCode: string - contractCall?: ContractCall - balance: string - txDetails?: { - to?: string - from?: string - value: string | number - } - status?: string -} - -export interface ContractCall { - methodName: string - params: string[] -} - export interface TransactionOptions { sendTransaction?: () => Promise estimateGas?: () => Promise gasPrice?: () => Promise balance?: string - contractCall?: ContractCall txDetails?: { - to?: string - from?: string value: string } } diff --git a/yarn.lock b/yarn.lock index b080882f8..5bf6f3a00 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1330,10 +1330,10 @@ resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== -"@sindresorhus/is@^0.14.0": - version "0.14.0" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" - integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== +"@sindresorhus/is@^4.0.0": + version "4.6.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f" + integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== "@socket.io/component-emitter@~3.1.0": version "3.1.0" @@ -1369,12 +1369,12 @@ superstruct "^0.14.2" tweetnacl "^1.0.0" -"@szmarczak/http-timer@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" - integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== +"@szmarczak/http-timer@^4.0.5": + version "4.0.6" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807" + integrity sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w== dependencies: - defer-to-connect "^1.0.1" + defer-to-connect "^2.0.0" "@toruslabs/base-controllers@^2.0.0", "@toruslabs/base-controllers@^2.0.2": version "2.0.2" @@ -1672,6 +1672,16 @@ dependencies: "@types/node" "*" +"@types/cacheable-request@^6.0.1": + version "6.0.2" + resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.2.tgz#c324da0197de0a98a2312156536ae262429ff6b9" + integrity sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA== + dependencies: + "@types/http-cache-semantics" "*" + "@types/keyv" "*" + "@types/node" "*" + "@types/responselike" "*" + "@types/connect-history-api-fallback@^1.3.5": version "1.3.5" resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz#d1f7a8a09d0ed5a57aee5ae9c18ab9b803205dae" @@ -1745,6 +1755,11 @@ "@types/minimatch" "*" "@types/node" "*" +"@types/http-cache-semantics@*": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz#0ea7b61496902b95890dc4c3a116b60cb8dae812" + integrity sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ== + "@types/http-proxy@^1.17.8": version "1.17.8" resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.8.tgz#968c66903e7e42b483608030ee85800f22d03f55" @@ -1772,11 +1787,23 @@ "@types/istanbul-lib-coverage" "*" "@types/istanbul-lib-report" "*" +"@types/json-buffer@~3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/json-buffer/-/json-buffer-3.0.0.tgz#85c1ff0f0948fc159810d4b5be35bf8c20875f64" + integrity sha512-3YP80IxxFJB4b5tYC2SUPwkg0XQLiu0nWvhRgEatgjf+29IcWO9X1k8xRv5DGssJ/lCrjYTjQPcobJr2yWIVuQ== + "@types/json-schema@*", "@types/json-schema@^7.0.7", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": version "7.0.9" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== +"@types/keyv@*": + version "3.1.4" + resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.4.tgz#3ccdb1c6751b0c7e52300bcdacd5bcbf8faa75b6" + integrity sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg== + dependencies: + "@types/node" "*" + "@types/ledgerhq__hw-transport-u2f@^4.21.2": version "4.21.2" resolved "https://registry.yarnpkg.com/@types/ledgerhq__hw-transport-u2f/-/ledgerhq__hw-transport-u2f-4.21.2.tgz#2e24c8b235f662177b6e9033c50258dcba1e4109" @@ -1906,6 +1933,13 @@ dependencies: "@types/node" "*" +"@types/responselike@*", "@types/responselike@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29" + integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA== + dependencies: + "@types/node" "*" + "@types/retry@^0.12.0": version "0.12.1" resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.1.tgz#d8f1c0d0dc23afad6dc16a9e993a0865774b4065" @@ -2421,6 +2455,15 @@ dependencies: "@walletconnect/window-getters" "^1.0.0" +"@web3-onboard/injected-wallets@^2.0.12": + version "2.0.12" + resolved "https://registry.yarnpkg.com/@web3-onboard/injected-wallets/-/injected-wallets-2.0.12.tgz#593cf6ec0fe1e2f57233e10795136cfd681c9bd5" + integrity sha512-viZebgwenIKRN/1q0A6Yq0euYxGmP7sPCPwjKQoTFQPcwKuR+kPkfLw1MnPkntxpC7Cyc5dS4/LsOqeEfSPFbQ== + dependencies: + "@web3-onboard/common" "^2.1.4" + joi "^17.4.2" + lodash.uniqby "^4.7.0" + "@web3auth/base-plugin@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@web3auth/base-plugin/-/base-plugin-1.0.1.tgz#1e2a87acf745299fdff6f92e6c46ee9bc38aa670" @@ -2889,25 +2932,10 @@ ansi-html-community@^0.0.8: resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= - -ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-regex@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" - integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== +ansi-regex@^2.0.0, ansi-regex@^4.1.0, ansi-regex@^4.1.1, ansi-regex@^5.0.1, ansi-regex@^6.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.1.tgz#164daac87ab2d6f6db3a29875e2d1766582dabed" + integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g== ansi-styles@^2.2.1: version "2.2.1" @@ -3049,15 +3077,10 @@ async-mutex@^0.3.2: dependencies: tslib "^2.3.1" -async@^1.4.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" - integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= - -async@^2.0.1, async@^2.1.2, async@^2.4.0, async@^2.5.0, async@^2.6.2: - version "2.6.3" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" - integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== +async@^1.4.2, async@^2.0.1, async@^2.1.2, async@^2.4.0, async@^2.5.0, async@^2.6.2, async@^2.6.4: + version "2.6.4" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221" + integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== dependencies: lodash "^4.17.14" @@ -3081,27 +3104,12 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== -axios@0.21.1: - version "0.21.1" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8" - integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA== - dependencies: - follow-redirects "^1.10.0" - -axios@^0.18.0: - version "0.18.1" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.18.1.tgz#ff3f0de2e7b5d180e757ad98000f1081b87bcea3" - integrity sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g== - dependencies: - follow-redirects "1.5.10" - is-buffer "^2.0.2" - -axios@^0.24.0: - version "0.24.0" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.24.0.tgz#804e6fa1e4b9c5288501dd9dff56a7a0940d20d6" - integrity sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA== +axios@0.21.1, axios@^0.18.0, axios@^0.21.2, axios@^0.24.0: + version "0.21.4" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" + integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== dependencies: - follow-redirects "^1.14.4" + follow-redirects "^1.14.0" babel-plugin-polyfill-corejs2@^0.3.0: version "0.3.1" @@ -3624,18 +3632,23 @@ bytes@3.1.2: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== -cacheable-request@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" - integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== +cacheable-lookup@^5.0.3: + version "5.0.4" + resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005" + integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA== + +cacheable-request@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.2.tgz#ea0d0b889364a25854757301ca12b2da77f91d27" + integrity sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew== dependencies: clone-response "^1.0.2" get-stream "^5.1.0" http-cache-semantics "^4.0.0" - keyv "^3.0.0" + keyv "^4.0.0" lowercase-keys "^2.0.0" - normalize-url "^4.1.0" - responselike "^1.0.2" + normalize-url "^6.0.1" + responselike "^2.0.0" call-bind@^1.0.0, call-bind@^1.0.2: version "1.0.2" @@ -3880,6 +3893,14 @@ component-inherit@0.0.3: resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143" integrity sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM= +compress-brotli@^1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/compress-brotli/-/compress-brotli-1.3.8.tgz#0c0a60c97a989145314ec381e84e26682e7b38db" + integrity sha512-lVcQsjhxhIXsuupfy9fmZUFtAIdBmXA7EGY6GBdgZ++qkM9zG4YFT8iU7FoBxzryNDMOpD1HIFHUSX4D87oqhQ== + dependencies: + "@types/json-buffer" "~3.0.0" + json-buffer "~3.0.1" + compressible@~2.0.16: version "2.0.18" resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" @@ -4200,7 +4221,7 @@ debug@2.6.9, debug@^2.2.0: dependencies: ms "2.0.0" -debug@3.1.0, debug@=3.1.0, debug@~3.1.0: +debug@3.1.0, debug@~3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== @@ -4238,13 +4259,20 @@ decode-uri-component@^0.2.0: resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= -decompress-response@^3.2.0, decompress-response@^3.3.0: +decompress-response@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= dependencies: mimic-response "^1.0.0" +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + deep-equal@^1.0.1: version "1.1.1" resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" @@ -4279,10 +4307,10 @@ default-gateway@^6.0.3: dependencies: execa "^5.0.0" -defer-to-connect@^1.0.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" - integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== +defer-to-connect@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" + integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== deferred-leveldown@~1.2.1: version "1.2.2" @@ -4454,11 +4482,6 @@ drbg.js@^1.0.1: create-hash "^1.1.2" create-hmac "^1.1.4" -duplexer3@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" - integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= - duplexify@^3.5.1: version "3.7.1" resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" @@ -5628,14 +5651,7 @@ flatted@^3.1.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== -follow-redirects@1.5.10: - version "1.5.10" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" - integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== - dependencies: - debug "=3.1.0" - -follow-redirects@^1.0.0, follow-redirects@^1.10.0, follow-redirects@^1.14.4: +follow-redirects@1.14.9, follow-redirects@^1.0.0, follow-redirects@^1.14.0: version "1.14.9" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.9.tgz#dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7" integrity sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w== @@ -5748,12 +5764,7 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: has "^1.0.3" has-symbols "^1.0.1" -get-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" - integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= - -get-stream@^4.0.0, get-stream@^4.1.0: +get-stream@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== @@ -5896,42 +5907,22 @@ google-protobuf@^3.15.8, google-protobuf@^3.7.0-rc.2: resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.19.4.tgz#8d32c3e34be9250956f28c0fb90955d13f311888" integrity sha512-OIPNCxsG2lkIvf+P5FNfJ/Km95CsXOBecS9ZcAU6m2Rq3svc0Apl9nB3GMDNKfQ9asNv4KjyAqGwPQFrVle3Yg== -got@9.6.0: - version "9.6.0" - resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" - integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== - dependencies: - "@sindresorhus/is" "^0.14.0" - "@szmarczak/http-timer" "^1.1.2" - cacheable-request "^6.0.0" - decompress-response "^3.3.0" - duplexer3 "^0.1.4" - get-stream "^4.1.0" - lowercase-keys "^1.0.1" - mimic-response "^1.0.1" - p-cancelable "^1.0.0" - to-readable-stream "^1.0.0" - url-parse-lax "^3.0.0" - -got@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a" - integrity sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw== - dependencies: - decompress-response "^3.2.0" - duplexer3 "^0.1.4" - get-stream "^3.0.0" - is-plain-obj "^1.1.0" - is-retry-allowed "^1.0.0" - is-stream "^1.0.0" - isurl "^1.0.0-alpha5" - lowercase-keys "^1.0.0" - p-cancelable "^0.3.0" - p-timeout "^1.1.1" - safe-buffer "^5.0.1" - timed-out "^4.0.0" - url-parse-lax "^1.0.0" - url-to-options "^1.0.1" +got@9.6.0, got@^11.8.5, got@^7.1.0: + version "11.8.5" + resolved "https://registry.yarnpkg.com/got/-/got-11.8.5.tgz#ce77d045136de56e8f024bebb82ea349bc730046" + integrity sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ== + dependencies: + "@sindresorhus/is" "^4.0.0" + "@szmarczak/http-timer" "^4.0.5" + "@types/cacheable-request" "^6.0.1" + "@types/responselike" "^1.0.0" + cacheable-lookup "^5.0.3" + cacheable-request "^7.0.2" + decompress-response "^6.0.0" + http2-wrapper "^1.0.0-beta.5.2" + lowercase-keys "^2.0.0" + p-cancelable "^2.0.0" + responselike "^2.0.0" graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: version "4.2.9" @@ -5993,23 +5984,11 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-symbol-support-x@^1.4.1: - version "1.4.2" - resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" - integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw== - has-symbols@^1.0.1, has-symbols@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== -has-to-string-tag-x@^1.2.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" - integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw== - dependencies: - has-symbol-support-x "^1.4.1" - has-tostringtag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" @@ -6161,6 +6140,14 @@ http-signature@~1.2.0: jsprim "^1.2.2" sshpk "^1.7.0" +http2-wrapper@^1.0.0-beta.5.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d" + integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg== + dependencies: + quick-lru "^5.1.1" + resolve-alpn "^1.0.0" + http@^0.0.1-security: version "0.0.1-security" resolved "https://registry.yarnpkg.com/http/-/http-0.0.1-security.tgz#3aac09129d12dc2747bbce4157afde20ad1f7995" @@ -6362,11 +6349,6 @@ is-boolean-object@^1.1.0: call-bind "^1.0.2" has-tostringtag "^1.0.0" -is-buffer@^2.0.2: - version "2.0.5" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" - integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== - is-callable@^1.1.4, is-callable@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" @@ -6472,11 +6454,6 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== -is-object@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.2.tgz#a56552e1c665c9e950b4a025461da87e72f86fcf" - integrity sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA== - is-path-cwd@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" @@ -6487,11 +6464,6 @@ is-path-inside@^3.0.2: resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== -is-plain-obj@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" - integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= - is-plain-obj@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" @@ -6519,17 +6491,12 @@ is-regex@^1.0.4, is-regex@^1.1.4: call-bind "^1.0.2" has-tostringtag "^1.0.0" -is-retry-allowed@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" - integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== - is-shared-array-buffer@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6" integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA== -is-stream@^1.0.0, is-stream@^1.1.0: +is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= @@ -6641,14 +6608,6 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= -isurl@^1.0.0-alpha5: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" - integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w== - dependencies: - has-to-string-tag-x "^1.2.0" - is-object "^1.0.1" - jayson@^3.4.4: version "3.6.6" resolved "https://registry.yarnpkg.com/jayson/-/jayson-3.6.6.tgz#189984f624e398f831bd2be8e8c80eb3abf764a1" @@ -6774,10 +6733,10 @@ jsesc@^2.5.1: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== -json-buffer@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" - integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= +json-buffer@3.0.1, json-buffer@~3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== json-parse-better-errors@^1.0.2: version "1.0.2" @@ -6895,12 +6854,13 @@ keccak@^3.0.0, keccak@^3.0.1, keccak@^3.0.2: node-gyp-build "^4.2.0" readable-stream "^3.6.0" -keyv@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" - integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== +keyv@^4.0.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.3.2.tgz#e839df676a0c7ee594c8835e7c1c83742558e5c2" + integrity sha512-kn8WmodVBe12lmHpA6W8OY7SNh6wVR+Z+wZESF4iF5FCazaVXGWOtnbnvX0tMQ1bO+/TmOD9LziuYMvrIIs0xw== dependencies: - json-buffer "3.0.0" + compress-brotli "^1.3.8" + json-buffer "3.0.1" keyvaluestorage-interface@^1.0.0: version "1.0.0" @@ -7102,11 +7062,6 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: dependencies: js-tokens "^3.0.0 || ^4.0.0" -lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" - integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== - lowercase-keys@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" @@ -7268,11 +7223,16 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -mimic-response@^1.0.0, mimic-response@^1.0.1: +mimic-response@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + min-document@^2.19.0: version "2.19.0" resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" @@ -7318,12 +7278,7 @@ minimatch@^3.0.4, minimatch@^3.1.1: dependencies: brace-expansion "^1.1.7" -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= - -minimist@^1.2.0, minimist@^1.2.5: +minimist@0.0.8, minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: version "1.2.6" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== @@ -7607,10 +7562,10 @@ normalize-path@^3.0.0, normalize-path@~3.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -normalize-url@^4.1.0: - version "4.5.1" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" - integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== +normalize-url@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" + integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== npm-bundled@^1.0.1: version "1.1.2" @@ -7817,15 +7772,10 @@ osenv@^0.1.4: os-homedir "^1.0.0" os-tmpdir "^1.0.0" -p-cancelable@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa" - integrity sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw== - -p-cancelable@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" - integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== +p-cancelable@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf" + integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg== p-finally@^1.0.0: version "1.0.0" @@ -7868,13 +7818,6 @@ p-retry@^4.5.0: "@types/retry" "^0.12.0" retry "^0.13.1" -p-timeout@^1.1.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386" - integrity sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y= - dependencies: - p-finally "^1.0.0" - p-try@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" @@ -8140,16 +8083,6 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= -prepend-http@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" - integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= - -prepend-http@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" - integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= - prettier-plugin-svelte@^2.4.0: version "2.6.0" resolved "https://registry.yarnpkg.com/prettier-plugin-svelte/-/prettier-plugin-svelte-2.6.0.tgz#0e845b560b55cd1d951d6c50431b4949f8591746" @@ -8372,6 +8305,11 @@ queue-microtask@^1.2.2, queue-microtask@^1.2.3: resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== +quick-lru@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" + integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== + randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -8633,6 +8571,11 @@ requires-port@^1.0.0: resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= +resolve-alpn@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9" + integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g== + resolve-cwd@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" @@ -8659,12 +8602,12 @@ resolve@^1.14.2, resolve@^1.17.0, resolve@^1.19.0, resolve@^1.9.0: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -responselike@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" - integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= +responselike@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.0.tgz#26391bcc3174f750f9a79eacc40a12a5c42d7723" + integrity sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw== dependencies: - lowercase-keys "^1.0.0" + lowercase-keys "^2.0.0" retry@^0.13.1: version "0.13.1" @@ -9693,7 +9636,7 @@ thunky@^1.0.2: resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== -timed-out@^4.0.0, timed-out@^4.0.1: +timed-out@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= @@ -9727,11 +9670,6 @@ to-fast-properties@^2.0.0: resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= -to-readable-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" - integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== - to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" @@ -9970,30 +9908,11 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -url-parse-lax@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" - integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM= - dependencies: - prepend-http "^1.0.1" - -url-parse-lax@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" - integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= - dependencies: - prepend-http "^2.0.0" - url-set-query@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/url-set-query/-/url-set-query-1.0.0.tgz#016e8cfd7c20ee05cafe7795e892bd0702faa339" integrity sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk= -url-to-options@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" - integrity sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k= - url@^0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" From 2e395407a4ca430f054e214a8ed5284f11440690 Mon Sep 17 00:00:00 2001 From: Adam Carpenter Date: Fri, 8 Jul 2022 12:37:53 -0600 Subject: [PATCH 04/14] More progress --- packages/core/src/preflight-notifications.ts | 183 +++++++++---------- packages/core/src/types.ts | 2 - 2 files changed, 86 insertions(+), 99 deletions(-) diff --git a/packages/core/src/preflight-notifications.ts b/packages/core/src/preflight-notifications.ts index 8a97545bc..e2b3e2188 100644 --- a/packages/core/src/preflight-notifications.ts +++ b/packages/core/src/preflight-notifications.ts @@ -1,121 +1,110 @@ import BigNumber from 'bignumber.js' import { nanoid } from 'nanoid' import defaultCopy from './i18n/en.json' -import { addNotification, removeNotification } from './store/actions' - import type { Network } from 'bnc-sdk' import type { Notification, TransactionOptions } from './types' +import { addNotification, removeNotification } from './store/actions' import { state } from './store' import { eventToType } from './notify' import { networkToChainId } from './utils' const notifications = state.get().notifications -export function preflightNotification( +export async function preflightNotification( options: TransactionOptions -): Promise { - return new Promise((resolve, reject) => { - // wrap in set timeout to put to the end of the event queue - - // Might not be necessary to timeout?? - // Instead call transactionHandler - setTimeout(async () => { - const { sendTransaction, estimateGas, gasPrice, balance, txDetails } = - options - - // if `balance` or `estimateGas` or `gasPrice` is not provided, - // then sufficient funds check is disabled - // if `txDetails` is not provided, - // then duplicate transaction check is disabled - // if dev doesn't want notify to initiate the transaction - // and `sendTransaction` is not provided, then transaction - // rejected notification is disabled - // to disable hints for `txAwaitingApproval`, `txConfirmReminder` - // or any other notification, then return false from listener functions - - const [gas, price] = await gasEstimates(estimateGas, gasPrice) - const id = nanoid() - const value = new BigNumber((txDetails && txDetails.value) || 0) - - // check sufficient balance if required parameters are available - if (balance && gas && price) { - const transactionCost = gas.times(price).plus(value) - - // if transaction cost is greater than the current balance - if (transactionCost.gt(new BigNumber(balance))) { - const eventCode = 'nsfFail' - - const newNotification = buildNotification(eventCode, id) - addNotification(newNotification) - - return reject('User has insufficient funds') - } - } - - // check previous transactions awaiting approval - if (notifications.find(tx => tx.eventCode === 'awaitingApproval')) { - const eventCode = 'txAwaitingApproval' - - const newNotification = buildNotification(eventCode, id) - addNotification(newNotification) - } +): Promise { + const { sendTransaction, estimateGas, gasPrice, balance, txDetails } = options + + // if `balance` or `estimateGas` or `gasPrice` is not provided, + // then sufficient funds check is disabled + // if `txDetails` is not provided, + // then duplicate transaction check is disabled + // if dev doesn't want notify to initiate the transaction + // and `sendTransaction` is not provided, then transaction + // rejected notification is disabled + // to disable hints for `txAwaitingApproval`, `txConfirmReminder` + // or any other notification, then return false from listener functions + + const [gas, price] = await gasEstimates(estimateGas, gasPrice) + const id = nanoid() + const value = new BigNumber((txDetails && txDetails.value) || 0) + + // check sufficient balance if required parameters are available + if (balance && gas && price) { + const transactionCost = gas.times(price).plus(value) + + // if transaction cost is greater than the current balance + if (transactionCost.gt(new BigNumber(balance))) { + const eventCode = 'nsfFail' - // confirm reminder after 20 seconds timeout - setTimeout(() => { - const awaitingApproval = notifications.find( - tx => tx.id === id && tx.eventCode === 'awaitingApproval' - ) + const newNotification = buildNotification(eventCode, id) + addNotification(newNotification) + } + } - if (awaitingApproval) { - const eventCode = 'txConfirmReminder' + // awaiting approval reminder after 15 seconds timeout + setTimeout(() => { + const txRequested = notifications.find( + tx => tx.id === id && tx.eventCode === 'txRequest' + ) - const newNotification = buildNotification(eventCode, id) - addNotification(newNotification) - } - }, 20000) + if (txRequested) { + const eventCode = 'txAwaitingApproval' - const eventCode = 'txRequest' - const newNotification = buildNotification(eventCode, id) + const newNotification = buildNotification(eventCode, txRequested.id) addNotification(newNotification) + } + }, 15000) - // if not provided with sendTransaction function, - // resolve with id so dev can initiate transaction - // dev will need to call notify.hash(txHash, id) with this id - // to link up the preflight with the postflight notifications - if (!sendTransaction) { - return resolve(id) - } - // get result and handle errors - let hash - try { - hash = await sendTransaction() - } catch (error) { - type CatchError = { - message: string - stack: string - } - const { eventCode, errorMsg } = extractMessageFromError( - error as CatchError - ) + // confirm reminder after 30 seconds timeout + setTimeout(() => { + const awaitingApproval = notifications.find( + tx => tx.id === id && tx.eventCode === 'awaitingApproval' + ) - const newNotification = buildNotification(eventCode, id) - addNotification(newNotification) + if (awaitingApproval) { + const eventCode = 'txConfirmReminder' - return reject(errorMsg) - } + const newNotification = buildNotification(eventCode, awaitingApproval.id) + addNotification(newNotification) + } + }, 30000) + + const eventCode = 'txRequest' + const newNotification = buildNotification(eventCode, id) + addNotification(newNotification) + + // if not provided with sendTransaction function, + // resolve with id so dev can initiate transaction + // dev will need to call notify.hash(txHash, id) with this id + // to link up the preflight with the postflight notifications + if (!sendTransaction) { + return id + } + // get result and handle errors + let hash + try { + hash = await sendTransaction() + } catch (error) { + type CatchError = { + message: string + stack: string + } + const { eventCode, errorMsg } = extractMessageFromError(error as CatchError) - // Remove preflight notification if a resolves to hash - // and let the SDK take over - if (hash) { - removeNotification(id) - } + const newNotification = buildNotification(eventCode, id) + addNotification(newNotification) + console.error(errorMsg) + return + } - reject( - 'sendTransaction function must resolve to a transaction hash that is of type String.' - ) - }, 10) - }) + // Remove preflight notification if a resolves to hash + // and let the SDK take over + if (hash) { + removeNotification(id) + return hash + } } const buildNotification = (eventCode: string, id: string): Notification => { @@ -180,10 +169,10 @@ export function extractMessageFromError(error: { } } -function gasEstimates( +const gasEstimates = async ( gasFunc: () => Promise, gasPriceFunc: () => Promise -) { +) => { if (!gasFunc || !gasPriceFunc) { return Promise.resolve([]) } diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 561145397..d58957585 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -138,7 +138,6 @@ export type NotificationPosition = CommonPositions export type AccountCenter = { enabled: boolean position?: AccountCenterPosition - containerElement?: string expanded?: boolean minimal?: boolean } @@ -218,7 +217,6 @@ export interface TransactionOptions { } } - // ==== ACTIONS ==== // export type Action = | AddChainsAction From eee7cd5abf2ac262e31e293d0e57e4f148f9ad2d Mon Sep 17 00:00:00 2001 From: Adam Carpenter Date: Fri, 8 Jul 2022 15:59:02 -0600 Subject: [PATCH 05/14] Its working! --- packages/core/package.json | 4 +- packages/core/src/index.ts | 2 + packages/core/src/preflight-notifications.ts | 64 +++++++++++++------ packages/core/src/types.ts | 2 + packages/core/src/validation.ts | 3 +- .../views/notify/NotificationContent.svelte | 2 +- packages/demo/package.json | 2 +- packages/demo/src/App.svelte | 45 ++++++++++++- 8 files changed, 98 insertions(+), 26 deletions(-) diff --git a/packages/core/package.json b/packages/core/package.json index 671aa254c..8d95c7e68 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,7 +1,7 @@ { "name": "@web3-onboard/core", - "version": "2.4.0-alpha.7", - "description": "Web3-Onboard makes it simple to connect Ethereum hardware and software wallets to your dapp. Features standardised spec compliant web3 providers for all supported wallets, framework agnostic modern javascript UI with code splitting, CSS customization, multi-chain and multi-account support, reactive wallet state subscriptions and real-time transaction state change notifications.", + "version": "2.4.0-alpha.8", + "description": "Web3-Onboard makes it simple to connect Ethereum hardware and software wallets to your dapp. Features standardized spec compliant web3 providers for all supported wallets, framework agnostic modern javascript UI with code splitting, CSS customization, multi-chain and multi-account support, reactive wallet state subscriptions and real-time transaction state change notifications.", "keywords": [ "Ethereum", "Web3", diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index ad692c4bd..02145ff1b 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -26,6 +26,7 @@ import { } from './store/actions' import updateBalances from './update-balances' +import { preflightNotification } from './preflight-notifications' const API = { connectWallet, @@ -39,6 +40,7 @@ const API = { setLocale, updateNotify, customNotification, + preflightNotification, updateBalances, updateAccountCenter, setPrimaryWallet diff --git a/packages/core/src/preflight-notifications.ts b/packages/core/src/preflight-notifications.ts index e2b3e2188..bbf0a722c 100644 --- a/packages/core/src/preflight-notifications.ts +++ b/packages/core/src/preflight-notifications.ts @@ -8,13 +8,39 @@ import { addNotification, removeNotification } from './store/actions' import { state } from './store' import { eventToType } from './notify' import { networkToChainId } from './utils' +import { configuration } from './configuration' -const notifications = state.get().notifications +let notificationsArr: Notification[] +state.select('notifications').subscribe(notifications => { + notificationsArr = notifications +}) export async function preflightNotification( options: TransactionOptions -): Promise { - const { sendTransaction, estimateGas, gasPrice, balance, txDetails } = options +): Promise | null { + const { apiKey } = configuration + + if (!apiKey) { + console.error( + 'An API key is required to use this feature - head to https://explorer.blocknative.com/account for a free key' + ) + return null + } + + const { + sendTransaction, + estimateGas, + gasPrice, + balance, + txDetails, + txApproveReminderTimeout + } = options + + // Check for reminder timeout and confirm its greater than 3 seconds + const reminderTimeout: number = + txApproveReminderTimeout && txApproveReminderTimeout > 3000 + ? txApproveReminderTimeout + : 15000 // if `balance` or `estimateGas` or `gasPrice` is not provided, // then sufficient funds check is disabled @@ -27,7 +53,7 @@ export async function preflightNotification( // or any other notification, then return false from listener functions const [gas, price] = await gasEstimates(estimateGas, gasPrice) - const id = nanoid() + const id = createId(nanoid()) const value = new BigNumber((txDetails && txDetails.value) || 0) // check sufficient balance if required parameters are available @@ -43,24 +69,20 @@ export async function preflightNotification( } } - // awaiting approval reminder after 15 seconds timeout - setTimeout(() => { - const txRequested = notifications.find( - tx => tx.id === id && tx.eventCode === 'txRequest' - ) + // check previous transactions awaiting approval + const txRequested = notificationsArr.find(tx => tx.eventCode === 'txRequest') - if (txRequested) { - const eventCode = 'txAwaitingApproval' + if (txRequested) { + const eventCode = 'txAwaitingApproval' - const newNotification = buildNotification(eventCode, txRequested.id) - addNotification(newNotification) - } - }, 15000) + const newNotification = buildNotification(eventCode, txRequested.id) + addNotification(newNotification) + } - // confirm reminder after 30 seconds timeout + // confirm reminder timeout defaults to 20 seconds setTimeout(() => { - const awaitingApproval = notifications.find( - tx => tx.id === id && tx.eventCode === 'awaitingApproval' + const awaitingApproval = notificationsArr.find( + tx => tx.id === id && tx.eventCode === 'txRequest' ) if (awaitingApproval) { @@ -69,7 +91,7 @@ export async function preflightNotification( const newNotification = buildNotification(eventCode, awaitingApproval.id) addNotification(newNotification) } - }, 30000) + }, reminderTimeout) const eventCode = 'txRequest' const newNotification = buildNotification(eventCode, id) @@ -126,6 +148,10 @@ const createKey = (id: string, eventCode: string): string => { return `${id}-${eventCode}` } +const createId = (id: string): string => { + return `${id}-preflight` +} + const createMessageText = (eventCode: string): string => { const notificationDefaultMessages = defaultCopy.notify diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index d58957585..2321e6d17 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -140,6 +140,7 @@ export type AccountCenter = { position?: AccountCenterPosition expanded?: boolean minimal?: boolean + containerElement: string } export type AccountCenterOptions = { @@ -215,6 +216,7 @@ export interface TransactionOptions { txDetails?: { value: string } + txApproveReminderTimeout?: number } // ==== ACTIONS ==== // diff --git a/packages/core/src/validation.ts b/packages/core/src/validation.ts index dd5223365..2a208f1f8 100644 --- a/packages/core/src/validation.ts +++ b/packages/core/src/validation.ts @@ -198,7 +198,8 @@ const accountCenter = Joi.object({ enabled: Joi.boolean(), position: commonPositions, expanded: Joi.boolean(), - minimal: Joi.boolean() + minimal: Joi.boolean(), + containerElement: Joi.string() }) const customNotificationUpdate = Joi.object({ diff --git a/packages/core/src/views/notify/NotificationContent.svelte b/packages/core/src/views/notify/NotificationContent.svelte index 7eb65a688..851dd6bfc 100644 --- a/packages/core/src/views/notify/NotificationContent.svelte +++ b/packages/core/src/views/notify/NotificationContent.svelte @@ -74,7 +74,7 @@ {notification.message} - {#if notification.id && !notification.id.includes('customNotification')} + {#if notification.id && (!notification.id.includes('customNotification') && !notification.id.includes('preflight') )} {#if notification.link} { + const ethersProvider = new ethers.providers.Web3Provider(provider, 'any') + + const signer = ethersProvider.getSigner() + const txDetails = { + to: toAddress, + value: 100000000000000 + } + + const sendTransaction = () => { + return signer.sendTransaction(txDetails).then(tx => tx.hash) + } + + const gasPrice = () => ethersProvider.getGasPrice().then(res => res.toString()) + + const estimateGas = () => { + return ethersProvider.estimateGas(txDetails).then(res => res.toString()) + } + + const receipt = await onboard.state.actions.preflightNotification({ + sendTransaction, + gasPrice, + estimateGas, + balance, + txDetails + }) + + console.log(receipt) + } + const signMessage = async (provider, address) => { const ethersProvider = new ethers.providers.Web3Provider(provider, 'any') @@ -477,6 +507,17 @@ Send Transaction +
+ + +