From 1f62d8630384f4620baabba1e456395544735dba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Brzezin=CC=81ski?= Date: Fri, 12 Jan 2024 23:05:25 +0100 Subject: [PATCH] complitly refactor trnasaction confirmation --- package.json | 4 +- src/globalTypes.ts | 2 +- src/transactions.ts | 258 ++++++++++++++++++++++++++++---------------- yarn.lock | 132 +++++++++++++---------- 4 files changed, 244 insertions(+), 152 deletions(-) diff --git a/package.json b/package.json index 78f8688..635c848 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@blockworks-foundation/mangolana", - "version": "0.0.1-beta.16", + "version": "0.0.2", "description": "", "main": "lib/index.js", "types": "lib/index.d.ts", @@ -30,7 +30,7 @@ }, "homepage": "https://github.com/blockworks-foundation/mangolana#readme", "dependencies": { - "@solana/web3.js": "^1.63.1", + "@solana/web3.js": "^1.88.0", "bs58": "^5.0.0", "node-fetch": "^3.2.10" }, diff --git a/src/globalTypes.ts b/src/globalTypes.ts index 852cb0f..cc91411 100644 --- a/src/globalTypes.ts +++ b/src/globalTypes.ts @@ -56,7 +56,7 @@ export class BlockHeightStrategyClass implements BlockHeightStrategy { block: BlockhashWithExpiryBlockHeight; getSignatureStatusesPoolIntervalMs: number; constructor({ - startBlockCheckAfterSecs = 90, + startBlockCheckAfterSecs = 10, block, getSignatureStatusesPoolIntervalMs = 5000, }: { diff --git a/src/transactions.ts b/src/transactions.ts index 5f166cd..15dcae4 100644 --- a/src/transactions.ts +++ b/src/transactions.ts @@ -3,6 +3,7 @@ import { Connection, Keypair, RpcResponseAndContext, + SignatureResult, SignatureStatus, SimulatedTransactionResponse, Transaction, @@ -17,10 +18,16 @@ import { getTimeoutConfig, SequenceType, TimeStrategy, + TimeStrategyClass, TransactionInstructionWithSigners, WalletSigner, } from './globalTypes'; +enum ConfirmationReject { + Timeout = 'Timeout', + Aborted = 'Aborted', +} + export interface TransactionInstructionWithType { instructionsSet: TransactionInstructionWithSigners[]; sequenceType?: SequenceType; @@ -39,6 +46,7 @@ export type awaitTransactionSignatureConfirmationProps = { config?: { logFlowInfo?: boolean; }; + abortSignal?: AbortSignal; }; /** * waits for transaction confirmation @@ -63,115 +71,185 @@ export const awaitTransactionSignatureConfirmation = async ({ connection, timeoutStrategy, config, + abortSignal, }: awaitTransactionSignatureConfirmationProps) => { + const abortController = new AbortController(); const logger = new Logger({ ...config }); const timeoutConfig = getTimeoutConfig(timeoutStrategy); - let timeoutBlockHeight = 0; - let timeout = 0; - if (timeoutConfig instanceof BlockHeightStrategyClass) { - timeoutBlockHeight = timeoutConfig.block.lastValidBlockHeight + MAXIMUM_NUMBER_OF_BLOCKS_FOR_TRANSACTION; - timeout = timeoutConfig.startBlockCheckAfterSecs; - } else { - timeout = timeoutConfig.timeout; - } - let startTimeoutCheck = false; - let done = false; - const confirmLevels: (TransactionConfirmationStatus | null | undefined)[] = ['finalized']; + const confirmLevels: TransactionConfirmationStatus[] = ['finalized']; if (confirmLevel === 'confirmed') { confirmLevels.push('confirmed'); } else if (confirmLevel === 'processed') { confirmLevels.push('confirmed'); confirmLevels.push('processed'); } - let subscriptionId: number | undefined; + try { + const result: RpcResponseAndContext = await Promise.race([ + confirmWithSignatureStatuses( + txid, + connection, + confirmLevels, + logger, + timeoutConfig, + abortController.signal, + abortSignal, + ), + confirmWithWebSockets(txid, connection, confirmLevel, logger, abortController.signal, abortSignal), + timeoutCheck(txid, timeoutConfig, logger, connection, confirmLevel, abortController.signal, abortSignal), + ]); + return result; + } catch (e) { + abortController.abort(); + logger.log('await transaction error', e); + throw e; + } +}; - const result = await new Promise((resolve, reject) => { - (async () => { - setTimeout(() => { - if (done) { - return; - } - if (timeoutBlockHeight !== 0) { - startTimeoutCheck = true; +const confirmWithSignatureStatuses = ( + txid: string, + connection: Connection, + confirmLevels: TransactionConfirmationStatus[], + logger: Logger, + timeoutConfig: TimeStrategyClass | BlockHeightStrategyClass, + internalSignal: AbortSignal, + externalSignal?: AbortSignal, +) => { + return new Promise>(async (resolve, reject) => { + let intervalTimeout: NodeJS.Timer | null = null; + const retryTimer = timeoutConfig.getSignatureStatusesPoolIntervalMs || 5000; + const onAbort = () => { + if (intervalTimeout) { + clearInterval(intervalTimeout); + } + + reject(ConfirmationReject.Aborted); + }; + internalSignal.addEventListener('abort', onAbort); + externalSignal?.addEventListener('abort', onAbort); + + intervalTimeout = setInterval(async () => { + try { + const result = await connection.getSignatureStatus(txid); + if (!result) return; + + if (result.value?.err) { + logger.log('REST error for', txid, result); + reject({ value: result.value, context: result.context }); + } else if ( + !( + result.value!.confirmations || + (result.value!.confirmationStatus && confirmLevels.includes(result.value!.confirmationStatus)) + ) + ) { + logger.log('REST not confirmed', txid, result); } else { - done = true; - logger.log('Timed out for txid: ', txid); - reject({ timeout: true }); + logger.log('REST confirmed', txid, result); + resolve({ value: result.value!, context: result.context }); } - }, timeout); - try { - subscriptionId = connection.onSignature( - txid, - (result, context) => { - subscriptionId = undefined; - done = true; - if (result.err) { - reject(result.err); - } else { - resolve(result); - } - }, - confirmLevel, - ); } catch (e) { - done = true; - logger.log('WS error in setup', txid, e); + logger.log('REST connection error: txid', txid, e); } - const retrySleep = timeoutConfig.getSignatureStatusesPoolIntervalMs || 5000; - while (!done) { - // eslint-disable-next-line no-loop-func - await sleep(retrySleep); - (async () => { - try { - const promises: [Promise>, Promise?] = [ - connection.getSignatureStatuses([txid]), - ]; - //if startTimeoutThreshold passed we start to check if - //current blocks are did not passed timeoutBlockHeight threshold - if (startTimeoutCheck) { - promises.push(connection.getBlockHeight('confirmed')); - } - const [signatureStatuses, currentBlockHeight] = await Promise.all(promises); - if (typeof currentBlockHeight !== undefined && timeoutBlockHeight <= currentBlockHeight!) { - logger.log('Timed out for txid: ', txid); - done = true; - reject({ timeout: true }); - } + }, retryTimer); + }); +}; - const result = signatureStatuses && signatureStatuses.value[0]; - if (!done) { - if (!result) return; - if (result.err) { - logger.log('REST error for', txid, result); - done = true; - reject(result.err); - } else if (!(result.confirmations || confirmLevels.includes(result.confirmationStatus))) { - logger.log('REST not confirmed', txid, result); - } else { - logger.log('REST confirmed', txid, result); - done = true; - resolve(result); - } - } - } catch (e) { - if (!done) { - logger.log('REST connection error: txid', txid, e); +const confirmWithWebSockets = ( + txid: string, + connection: Connection, + confirmLevel: TransactionConfirmationStatus, + logger: Logger, + internalSignal: AbortSignal, + externalSignal?: AbortSignal, +) => { + return new Promise>(async (resolve, reject) => { + let subscriptionId: number | undefined; + const onAbort = () => { + if (subscriptionId) { + connection.removeSignatureListener(subscriptionId).catch((e) => { + logger.log('WS error in cleanup', e); + }); + } + reject(ConfirmationReject.Aborted); + }; + internalSignal.addEventListener('abort', onAbort); + externalSignal?.addEventListener('abort', onAbort); + try { + logger.log('on signature', connection); + subscriptionId = connection.onSignature( + txid, + (result, context) => { + subscriptionId = undefined; + if (result.err) { + reject({ value: result, context }); + } else { + //@ts-ignore + resolve({ value: result, context }); + } + }, + confirmLevel, + ); + } catch (e) { + logger.log('WS error in setup', txid, e); + } + if (subscriptionId) { + connection.removeSignatureListener(subscriptionId).catch((e) => { + logger.log('WS error in cleanup', e); + }); + } + }); +}; + +const timeoutCheck = ( + txid: string, + timeoutConfig: TimeStrategyClass | BlockHeightStrategyClass, + logger: Logger, + connection: Connection, + confirmLevel: TransactionConfirmationStatus, + internalSignal: AbortSignal, + externalSignal?: AbortSignal, +) => { + return new Promise>(async (resolve, reject) => { + let intervalTimer: NodeJS.Timeout | null = null; + let setTimeoutTimer: NodeJS.Timeout | null = null; + let timeoutBlockHeight = 0; + let timeout = 0; + if (timeoutConfig instanceof BlockHeightStrategyClass) { + timeoutBlockHeight = timeoutConfig.block.lastValidBlockHeight; + timeout = timeoutConfig.startBlockCheckAfterSecs; + } else { + timeout = timeoutConfig.timeout; + } + const onAbort = () => { + if (intervalTimer) { + clearInterval(intervalTimer); + } + if (setTimeoutTimer) { + clearTimeout(setTimeoutTimer); + } + reject(ConfirmationReject.Aborted); + }; + internalSignal.addEventListener('abort', onAbort); + externalSignal?.addEventListener('abort', onAbort); + const retrySleep = timeoutConfig.getSignatureStatusesPoolIntervalMs || 5000; + setTimeoutTimer = setTimeout(async () => { + if (timeoutBlockHeight !== 0) { + intervalTimer = setInterval(async () => { + const currentBlockHeight = await connection.getBlockHeight(confirmLevel); + if (typeof currentBlockHeight !== undefined && timeoutBlockHeight <= currentBlockHeight!) { + logger.log('Timed out for txid: ', txid); + if (intervalTimer) { + clearInterval(intervalTimer); } + reject(ConfirmationReject.Timeout); } - })(); + }, retrySleep); + } else { + logger.log('Timed out for txid: ', txid); + reject(ConfirmationReject.Timeout); } - })(); + }, timeout); }); - - if (subscriptionId) { - connection.removeSignatureListener(subscriptionId).catch((e) => { - logger.log('WS error in cleanup', e); - }); - } - - done = true; - return result; }; export type sendAndConfirmSignedTransactionProps = { @@ -273,7 +351,7 @@ export const sendAndConfirmSignedTransaction = async ({ } } catch (err: any) { logger.log(err); - if (err.timeout) { + if (err === 'Timeout') { throw { txid }; } let simulateResult: SimulatedTransactionResponse | null = null; diff --git a/yarn.lock b/yarn.lock index 0927f2d..69c930c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -23,54 +23,58 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/runtime@^7.12.5", "@babel/runtime@^7.17.2": +"@babel/runtime@^7.17.2": version "7.19.4" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.19.4.tgz#a42f814502ee467d55b38dd1c256f53a7b885c78" integrity sha512-EXpLCrk55f+cYqmHsSR+yD/0gAIMxxA9QK9lnQWzhMCvt+YmoBN7Zx94s++Kv0+unHk39vxNO8t+CMA2WSS3wA== dependencies: regenerator-runtime "^0.13.4" -"@noble/ed25519@^1.7.0": - version "1.7.1" - resolved "https://registry.yarnpkg.com/@noble/ed25519/-/ed25519-1.7.1.tgz#6899660f6fbb97798a6fbd227227c4589a454724" - integrity sha512-Rk4SkJFaXZiznFyC/t77Q0NKS4FL7TLJJsVG2V2oiEq3kJVeTdxysEe/yRWSpnWMe808XRDJ+VFh5pt/FN5plw== +"@babel/runtime@^7.23.4": + version "7.23.8" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.8.tgz#8ee6fe1ac47add7122902f257b8ddf55c898f650" + integrity sha512-Y7KbAP984rn1VGMbGqKmBLio9V7y5Je9GvU4rQPCPinCyNfUcToxIXl06d59URp/F3LwinvODxab5N/G6qggkw== + dependencies: + regenerator-runtime "^0.14.0" -"@noble/hashes@^1.1.2": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.3.tgz#360afc77610e0a61f3417e497dcf36862e4f8111" - integrity sha512-CE0FCR57H2acVI5UOzIGSSIYxZ6v/HOhDR0Ro9VLyhnzLwx0o8W1mmgaqlEUx4049qJDlIBRztv5k+MM8vbO3A== +"@noble/curves@^1.2.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.3.0.tgz#01be46da4fd195822dab821e72f71bf4aeec635e" + integrity sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA== + dependencies: + "@noble/hashes" "1.3.3" -"@noble/secp256k1@^1.6.3": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.0.tgz#d15357f7c227e751d90aa06b05a0e5cf993ba8c1" - integrity sha512-kbacwGSsH/CTout0ZnZWxnW1B+jH/7r/WAAKLBtrRJ/+CUH7lgmQzl3GTrQua3SGKWNSDsS6lmjnDpIJ5Dxyaw== +"@noble/hashes@1.3.3", "@noble/hashes@^1.3.2": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.3.tgz#39908da56a4adc270147bb07968bf3b16cfe1699" + integrity sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA== -"@solana/buffer-layout@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@solana/buffer-layout/-/buffer-layout-4.0.0.tgz#75b1b11adc487234821c81dfae3119b73a5fd734" - integrity sha512-lR0EMP2HC3+Mxwd4YcnZb0smnaDw7Bl2IQWZiTevRH5ZZBZn6VRWn3/92E3qdU4SSImJkA6IDHawOHAnx/qUvQ== +"@solana/buffer-layout@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz#b996235eaec15b1e0b5092a8ed6028df77fa6c15" + integrity sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA== dependencies: buffer "~6.0.3" -"@solana/web3.js@^1.63.1": - version "1.63.1" - resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.63.1.tgz#88a19a17f5f4aada73ad70a94044c1067cab2b4d" - integrity sha512-wgEdGVK5FTS2zENxbcGSvKpGZ0jDS6BUdGu8Gn6ns0CzgJkK83u4ip3THSnBPEQ5i/jrqukg998BwV1H67+qiQ== +"@solana/web3.js@^1.88.0": + version "1.88.0" + resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.88.0.tgz#24e1482f63ac54914430b4ce5ab36eaf433ecdb8" + integrity sha512-E4BdfB0HZpb66OPFhIzPApNE2tG75Mc6XKIoeymUkx/IV+USSYuxDX29sjgE/KGNYxggrOf4YuYnRMI6UiPL8w== dependencies: - "@babel/runtime" "^7.12.5" - "@noble/ed25519" "^1.7.0" - "@noble/hashes" "^1.1.2" - "@noble/secp256k1" "^1.6.3" - "@solana/buffer-layout" "^4.0.0" + "@babel/runtime" "^7.23.4" + "@noble/curves" "^1.2.0" + "@noble/hashes" "^1.3.2" + "@solana/buffer-layout" "^4.0.1" + agentkeepalive "^4.5.0" bigint-buffer "^1.1.5" - bn.js "^5.0.0" + bn.js "^5.2.1" borsh "^0.7.0" bs58 "^4.0.1" - buffer "6.0.1" + buffer "6.0.3" fast-stable-stringify "^1.0.0" - jayson "^3.4.4" - node-fetch "2" - rpc-websockets "^7.5.0" + jayson "^4.1.0" + node-fetch "^2.7.0" + rpc-websockets "^7.5.1" superstruct "^0.14.2" "@types/connect@^3.4.33": @@ -105,6 +109,13 @@ JSONStream@^1.3.5: jsonparse "^1.2.0" through ">=2.2.7 <3" +agentkeepalive@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.5.0.tgz#2673ad1389b3c418c5a20c5d7364f93ca04be923" + integrity sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew== + dependencies: + humanize-ms "^1.2.1" + ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -155,7 +166,7 @@ bindings@^1.3.0: dependencies: file-uri-to-path "1.0.0" -bn.js@^5.0.0, bn.js@^5.2.0: +bn.js@^5.2.0, bn.js@^5.2.1: version "5.2.1" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== @@ -198,15 +209,7 @@ bs58@^5.0.0: dependencies: base-x "^4.0.0" -buffer@6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.1.tgz#3cbea8c1463e5a0779e30b66d4c88c6ffa182ac2" - integrity sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.2.1" - -buffer@~6.0.3: +buffer@6.0.3, buffer@~6.0.3: version "6.0.3" resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== @@ -363,6 +366,13 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" +humanize-ms@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" + integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== + dependencies: + ms "^2.0.0" + ieee754@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" @@ -393,10 +403,10 @@ isomorphic-ws@^4.0.1: resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== -jayson@^3.4.4: - version "3.7.0" - resolved "https://registry.yarnpkg.com/jayson/-/jayson-3.7.0.tgz#b735b12d06d348639ae8230d7a1e2916cb078f25" - integrity sha512-tfy39KJMrrXJ+mFcMpxwBvFDetS8LAID93+rycFglIQM4kl3uNR3W4lBLE/FFhsoUCEox5Dt2adVpDm/XtebbQ== +jayson@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/jayson/-/jayson-4.1.0.tgz#60dc946a85197317f2b1439d672a8b0a99cea2f9" + integrity sha512-R6JlbyLN53Mjku329XoRT2zJAE6ZgOQ8f91ucYdMCD4nkGCF9kZSrcGXpHIU4jeKj58zUZke2p+cdQchU7Ly7A== dependencies: "@types/connect" "^3.4.33" "@types/node" "^12.12.54" @@ -408,7 +418,6 @@ jayson@^3.4.4: eyes "^0.1.8" isomorphic-ws "^4.0.1" json-stringify-safe "^5.0.1" - lodash "^4.17.20" uuid "^8.3.2" ws "^7.4.5" @@ -440,11 +449,6 @@ jsonparse@^1.2.0: resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== -lodash@^4.17.20: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - lunr@^2.3.9: version "2.3.9" resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" @@ -481,15 +485,20 @@ mkdirp@^0.5.3: dependencies: minimist "^1.2.6" +ms@^2.0.0: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + node-domexception@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== -node-fetch@2: - version "2.6.7" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" - integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== +node-fetch@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== dependencies: whatwg-url "^5.0.0" @@ -534,6 +543,11 @@ regenerator-runtime@^0.13.4: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== +regenerator-runtime@^0.14.0: + version "0.14.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" + integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== + resolve@^1.3.2: version "1.22.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" @@ -543,10 +557,10 @@ resolve@^1.3.2: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -rpc-websockets@^7.5.0: - version "7.5.0" - resolved "https://registry.yarnpkg.com/rpc-websockets/-/rpc-websockets-7.5.0.tgz#bbeb87572e66703ff151e50af1658f98098e2748" - integrity sha512-9tIRi1uZGy7YmDjErf1Ax3wtqdSSLIlnmL5OtOzgd5eqPKbsPpwDP5whUDO2LQay3Xp0CcHlcNSGzacNRluBaQ== +rpc-websockets@^7.5.1: + version "7.9.0" + resolved "https://registry.yarnpkg.com/rpc-websockets/-/rpc-websockets-7.9.0.tgz#a3938e16d6f134a3999fdfac422a503731bf8973" + integrity sha512-DwKewQz1IUA5wfLvgM8wDpPRcr+nWSxuFxx5CbrI2z/MyyZ4nXLM86TvIA+cI1ZAdqC8JIBR1mZR55dzaLU+Hw== dependencies: "@babel/runtime" "^7.17.2" eventemitter3 "^4.0.7"