From 39ded689113f51e40a5ab2a45465cda5d3c5f1a8 Mon Sep 17 00:00:00 2001 From: Volodymyr Brazhnyk <16227101+vovacha@users.noreply.github.com> Date: Tue, 6 Aug 2024 15:43:28 +0200 Subject: [PATCH] Add XCM transfers support (#250) --- .eslintrc.js | 4 +- .../polkadot-watcher-transaction/Chart.yaml | 4 +- package.json | 13 +- src/constants.ts | 76 ++ src/notifier/matrixbot.ts | 5 +- src/subscriber.ts | 17 +- .../ISubscribscriptionModule.ts | 2 - .../balanceBelowThreshold.ts | 2 +- src/subscriptionModules/eventScannerBased.ts | 86 ++- src/transfers.ts | 186 +++++ src/types.ts | 45 +- src/utils.ts | 19 +- test/integration/balancesData.ts | 21 + test/integration/transfers.ts | 55 ++ test/integration/xcmData.ts | 176 +++++ test/mocks.ts | 5 +- test/subscriber.ts | 32 +- yarn.lock | 697 ++++++++++++------ 18 files changed, 1096 insertions(+), 349 deletions(-) create mode 100644 src/transfers.ts create mode 100644 test/integration/balancesData.ts create mode 100644 test/integration/transfers.ts create mode 100644 test/integration/xcmData.ts diff --git a/.eslintrc.js b/.eslintrc.js index 764f095..04e44ea 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -9,9 +9,7 @@ module.exports = { 'plugin:@typescript-eslint/eslint-recommended', 'plugin:@typescript-eslint/recommended', ], - "rules": { - "@typescript-eslint/camelcase": ["error", { "properties": "never" } ] - }, + rules: {}, env: { node: true, }, diff --git a/charts/polkadot-watcher-transaction/Chart.yaml b/charts/polkadot-watcher-transaction/Chart.yaml index b5c06cb..2d340ac 100644 --- a/charts/polkadot-watcher-transaction/Chart.yaml +++ b/charts/polkadot-watcher-transaction/Chart.yaml @@ -1,5 +1,5 @@ description: Polkadot Watcher name: polkadot-watcher-transaction -version: v1.3.6 -appVersion: v1.3.6 +version: v1.4.0 +appVersion: v1.4.0 apiVersion: v2 diff --git a/package.json b/package.json index 4fd86e5..bf50bd7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "polkadot-watcher-transaction", - "version": "1.3.6", + "version": "1.4.0", "description": "Monitor events on Polkadot networks, specifically transactions", "repository": "git@github.com:w3f/polkadot-watcher-csv-exporter.git", "author": "W3F Infrastructure Team ", @@ -16,11 +16,11 @@ "prepare": "yarn build", "pretest": "yarn lint", "test": "mocha --timeout 60000 --require ts-node/register --exit test/*.ts test/**/*.ts", - "e2e-test": "mocha --timeout 300000 --require ts-node/register --exit e2e-test/**/*.ts", + "test:integration": "mocha --timeout 60000 --require ts-node/register --exit test/integration/*.ts", "start": "node ./dist/index.js start" }, "dependencies": { - "@polkadot/api": "^12.0.1", + "@polkadot/api": "^12.2.3", "@w3f/config": "^0.1.1", "@w3f/logger": "^0.4.2", "commander": "^4.0.0", @@ -39,8 +39,8 @@ "@types/node": "14.18.20", "@types/sinon": "10.0.11", "@types/tmp": "0.2.3", - "@typescript-eslint/eslint-plugin": "2.34.0", - "@typescript-eslint/parser": "2.34.0", + "@typescript-eslint/eslint-plugin": "^5.26.0", + "@typescript-eslint/parser": "^5.26.0", "@w3f/polkadot-api-client": "^1.3.0", "@w3f/test-utils": "^1.4.0", "chai": "4.3.6", @@ -53,5 +53,8 @@ "tmp": "0.2.1", "ts-node": "10.8.0", "typescript": "4.7.2" + }, + "resolutions": { + "@polkadot/api": "^12.2.3" } } diff --git a/src/constants.ts b/src/constants.ts index fb4ee56..ceb4151 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,4 +1,5 @@ import { Balance } from '@polkadot/types/interfaces'; +import { ChainId } from './types'; import BN from 'bn.js'; export const ZeroBN = new BN(0); @@ -8,3 +9,78 @@ export const retriesBeforeLeave = 5 export const delayBeforeRetryMillis = 5000 //5 seconds export const dataFileName = "lastChecked.txt" export const environment = "production" +export const chainsInfo = { + kusama: { id: 'kusama' as ChainId, decimals: [12], tokens: ['KSM'], SS58: 2 }, + polkadot: { id: 'polkadot' as ChainId, decimals: [10], tokens: ['DOT'], SS58: 0 }, + development: { id: 'polkadot' as ChainId, decimals: [10], tokens: ['DOT'], SS58: 0 } +} +export const parachainNames = { + polkadot: { + "1000": "AssetHub", + "1001": "Collectives", + "1002": "BridgeHub", + "1004": "People", + "2000": "Acala", + "2002": "Clover", + "2004": "Moonbeam", + "2006": "Astar", + "2008": "Crust", + "2012": "Parallel", + "2013": "Litentry", + "2025": "SORA", + "2026": "Nodle", + "2030": "Bifrost", + "2031": "Centrifuge", + "2032": "Interlay", + "2034": "Hydration", + "2035": "Phala Network", + "2037": "Unique Network", + "2040": "Polkadex", + "2043": "NeuroWeb", + "2046": "Darwinia2", + "2051": "Ajuna", + "2056": "Aventus", + "2086": "KILT Protocol", + "2090": "OAK Network", + "2092": "Zeitgeist", + "2093": "Hashed Network", + "2094": "Pendulum", + "2104": "Manta", + "3338": "peaq", + "3345": "Energy Web X", + "3346": "Continuum", + "3369": "Mythos" + }, + kusama: { + "1000": "AssetHub", + "1001": "Collectives", + "1002": "BridgeHub", + "1004": "People", + "1005": "Coretime", + "2000": "Karura", + "2001": "Bifrost", + "2004": "Khala Network", + "2007": "Shiden", + "2011": "SORA", + "2012": "Crust Shadow", + "2023": "Moonriver", + "2024": "Genshiro", + "2048": "Robonomics", + "2084": "Calamari", + "2087": "Picasso", + "2090": "Basilisk", + "2092": "Kintsugi", + "2095": "Quartz", + "2096": "Pioneer", + "2105": "Crab2", + "2106": "Litmus", + "2110": "Mangata", + "2113": "Kabocha", + "2114": "Turing Network", + "2119": "Bajun Network", + "2239": "Acurast", + "2241": "krest", + "3339": "Curio", + "3344": "Xode" + } +}; \ No newline at end of file diff --git a/src/notifier/matrixbot.ts b/src/notifier/matrixbot.ts index 4cf7877..8d01a2a 100644 --- a/src/notifier/matrixbot.ts +++ b/src/notifier/matrixbot.ts @@ -76,13 +76,14 @@ export class Matrixbot implements Notifier { let description: string; let alertname: string; + const chainName = data.networkId[0].toUpperCase() + data.networkId.slice(1) const checkUrl = data.hash ? `https://${data.networkId}.subscan.io/extrinsic/${data.hash} for details.` : `https://${data.networkId}.subscan.io/account/${data.address}?tab=transfer for details.` if (data.txType === TransactionType.Sent) { - description = `New Transfer of ${data.amount} sent from the account ${data.name}, check ${checkUrl}`; + description = `New Transfer of ${data.amount} ${data.token} sent from the ${chainName} account ${data.name}, check ${checkUrl}`; alertname = 'TransferSent'; } else { - description = `New Transfer of ${data.amount} received in the account ${data.name}, check ${checkUrl}`; + description = `New Transfer of ${data.amount} ${data.token} received in the ${chainName} account ${data.name}, check ${checkUrl}`; alertname = 'TransferReceived'; } msg.alerts[0].labels.alertname = alertname; diff --git a/src/subscriber.ts b/src/subscriber.ts index a4f099f..5e1aa84 100644 --- a/src/subscriber.ts +++ b/src/subscriber.ts @@ -1,17 +1,16 @@ +import '@polkadot/api-augment/polkadot' import { ApiPromise, WsProvider } from '@polkadot/api'; import { Logger, LoggerSingleton } from './logger'; -import { Text } from '@polkadot/types/primitive'; -import { - InputConfig, PromClient, SubscriberConfig, TransactionData, TransactionType -} from './types'; +import { InputConfig, PromClient, SubscriberConfig, TransactionData, TransactionType, TypeRegistry } from './types'; import { EventScannerBased } from './subscriptionModules/eventScannerBased'; import { SubscriptionModuleConstructorParams } from './subscriptionModules/ISubscribscriptionModule'; import { Notifier } from './notifier/INotifier'; import { BalanceBelowThreshold } from './subscriptionModules/balanceBelowThreshold'; +export const registry = new TypeRegistry() + export class Subscriber { - private chain: Text; private api: ApiPromise; private networkId: string; private endpoint: string; @@ -75,7 +74,7 @@ export class Subscriber { private _initAPI = async (): Promise =>{ const provider = new WsProvider(this.endpoint); - this.api = new ApiPromise({provider}) + this.api = new ApiPromise({provider, registry}) if(this.api){ this.api.on("error", error => { if( error.toString().includes("FATAL") || JSON.stringify(error).includes("FATAL") ){ @@ -86,14 +85,14 @@ export class Subscriber { } await this.api.isReadyOrError; - this.chain = await this.api.rpc.system.chain(); - this.networkId = this.chain.toString().toLowerCase() + const chain = await this.api.rpc.system.chain(); + this.networkId = chain.toString().toLowerCase() const [nodeName, nodeVersion] = await Promise.all([ this.api.rpc.system.name(), this.api.rpc.system.version() ]); this.logger.info( - `You are connected to chain ${this.chain} using ${nodeName} v${nodeVersion}` + `You are connected to chain ${this.networkId} using ${nodeName} v${nodeVersion}` ); } diff --git a/src/subscriptionModules/ISubscribscriptionModule.ts b/src/subscriptionModules/ISubscribscriptionModule.ts index 1549e33..b5e187b 100644 --- a/src/subscriptionModules/ISubscribscriptionModule.ts +++ b/src/subscriptionModules/ISubscribscriptionModule.ts @@ -1,5 +1,3 @@ -/* eslint-disable @typescript-eslint/interface-name-prefix */ - import { ApiPromise } from "@polkadot/api"; import { Notifier } from "../notifier/INotifier"; import { SubscriberConfig } from "../types"; diff --git a/src/subscriptionModules/balanceBelowThreshold.ts b/src/subscriptionModules/balanceBelowThreshold.ts index 81edc9e..646a3dd 100644 --- a/src/subscriptionModules/balanceBelowThreshold.ts +++ b/src/subscriptionModules/balanceBelowThreshold.ts @@ -34,7 +34,7 @@ export class BalanceBelowThreshold implements ISubscriptionModule{ this.promClient.updateDesiredBalance(this.networkId,account.name,account.address,account.threshold) } - await this.api.query.system.account.multi(this.subscriptions.map(a => a.address), (balances) => { + await this.api.query.system.account.multi(this.subscriptions.map(a => a.address), (balances: any) => { this.subscriptions.forEach((account, index) => { const free = balances[index].data.free; let balance = this.formatBalance(free.toBigInt()); diff --git a/src/subscriptionModules/eventScannerBased.ts b/src/subscriptionModules/eventScannerBased.ts index ec80d57..ece8768 100644 --- a/src/subscriptionModules/eventScannerBased.ts +++ b/src/subscriptionModules/eventScannerBased.ts @@ -2,20 +2,22 @@ import { ApiPromise} from '@polkadot/api'; import { Logger, LoggerSingleton } from '../logger'; import readline from 'readline'; import { - TransactionData, TransactionType, SubscriberConfig, Subscribable, PromClient + TransactionData, TransactionType, SubscriberConfig, Subscribable, PromClient, + ChainId, TransferInfo, ChainInfo, Event } from '../types'; -import { Event, CodecHash } from '@polkadot/types/interfaces'; -import { closeFile, delay, extractTransferInfoFromEvent, getFileNames, getSubscriptionNotificationConfig, initReadFileStream, initWriteFileStream, isBalanceTransferEvent, isDirEmpty, isDirExistent, makeDir, setIntervalFunction } from '../utils'; -import { formatBalance } from '@polkadot/util/format/formatBalance' +import { + closeFile, delay, getFileNames, getSubscriptionNotificationConfig, initReadFileStream, + initWriteFileStream, isDirEmpty, isDirExistent, makeDir, setIntervalFunction } from '../utils'; +import { extractTransferInfoFromEvent, isTransferEvent } from '../transfers'; import { ISubscriptionModule, SubscriptionModuleConstructorParams } from './ISubscribscriptionModule'; import { Notifier } from '../notifier/INotifier'; -import { dataFileName, delayBeforeRetryMillis, retriesBeforeLeave, scanIntervalMillis } from '../constants'; +import { chainsInfo, dataFileName, delayBeforeRetryMillis, retriesBeforeLeave, scanIntervalMillis } from '../constants'; +import { EventRecord } from "@polkadot/types/interfaces"; export class EventScannerBased implements ISubscriptionModule{ private subscriptions = new Map() private readonly api: ApiPromise - private readonly networkId: string private readonly notifier: Notifier private readonly config: SubscriberConfig private readonly logger: Logger = LoggerSingleton.getInstance() @@ -24,20 +26,24 @@ export class EventScannerBased implements ISubscriptionModule{ private dataFileName = dataFileName private retriesBeforeLeave: number private delayBeforeRetryMillis: number + private chainInfo: ChainInfo + private extractTransferInfoFromEvent: (event: Event, chainInfo: ChainInfo, blockNumber: number) => TransferInfo + private isTransferEvent: (event: Event) => boolean private isScanOngoing = false //lock for concurrency private isNewScanRequired = false constructor(params: SubscriptionModuleConstructorParams, private readonly promClient: PromClient) { this.api = params.api - this.networkId = params.networkId this.notifier = params.notifier this.config = params.config this.dataDir = this.config.modules.transferEventScanner.dataDir this.scanIntervalMillis = this.config.modules.transferEventScanner.scanIntervalMillis ? this.config.modules.transferEventScanner.scanIntervalMillis : scanIntervalMillis this.delayBeforeRetryMillis = this.config.modules.transferEventScanner.delayBeforeRetryMillis ? this.config.modules.transferEventScanner.delayBeforeRetryMillis : delayBeforeRetryMillis this.retriesBeforeLeave = this.config.modules.transferEventScanner.retriesBeforeLeave ? this.config.modules.transferEventScanner.retriesBeforeLeave : retriesBeforeLeave - + this.extractTransferInfoFromEvent = extractTransferInfoFromEvent + this.isTransferEvent = isTransferEvent + this.chainInfo = chainsInfo[params.networkId as ChainId] this._initSubscriptions() } @@ -50,7 +56,7 @@ export class EventScannerBased implements ISubscriptionModule{ public subscribe = async (): Promise => { await this._initDataDir() - this.promClient.updateScanHeight(this.networkId,await this._getLastCheckedBlock())//init prometheus metric + this.promClient.updateScanHeight(this.chainInfo.id,await this._getLastCheckedBlock())//init prometheus metric await this._handleEventsSubscriptions() // scan immediately after a event detection this.logger.info(`Event Scanner Based Module subscribed...`) @@ -74,19 +80,25 @@ export class EventScannerBased implements ISubscriptionModule{ } private _handleEventsSubscriptions = async (): Promise => { - this.api.query.system.events((events) => { - events.forEach(async (record) => { - const { event } = record; - if(isBalanceTransferEvent(event,this.api)) await this._handleBalanceTransferEvents(event) - }) + this.api.query.system.events(async (records: EventRecord[]) => { + for (const { event } of records) { + if (this.isTransferEvent(event)) { + const currentBlockNumber = (await this.api.rpc.chain.getHeader()).number.unwrap().toNumber() + try { + const transfer = this.extractTransferInfoFromEvent(event, this.chainInfo, currentBlockNumber) + if( + this.subscriptions.has(transfer.origin.address) || + this.subscriptions.has(transfer.destination.address)) this._requestNewScan() + } catch (error) { + this.logger.error(`TransferInfo extraction failed at block ${currentBlockNumber}: ${error}`) + this.logger.warn('quitting...') + process.exit(-1); + } + } + } }) } - private _handleBalanceTransferEvents = async (event: Event): Promise => { - const {from,to} = extractTransferInfoFromEvent(event) - if(this.subscriptions.has(from) || this.subscriptions.has(to)) this._requestNewScan() - } - private _requestNewScan = async (): Promise => { if(this.isScanOngoing){ /* @@ -132,7 +144,7 @@ export class EventScannerBased implements ISubscriptionModule{ const blockHash = await this.api.rpc.chain.getBlockHash(blockNumber) const block = await this.api.rpc.chain.getBlock(blockHash) const allRecords = await this.api.query.system.events.at(blockHash); - + for (const [index, { hash }] of block.block.extrinsics.entries()) { @@ -140,12 +152,13 @@ export class EventScannerBased implements ISubscriptionModule{ .filter(({ phase,event }) => phase.isApplyExtrinsic && phase.asApplyExtrinsic.eq(index) && - isBalanceTransferEvent(event,this.api) + isTransferEvent(event) )) { let retriesBeforeLeave = this.retriesBeforeLeave do { - result = await this._balanceTransferHandler(event, hash) + const transfer = this.extractTransferInfoFromEvent(event, this.chainInfo, blockNumber) + result = await this._transferNotificationHandler(transfer, hash.toString()) if(!result){ retriesBeforeLeave-- this.logger.warn(`New retry at block ${blockNumber} !!`) @@ -170,30 +183,32 @@ export class EventScannerBased implements ISubscriptionModule{ this.logger.info(`\n*****\nSCAN completed at block ${await this._getLastCheckedBlock()}\n*****`) } - private _balanceTransferHandler = async (event: Event, extrinsicHash: CodecHash): Promise => { + private _transferNotificationHandler = async (transfer: TransferInfo, extrinsicHash: string): Promise => { //this.logger.debug('Balances Transfer Event Detected') - const {from,to,amount} = extractTransferInfoFromEvent(event) - let isNewNotificationDelivered = false let isNewNotificationNecessary = false let notificationConfigFrom: {sent: boolean; received: boolean} let notificationConfigTo: {sent: boolean; received: boolean} + const from = transfer.origin.address + const to = transfer.destination.address + if(this.subscriptions.has(from)){ isNewNotificationNecessary = true const data: TransactionData = { name: this.subscriptions.get(from).name, address: from, - networkId: this.networkId, + networkId: this.chainInfo.id, txType: TransactionType.Sent, - hash: extrinsicHash.toString(), - amount: formatBalance(amount,{decimals:this.api.registry.chainDecimals[0]}) + hash: extrinsicHash, + amount: transfer.amount, + token: transfer.token }; notificationConfigFrom = getSubscriptionNotificationConfig(this.config.modules?.transferEventScanner,this.subscriptions.get(from).transferEventScanner) if(notificationConfigFrom.sent){ - this.logger.info(`Balances Transfer Event from ${from} detected`) + this.logger.info(`Transfer from ${from} detected`) isNewNotificationDelivered = await this._notifyNewTransfer(data) } } @@ -203,22 +218,23 @@ export class EventScannerBased implements ISubscriptionModule{ const data: TransactionData = { name: this.subscriptions.get(to).name, address: to, - networkId: this.networkId, + networkId: this.chainInfo.id, txType: TransactionType.Received, - hash: extrinsicHash.toString(), - amount: formatBalance(amount,{decimals:this.api.registry.chainDecimals[0]}) + hash: extrinsicHash, + amount: transfer.amount, + token: transfer.token }; notificationConfigTo = getSubscriptionNotificationConfig(this.config.modules?.transferEventScanner,this.subscriptions.get(to).transferEventScanner) if(notificationConfigTo.received){ - this.logger.info(`Balances Transfer Event to ${to} detected`) + this.logger.info(`Transfer to ${to} detected`) isNewNotificationDelivered = await this._notifyNewTransfer(data) } } if(isNewNotificationNecessary && !notificationConfigFrom?.sent && !notificationConfigTo?.received){ isNewNotificationNecessary = false - this.logger.debug(`Balances Transfer Event from ${from} to ${to} detected. Notification SUPPRESSED`) + this.logger.debug(`Transfer from ${from} to ${to} detected. Notification SUPPRESSED`) } return isNewNotificationDelivered || !isNewNotificationNecessary @@ -252,7 +268,7 @@ export class EventScannerBased implements ISubscriptionModule{ const file = initWriteFileStream(this.dataDir,this.dataFileName,this.logger) const result = file.write(blockNumber.toString()) await closeFile(file) - if(result) this.promClient.updateScanHeight(this.networkId,blockNumber) + if(result) this.promClient.updateScanHeight(this.chainInfo.id,blockNumber) return result } diff --git a/src/transfers.ts b/src/transfers.ts new file mode 100644 index 0000000..1f4bb5e --- /dev/null +++ b/src/transfers.ts @@ -0,0 +1,186 @@ +import { Logger, LoggerSingleton } from './logger'; +import { hexToU8a, formatBalance } from '@polkadot/util'; +import { encodeAddress } from '@polkadot/util-crypto'; +import { + Event, TransferInfo, XcmSentEvent, StagingXcmV4Xcm, StagingXcmV4Location, StagingXcmV4Asset, + ChainInfo, BalancesTransferEvent, Balance } from './types'; +import { parachainNames } from './constants'; +import { registry } from './subscriber'; + + +const log: Logger = LoggerSingleton.getInstance() + + +export const isTransferEvent = (event: Event): boolean => { + return isBalancesTransferEvent(event) || isXcmSentEvent(event); +} + +/** + * Extracts transfer information from the given event. + * + * Depending on the type of the event, it extracts transfer information + * from either a pallet Balances Transfer event or a pallet's XCM Sent event. + * + * @param {Event} event - The event to extract transfer information from. + * @param {ChainInfo} chainInfo - Information about the blockchain network. + * @param {number} blockNumber - The block number at which the event occurred. + * @returns {TransferInfo} The extracted transfer information. + * @throws {Error} If the event type is not a valid transfer event type. + */ +export const extractTransferInfoFromEvent = (event: Event, chainInfo: ChainInfo, blockNumber: number): TransferInfo => { + if (isBalancesTransferEvent(event)) { + const balancesTransfer: BalancesTransferEvent = { + origin: event.data[0].toString(), + destination: event.data[1].toString(), + amount: event.data[2] as unknown as Balance + } + return extractTransferInfoFromBalancesEvent(balancesTransfer, chainInfo, blockNumber); + + } else if (isXcmSentEvent(event)) { + const [rawOrigin, rawDestination, rawMessage] = event.data + const xcmSent: XcmSentEvent = { + origin: registry.createType('StagingXcmV4Location',rawOrigin.toU8a()), + destination: registry.createType('StagingXcmV4Location',rawDestination.toU8a()), + message: registry.createType('StagingXcmV4Xcm',rawMessage.toU8a()) + } + return extractTransferInfoFromXcmEvent(xcmSent, chainInfo, blockNumber); + + } else { + throw new Error(`Invalid Transfer Event type. Index: ${event.index}. Block: ${blockNumber}`); + } +} + +/** + * Extracts transfer information from an XCM Sent event. + * + * This function processes an XCM event to extract details about a transfer, including the origin and + * destination of the transfer, and the amount transferred. It uses specific instructions within the + * XCM message to determine the beneficiary and asset information. + * + * @param {XcmSentEvent} event - The XCM event containing the transfer details. + * @param {ChainInfo} chainInfo - Information about the blockchain network. + * @param {number} blockNumber - The block number at which the event occurred. + * @returns {TransferInfo} An object containing the 'from', 'to', and 'amount' of the transfer. + */ +function extractTransferInfoFromXcmEvent(event: XcmSentEvent, chainInfo: ChainInfo, blockNumber: number): TransferInfo { + const { origin, message } = event + let { destination } = event + // 1. Get origin from the MultiLocation (X1.AccountId32) + const originAddress = getLocation(origin, chainInfo, blockNumber) + // 2. Get beneficiary + // 2.1. Try from "DepositAsset" instruction, which is common for most of extrinsics + let beneficiaryInstruction = findInstruction(message, 'DepositAsset'); + if (!beneficiaryInstruction) { + // 2.2. Try from "DepositReserveAsset" instruction used by "transfer_assets_using_type_and_then" + // Check custom XCM on destination + const depositRA = findInstruction(message, 'DepositReserveAsset'); + if (depositRA?.xcm) { + beneficiaryInstruction = findInstruction(depositRA.xcm, 'DepositAsset'); + // Real destination is in the nested XCM message + destination = depositRA.dest; + } + } + if (!beneficiaryInstruction) { + throw new Error(`XCM. No beneficiary instructions found. Block: ${blockNumber}`); + } + const destinationAddress = getLocation(beneficiaryInstruction.beneficiary, chainInfo, blockNumber) + // 3. Get assets information + const assetInstruction = findInstruction(message, 'ReserveAssetDeposited') || + findInstruction(message, 'ReceiveTeleportedAsset'); + + if (!assetInstruction) { + throw new Error(`XCM. No assets instructions found. Block: ${blockNumber}`); + } + const destChain = getLocation(destination, chainInfo, blockNumber) + const transfers = getTokenAmountFromAsset( + assetInstruction, + chainInfo, + blockNumber + ) + if (transfers.length === 0) { + throw new Error(`XCM. No assets found inside of instruction. Block: ${blockNumber}`); + } + // TODO: AssetHub monitoring. The list of assets should be returned instead. + const [token, amount] = transfers[0] + return { + origin: { + address: originAddress, + chain: chainInfo.id + }, + destination: { + address: destinationAddress, + chain: destChain + }, + amount: amount, + token: token + } +} + +function getLocation(location: StagingXcmV4Location, chainInfo: ChainInfo, blockNumber: number): string { + if (!(location.interior.isX1)) { + log.error(`XCM. Junctions not supported: ${location.interior.type}. Block ${blockNumber}`) + return 'Unknown' + } + const x1 = location.interior.asX1[0] + if (x1.isAccountId32) { + const originIdHex = x1.asAccountId32.id.toString(); + return encodeAddress(hexToU8a(originIdHex), chainInfo.SS58); + } else if (x1.isAccountKey20) { + return x1.asAccountKey20.key.toHuman() + } else if (x1.isParachain) { + const chainIndex = x1.asParachain.toString() + return parachainNames[chainInfo.id][chainIndex] || `Parachain ${chainIndex}`; + } else { + log.error(`XCM. Junctions not supported: ${x1.type}. Block ${blockNumber}`) + } + return 'Unknown' +} + +const findInstruction = (xcm: StagingXcmV4Xcm, key: string) => xcm.find(instr => instr.type === key)?.['as' + key]; + +function getTokenAmountFromAsset(assets: StagingXcmV4Asset[], chainInfo: ChainInfo, blockNumber: number): [string, string][] { + const result: [string, string][] = []; + for (const asset of assets) { + if (!(asset.fun.isFungible)) { + // NFTs are not a subject for monitoring + continue + } + const amount = formatBalance(asset.fun.asFungible, {decimals: chainInfo.decimals[0], withSi: false, forceUnit: '-' }) + const interior = asset.id.interior + let token: string; + if (interior.isHere) { + token = chainInfo.tokens[0] + } else if (interior.isX3) { + // TODO: AssetHub monitoring. The token address should be processed. + continue + } else { + log.error(`Asset Junctions not supported: ${interior.type}. Block ${blockNumber}`) + continue + } + result.push([token, amount]) + } + return result +} + +export const isBalancesTransferEvent = (event: Event): boolean => { + return event.section === 'balances' && event.method === 'Transfer' +} + +export function isXcmSentEvent(event: Event): boolean { + return ['polkadotXcm', 'xcmPallet'].includes(event.section) && event.method === 'Sent' +} + +const extractTransferInfoFromBalancesEvent = (event: BalancesTransferEvent, chainInfo: ChainInfo, _blockNumber: number): TransferInfo =>{ + return { + origin: { + address: event.origin, + chain: chainInfo.id + }, + destination: { + address: event.destination, + chain: chainInfo.id + }, + amount: formatBalance(event.amount, {decimals: chainInfo.decimals[0], withSi: false, forceUnit: '-' }), + token: chainInfo.tokens[0] + } +} diff --git a/src/types.ts b/src/types.ts index f9aa022..cb47c30 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,4 +1,33 @@ -import { Balance } from '@polkadot/types/interfaces'; +import '@polkadot/api-augment/polkadot'; +import { Balance, Event, CodecHash, EventRecord } from '@polkadot/types/interfaces'; +import { DeriveAccountRegistration } from '@polkadot/api-derive/accounts/types'; +import { StagingXcmV4Location, StagingXcmV4Xcm, StagingXcmV4Asset } from '@polkadot/types/lookup'; +import { TypeRegistry } from '@polkadot/types'; +import { string } from 'yaml/dist/schema/common/string'; + + +export type ChainId = 'polkadot' | 'kusama' + +export { StagingXcmV4Location, StagingXcmV4Xcm, StagingXcmV4Asset, Balance, Event, EventRecord, CodecHash, DeriveAccountRegistration, TypeRegistry } + +export interface ChainInfo { + id: ChainId; + decimals: number[]; + tokens: string[]; + SS58: number; +} + +export interface BalancesTransferEvent { + origin: string; + destination: string; + amount: Balance; +} + +export interface XcmSentEvent { + origin: StagingXcmV4Location; + destination: StagingXcmV4Location; + message: StagingXcmV4Xcm; +} export interface InputConfig { logLevel: string; @@ -72,12 +101,20 @@ export interface TransactionData extends Subscribable { networkId: string; hash?: string; amount?: string; + token?: string; } export interface TransferInfo { - from: string; - to: string; - amount: Balance; + origin: { + address: string; + chain: string; + }; + destination: { + address: string; + chain: string; + }; + token: string; + amount: string; } export interface InitializedMap { diff --git a/src/utils.ts b/src/utils.ts index 965a289..827d8e8 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,9 +1,6 @@ import fs, { ReadStream, WriteStream } from 'fs'; import { Logger } from '@w3f/logger'; -import { DeriveAccountRegistration } from '@polkadot/api-derive/accounts/types'; -import { Event, Balance } from '@polkadot/types/interfaces'; -import { SubscriptionModuleConfig, TransferInfo } from './types'; -import { ApiPromise } from '@polkadot/api'; +import { SubscriptionModuleConfig, DeriveAccountRegistration } from './types'; export const isDirEmpty = (path: string): boolean =>{ return fs.readdirSync(path).length === 0 @@ -85,24 +82,12 @@ export const getDisplayName = (identity: DeriveAccountRegistration): string =>{ } } -export const asyncForEach = async < T extends {} > (array: Array, callback: (arg0: T, arg1: number, arg2: Array) => void): Promise =>{ +export const asyncForEach = async (array: Array, callback: (arg0: T, arg1: number, arg2: Array) => void): Promise =>{ for (let index = 0; index < array.length; index++) { await callback(array[index], index, array); } } -export const isBalanceTransferEvent = (event: Event, api: ApiPromise): boolean => { - return api.events.balances.Transfer.is(event) -} - -export const extractTransferInfoFromEvent = (event: Event): TransferInfo =>{ - const from = event.data[0].toString() - const to = event.data[1].toString() - const amount = event.data[2] as unknown as Balance - - return {from,to,amount} -} - export const getSubscriptionNotificationConfig = (config: SubscriptionModuleConfig, configSpecific: SubscriptionModuleConfig): {sent: boolean; received: boolean} => { /* Specific/Nested config is the most prioritized diff --git a/test/integration/balancesData.ts b/test/integration/balancesData.ts new file mode 100644 index 0000000..8799ac7 --- /dev/null +++ b/test/integration/balancesData.ts @@ -0,0 +1,21 @@ +export const balancesTests = { + kusama: [ + { + description: "Pallet Balances. Batch, proxy, multisig", + link: "https://kusama.subscan.io/extrinsic/0xed315f5599c6ddab302088f8df5ffe0277719dbe8b332e85dbfd2fe060730157", + block: 21441337, + eventIndex: 49, + origin: { + address: "ESVfLhWFe7pAePrxctqDPEx8jEZFPCWxfmyuGAzn8gAJdPU", + chain: "Kusama" + }, + destination: { + address: "FU8YDYuuvCrLh5DoaNu3oQa1GrocjDD129yqbJ5t2qE31K2", + chain: "Kusama" + }, + token: "KSM", + amount: "12,105.0000", + } + ], + polkadot: [], +} \ No newline at end of file diff --git a/test/integration/transfers.ts b/test/integration/transfers.ts new file mode 100644 index 0000000..531d8a8 --- /dev/null +++ b/test/integration/transfers.ts @@ -0,0 +1,55 @@ +import { ApiPromise, WsProvider } from '@polkadot/api'; +import { expect } from 'chai'; +import { ChainId, EventRecord } from '../../src/types'; +import { chainsInfo } from '../../src/constants'; +import { extractTransferInfoFromEvent, isTransferEvent } from '../../src/transfers'; +import { xcmTests } from './xcmData' +import { balancesTests } from './balancesData' +import { registry } from '../../src/subscriber'; + + +const chains: ChainId[] = ['kusama', 'polkadot']; +const urls = { + kusama: 'wss://kusama-rpc.dwellir.com', + polkadot: 'wss://polkadot-rpc.dwellir.com' +}; + +for (const chain of chains) { + + describe(`Transfers: ${chain}`, (): void => { + let api: ApiPromise; + + before(async (): Promise => { + api = await ApiPromise.create({ provider: new WsProvider(urls[chain]), registry, throwOnConnect: true }); + }); + + after(async (): Promise => { + await api.disconnect(); + }) + + for (const test of [...balancesTests[chain], ...xcmTests[chain]]) { + it(test.description, async function() { + const { block, origin, destination, amount, token, eventIndex } = test; + const blockHash = await api.rpc.chain.getBlockHash(block); + const apiAt = await api.at(blockHash); + + await apiAt.query.system.events((records: EventRecord[]) => { + records.forEach(({ event }, index) => { + if (index === eventIndex) { + expect(isTransferEvent(event)) + const transferInfo = extractTransferInfoFromEvent(event, chainsInfo[chain], block); + expect(transferInfo).to.not.be.null; + expect(transferInfo.origin.address).to.equal(origin.address); + expect(transferInfo.origin.chain.toLowerCase()).to.equal(origin.chain.toLowerCase()); + expect(transferInfo.destination.address).to.equal(destination.address); + expect(transferInfo.destination.chain.toLowerCase()).to.equal(destination.chain.toLowerCase()); + expect(transferInfo.amount).to.equal(amount); + expect(transferInfo.token).to.equal(token); + return + } + }) + }) + }) + } + }) +} diff --git a/test/integration/xcmData.ts b/test/integration/xcmData.ts new file mode 100644 index 0000000..35f9cfc --- /dev/null +++ b/test/integration/xcmData.ts @@ -0,0 +1,176 @@ +export const xcmTests = { + kusama: [ + { + description: "Pallet XCM. Call limited_teleport_assets - V2 dest 1000", + link: "https://kusama.subscan.io/extrinsic/24265902-2", + messageId: "0x6a201a09c654a73dc6ff43890151e913fb69a7cef12d2a0c696ff928a19ec2ae", + block: 24265902, + eventIndex: 46, + origin: { + address: "EAs8ocCfK72QQNC3H3PzC4hdmo9dtUth8Unb4kgbozZyuAz", + chain: "Kusama" + }, + destination: { + address: "EAs8ocCfK72QQNC3H3PzC4hdmo9dtUth8Unb4kgbozZyuAz", + chain: "AssetHub" + }, + token: "KSM", + amount: "0.0250" + }, + ], + polkadot: [ + { + description: "Pallet XCM. Multisig dest 1000", + link: "https://polkadot.subscan.io/extrinsic/21497354-2", + messageId: "0xd261442d6dd36914970669aba5bab62eeeb6889379c3b05cd7dc79e2fa681cc0", + block: 21497354, + eventIndex: 55, + origin: { + address: "13FzGLWoueKvUqFePiJgvFYWhH5KckHGtVBXvAX7SBtVZbXu", + chain: "Polkadot" + }, + destination: { + address: "16bZYfxvkUGT5WbjwyJkEmZYAsBdZhMeonnaxtcuUrhzpKHm", + chain: "AssetHub" + }, + token: "DOT", + amount: "49,990.0000" + }, + { + description: "Pallet XCM. Call limited_teleport_assets - XCM V2 dest 1000", + link: "https://polkadot.subscan.io/extrinsic/21814508-2", + messageId: "0x29b2d7fb57be5b21381165d89d4ea9589ddfe43371d737a1dd410ed2dd099479", + block: 21814508, + eventIndex: 58, + origin: { + address: "14Dtc5jL8Q9RwJrv4YwkcLTXqRyfBtFYDA8nG7z5ZxwRVCVP", + chain: "Polkadot" + }, + destination: { + address: "14Dtc5jL8Q9RwJrv4YwkcLTXqRyfBtFYDA8nG7z5ZxwRVCVP", + chain: "AssetHub" + }, + token: "DOT", + amount: "1.0035" + }, + { + description: "Pallet XCM. Call limited_teleport_assets - XCM V3 dest 1004", + link: "https://polkadot.subscan.io/extrinsic/21812018-2", + messageId: "0x122c9fa63b640ae1ada81395adf133637e0daf1539ade635602ea58544a931c2", + block: 21812018, + eventIndex: 58, + origin: { + address: "19e6YYas7iGGZzxwJh5KvAARL1XZnJXffcxxNvW3nkF9CLe", + chain: "Polkadot" + }, + destination: { + address: "19e6YYas7iGGZzxwJh5KvAARL1XZnJXffcxxNvW3nkF9CLe", + chain: "People" + }, + token: "DOT", + amount: "0.1500" + }, + { + description: "Pallet XCM. Call teleport_assets - XCM V2 dest 1001", + link: "https://polkadot.subscan.io/extrinsic/20479101-2", + messageId: "0x3e1c58427c4195a88858440bef03777b3cfad6160ab2ab7c92d398df410046b1", + block: 20479101, + eventIndex: 53, + origin: { + address: "16YCL3UVpVWQLGW3p3Zx4k5WAEp9W1DwdDnxAbyAaPxVxnp3", + chain: "Polkadot" + }, + destination: { + address: "16YCL3UVpVWQLGW3p3Zx4k5WAEp9W1DwdDnxAbyAaPxVxnp3", + chain: "Collectives" + }, + token: "DOT", + amount: "2.0000" + }, + { + description: "Pallet XCM. Call transfer_assets - XCM V3 dest 1000", + link: "https://polkadot.subscan.io/extrinsic/21679999-3", + messageId: "0x187ff78cf410141d13c8904b9ac57080f8bf320baf5e8442addf71d1204c99a5", + block: 21679999, + eventIndex: 64, + origin: { + address: "14pB37HYXX8VELDLaYX3oah4XDTvwTzS3LSb6SVmcTVNpUKZ", + chain: "Polkadot" + }, + destination: { + address: "14pB37HYXX8VELDLaYX3oah4XDTvwTzS3LSb6SVmcTVNpUKZ", + chain: "AssetHub" + }, + token: "DOT", + amount: "11.0000" + }, + { + description: "Pallet XCM. Call reserve_transfer_assets - XCM V2 dest 2012", + link: "https://polkadot.subscan.io/extrinsic/21815927-2", + messageId: "0x187ff78cf410141d13c8904b9ac57080f8bf320baf5e8442addf71d1204c99a5", + block: 21815927, + eventIndex: 57, + origin: { + address: "16B5hraqXvJJjNL1ZpD58dEGYHGdVHnHuoJ2kQh4KagLsF8T", + chain: "Polkadot" + }, + destination: { + address: "16B5hraqXvJJjNL1ZpD58dEGYHGdVHnHuoJ2kQh4KagLsF8T", + chain: "Parallel" + }, + token: "DOT", + amount: "0.8211" + }, + { + description: "Pallet XCM. Call limited_reserve_transfer_assets - XCM V3 dest 2000", + link: "https://polkadot.subscan.io/extrinsic/21816282-5", + messageId: "0x31d9b88c1edaca991ea13c12e7f156d171eaf560120f1a390f72472ca172eaee", + block: 21816282, + eventIndex: 78, + origin: { + address: "14zHCfbyPJVL2QwRE8KedRTV63dqydA5SKzfi966vAFwsGb2", + chain: "Polkadot" + }, + destination: { + address: "14zHCfbyPJVL2QwRE8KedRTV63dqydA5SKzfi966vAFwsGb2", + chain: "Acala" + }, + token: "DOT", + amount: "261.0000" + }, + { + description: "Pallet XCM. Call transfer_assets_using_type_and_then - custom XCM on dest AssetHub", + link: "https://polkadot.subscan.io/extrinsic/21803427-4", + messageId: "0x8ba2e8c5c034fd0ba236442273e9125f3f305343bc140442802bf62b7d403c24", + block: 21803427, + eventIndex: 72, + origin: { + address: "15dkzFquMdELBU3CpYqxW86ZDywBqfm3DcCxFYyDgsB4fbhL", + chain: "Polkadot" + }, + destination: { + address: "15dkzFquMdELBU3CpYqxW86ZDywBqfm3DcCxFYyDgsB4fbhL", + chain: "Parachain 3344" + }, + token: "DOT", + amount: "2.0000" + }, + { + description: "Pallet XCM. Call smart contract destination - 2004 Moonbeam", + link: "https://polkadot.subscan.io/extrinsic/21821595-3", + messageId: "0x688157990e84d3e8455cf82e7d26b3f1dea45833cdb3716b579fed9513bdb6b4", + block: 21821595, + eventIndex: 64, + origin: { + address: "12jEnW69xZzGrU7HKZpiya3w2W6ns4ULWJwsPsnGKgUcyRAs", + chain: "Polkadot" + }, + destination: { + address: "0x5f4bcf4f005a62e1364260bc115bbb3a2dbd622a", + chain: "Moonbeam" + }, + token: "DOT", + amount: "20.0000" + }, + ] +} \ No newline at end of file diff --git a/test/mocks.ts b/test/mocks.ts index b3da57c..0370ea0 100644 --- a/test/mocks.ts +++ b/test/mocks.ts @@ -6,7 +6,8 @@ import { Client, Keyring } from '@w3f/polkadot-api-client'; import { TransactionData } from '../src/types'; import { initClient, sendFromAToB } from './utils'; import { TestPolkadotRPC } from '@w3f/test-utils'; -import { delay, isBalanceTransferEvent } from '../src/utils'; +import { delay } from '../src/utils'; +import { isBalancesTransferEvent } from '../src/transfers'; import { Event } from '@polkadot/types/interfaces'; import { Notifier } from '../src/notifier/INotifier'; import { PromClient } from "../src/types"; @@ -68,7 +69,7 @@ export class ExtrinsicMock { events.forEach(async (record) => { const { event } = record; - if (isBalanceTransferEvent(event,api)) { + if (isBalancesTransferEvent(event)) { unsubscribe() result = event } diff --git a/test/subscriber.ts b/test/subscriber.ts index 8537aed..36950ac 100644 --- a/test/subscriber.ts +++ b/test/subscriber.ts @@ -1,7 +1,5 @@ -import '@polkadot/api-augment'; //https://github.com/polkadot-js/api/issues/4450 import { Client, Keyring } from '@w3f/polkadot-api-client'; import { TestPolkadotRPC } from '@w3f/test-utils'; -import { createLogger } from '@w3f/logger'; import { should } from 'chai'; import { Subscriber } from '../src/subscriber'; import { @@ -13,8 +11,9 @@ import { import { TransactionType } from '../src/types'; import { initClient, sendFromAToB } from './utils'; import { isDirExistent, rmDir } from '../src/utils'; -import { CodecHash } from '@polkadot/types/interfaces'; +import { extractTransferInfoFromEvent } from '../src/transfers'; import sinon from 'sinon' +import { chainsInfo } from '../src/constants'; should(); @@ -72,8 +71,6 @@ const cfg2 = { } }; -const logger = createLogger(); - const testRPC = new TestPolkadotRPC(); const extrinsicMock = new ExtrinsicMock(testRPC) @@ -112,15 +109,6 @@ const checkNotifiedTransactionEvent = (expectedName: string, expectedTxType: Tra found.should.be.false; } -const createCodecHash = async (client?: Client): Promise =>{ - - if(!client){ - client = initClient(testRPC.endpoint()) - } - - return (await client.api()).createType('CodecHash') -} - describe('Subscriber, with a started new chain...', () => { before(async () => { // we are starting a chain from scratch @@ -164,24 +152,24 @@ describe('Subscriber, with a started new chain...', () => { describe('transferBalancesEventHandler', async () => { it('is transferBalances event, our addresses are not involved so a notification is not necessary', async () => { const event = await extrinsicMock.generateTransferEvent('//Charlie','//Dave') - - const result = await subject["eventScannerBased"]["_balanceTransferHandler"](event,await createCodecHash()) + const transfer = extractTransferInfoFromEvent(event, chainsInfo.polkadot, 1) + const result = await subject["eventScannerBased"]["_transferNotificationHandler"](transfer, '') result.should.be.true }); it('is transferBalances event 1', async () => { const event = await extrinsicMock.generateTransferEvent('//Alice','//Bob') - - const result = await subject["eventScannerBased"]["_balanceTransferHandler"](event,await createCodecHash()) + const transfer = extractTransferInfoFromEvent(event, chainsInfo.polkadot, 1) + const result = await subject["eventScannerBased"]["_transferNotificationHandler"](transfer, '') result.should.be.true }); it('is transferBalances event 2', async () => { const event = await extrinsicMock.generateTransferEvent('//Bob','//Alice') - - const result = await subject["eventScannerBased"]["_balanceTransferHandler"](event,await createCodecHash()) + const transfer = extractTransferInfoFromEvent(event, chainsInfo.polkadot, 1) + const result = await subject["eventScannerBased"]["_transferNotificationHandler"](transfer, '') result.should.be.true }); @@ -251,8 +239,8 @@ describe('Subscriber, with a started new chain...', () => { describe('transferBalancesEventHandler', async () => { it('is transferBalances event, but the notifier is broken', async () => { const event = await extrinsicMock.generateTransferEvent('//Alice','//Bob') - - const result = await subject["eventScannerBased"]["_balanceTransferHandler"](event,await createCodecHash()) + const transfer = extractTransferInfoFromEvent(event, chainsInfo.polkadot, 1) + const result = await subject["eventScannerBased"]["_transferNotificationHandler"](transfer, '') result.should.be.false }); diff --git a/yarn.lock b/yarn.lock index d4126f7..a53ac2e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -532,6 +532,18 @@ enabled "2.0.x" kuler "^2.0.0" +"@eslint-community/eslint-utils@^4.2.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + +"@eslint-community/regexpp@^4.4.0": + version "4.11.0" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.11.0.tgz#b0ffd0312b4a3fd2d6f77237e7248a5ad3a680ae" + integrity sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A== + "@eslint/eslintrc@^0.4.3": version "0.4.3" resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c" @@ -598,6 +610,27 @@ resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.4.0.tgz#45814aa329f30e4fe0ba49426f49dfccdd066426" integrity sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg== +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + "@polkadot-api/json-rpc-provider-proxy@0.0.1": version "0.0.1" resolved "https://registry.yarnpkg.com/@polkadot-api/json-rpc-provider-proxy/-/json-rpc-provider-proxy-0.0.1.tgz#bb5c943642cdf0ec7bc48c0a2647558b9fcd7bdb" @@ -646,123 +679,123 @@ resolved "https://registry.yarnpkg.com/@polkadot-api/utils/-/utils-0.0.1.tgz#908b22becac705149d7cc946532143d0fb003bfc" integrity sha512-3j+pRmlF9SgiYDabSdZsBSsN5XHbpXOAce1lWj56IEEaFZVjsiCaxDOA7C9nCcgfVXuvnbxqqEGQvnY+QfBAUw== -"@polkadot/api-augment@12.0.1": - version "12.0.1" - resolved "https://registry.yarnpkg.com/@polkadot/api-augment/-/api-augment-12.0.1.tgz#30c8f94e216591db02c6aadd84a56dbf7f9303ed" - integrity sha512-ZgjuqAnUnwoszccxljxY84LnUI1dR39xy7/fOmNtT4+WSHewB3uZneAWvIckXMANMZgzLaLagzQx+OmnSOuzlA== - dependencies: - "@polkadot/api-base" "12.0.1" - "@polkadot/rpc-augment" "12.0.1" - "@polkadot/types" "12.0.1" - "@polkadot/types-augment" "12.0.1" - "@polkadot/types-codec" "12.0.1" - "@polkadot/util" "^12.6.2" +"@polkadot/api-augment@12.3.1": + version "12.3.1" + resolved "https://registry.yarnpkg.com/@polkadot/api-augment/-/api-augment-12.3.1.tgz#07c1b510310868e01f89e4d2f2313595d068b228" + integrity sha512-KfofZVEUeTgLzcexdxKBT2vihazDheUoTLxbsa2ztmmw4UB/IjOL911y04pjg2obZQAI9B+oCyxJXyCfzauWEg== + dependencies: + "@polkadot/api-base" "12.3.1" + "@polkadot/rpc-augment" "12.3.1" + "@polkadot/types" "12.3.1" + "@polkadot/types-augment" "12.3.1" + "@polkadot/types-codec" "12.3.1" + "@polkadot/util" "^13.0.2" tslib "^2.6.2" -"@polkadot/api-base@12.0.1": - version "12.0.1" - resolved "https://registry.yarnpkg.com/@polkadot/api-base/-/api-base-12.0.1.tgz#0d55917a2d23b3d8a14734d5e90d85a21e554221" - integrity sha512-DaUPvmd0Fbbvlkd8X0ThF6C6jtupgvPKS4+9jMET+W56nUAttKnSA8rG30K7h4bMf9qKvj/IMGrQ0ZIOY0rbIg== +"@polkadot/api-base@12.3.1": + version "12.3.1" + resolved "https://registry.yarnpkg.com/@polkadot/api-base/-/api-base-12.3.1.tgz#084801da4e54820ec0e91c51a237bcd861665c1d" + integrity sha512-vNbxXNjn4APfXg+ui99gurX2Jzns+eezmWranxoGXT7q0mme1zAtWus5t4e+qe1qRjDNZZYPruF7YJA8dL5k8A== dependencies: - "@polkadot/rpc-core" "12.0.1" - "@polkadot/types" "12.0.1" - "@polkadot/util" "^12.6.2" + "@polkadot/rpc-core" "12.3.1" + "@polkadot/types" "12.3.1" + "@polkadot/util" "^13.0.2" rxjs "^7.8.1" tslib "^2.6.2" -"@polkadot/api-derive@12.0.1": - version "12.0.1" - resolved "https://registry.yarnpkg.com/@polkadot/api-derive/-/api-derive-12.0.1.tgz#182b27e1a5bb0fa033d7a56936ffa074ce3163f2" - integrity sha512-lENXzrCYzMQVxg8utGjGZQo/qW1iuJlHbmud1THnvUgYB36g41LR/YLSZEzyNkGT6q1W04Qe1z6+W59dWAYmkg== - dependencies: - "@polkadot/api" "12.0.1" - "@polkadot/api-augment" "12.0.1" - "@polkadot/api-base" "12.0.1" - "@polkadot/rpc-core" "12.0.1" - "@polkadot/types" "12.0.1" - "@polkadot/types-codec" "12.0.1" - "@polkadot/util" "^12.6.2" - "@polkadot/util-crypto" "^12.6.2" +"@polkadot/api-derive@12.3.1": + version "12.3.1" + resolved "https://registry.yarnpkg.com/@polkadot/api-derive/-/api-derive-12.3.1.tgz#2da05346fed18ff29ed2a581a3270591de11662c" + integrity sha512-2MbK1h4GcKEdSgDKKYI28iZESw0VOm0kekV6YGQflZNWe84jJOn2rohP8pACseUjQjwWDgbPPBvTlRZTk7zdAw== + dependencies: + "@polkadot/api" "12.3.1" + "@polkadot/api-augment" "12.3.1" + "@polkadot/api-base" "12.3.1" + "@polkadot/rpc-core" "12.3.1" + "@polkadot/types" "12.3.1" + "@polkadot/types-codec" "12.3.1" + "@polkadot/util" "^13.0.2" + "@polkadot/util-crypto" "^13.0.2" rxjs "^7.8.1" tslib "^2.6.2" -"@polkadot/api@12.0.1", "@polkadot/api@^12.0.1": - version "12.0.1" - resolved "https://registry.yarnpkg.com/@polkadot/api/-/api-12.0.1.tgz#3067a0466d9a645a8d3a30a772854dc3eae65fb5" - integrity sha512-l4z2SYTJs9CWab3qKPrmDkNj8+CGRWHgvq50vIxgBBvFKhSBO0TGBoJM5Mf38Tl6kw/3mJzRkKaG23+Y8LW9Rw== - dependencies: - "@polkadot/api-augment" "12.0.1" - "@polkadot/api-base" "12.0.1" - "@polkadot/api-derive" "12.0.1" - "@polkadot/keyring" "^12.6.2" - "@polkadot/rpc-augment" "12.0.1" - "@polkadot/rpc-core" "12.0.1" - "@polkadot/rpc-provider" "12.0.1" - "@polkadot/types" "12.0.1" - "@polkadot/types-augment" "12.0.1" - "@polkadot/types-codec" "12.0.1" - "@polkadot/types-create" "12.0.1" - "@polkadot/types-known" "12.0.1" - "@polkadot/util" "^12.6.2" - "@polkadot/util-crypto" "^12.6.2" +"@polkadot/api@12.3.1", "@polkadot/api@^12.0.1", "@polkadot/api@^12.2.3": + version "12.3.1" + resolved "https://registry.yarnpkg.com/@polkadot/api/-/api-12.3.1.tgz#bce62c902293295460832d15ee8fa2119a36ae42" + integrity sha512-VCrtadJRJttya5NhZ8slkD/UQyOZv4qABjagQMaG1eTZpn5k1wskmDUGdHrZZpYO5jBPewnCgaN8+LPKO2qiOw== + dependencies: + "@polkadot/api-augment" "12.3.1" + "@polkadot/api-base" "12.3.1" + "@polkadot/api-derive" "12.3.1" + "@polkadot/keyring" "^13.0.2" + "@polkadot/rpc-augment" "12.3.1" + "@polkadot/rpc-core" "12.3.1" + "@polkadot/rpc-provider" "12.3.1" + "@polkadot/types" "12.3.1" + "@polkadot/types-augment" "12.3.1" + "@polkadot/types-codec" "12.3.1" + "@polkadot/types-create" "12.3.1" + "@polkadot/types-known" "12.3.1" + "@polkadot/util" "^13.0.2" + "@polkadot/util-crypto" "^13.0.2" eventemitter3 "^5.0.1" rxjs "^7.8.1" tslib "^2.6.2" -"@polkadot/keyring@^12.6.2": - version "12.6.2" - resolved "https://registry.yarnpkg.com/@polkadot/keyring/-/keyring-12.6.2.tgz#6067e6294fee23728b008ac116e7e9db05cecb9b" - integrity sha512-O3Q7GVmRYm8q7HuB3S0+Yf/q/EB2egKRRU3fv9b3B7V+A52tKzA+vIwEmNVaD1g5FKW9oB97rmpggs0zaKFqHw== +"@polkadot/keyring@^13.0.2": + version "13.0.2" + resolved "https://registry.yarnpkg.com/@polkadot/keyring/-/keyring-13.0.2.tgz#05a655eb06c965ae5ee5f181d25916797ea50849" + integrity sha512-NeLbhyKDT5W8LI9seWTZGePxNTOVpDhv2018HSrEDwJq9Ie0C4TZhUf3KNERCkSveuThXjfQJMs+1CF33ZXPWw== dependencies: - "@polkadot/util" "12.6.2" - "@polkadot/util-crypto" "12.6.2" + "@polkadot/util" "13.0.2" + "@polkadot/util-crypto" "13.0.2" tslib "^2.6.2" -"@polkadot/networks@12.6.2", "@polkadot/networks@^12.6.2": - version "12.6.2" - resolved "https://registry.yarnpkg.com/@polkadot/networks/-/networks-12.6.2.tgz#791779fee1d86cc5b6cd371858eea9b7c3f8720d" - integrity sha512-1oWtZm1IvPWqvMrldVH6NI2gBoCndl5GEwx7lAuQWGr7eNL+6Bdc5K3Z9T0MzFvDGoi2/CBqjX9dRKo39pDC/w== +"@polkadot/networks@13.0.2", "@polkadot/networks@^13.0.2": + version "13.0.2" + resolved "https://registry.yarnpkg.com/@polkadot/networks/-/networks-13.0.2.tgz#0f8fc896b8fb2141212b6448739f4a00bc72b29c" + integrity sha512-ABAL+vug/gIwkdFEzeh87JoJd0YKrxSYg/HjUrZ+Zis2ucxQEKpvtCpJ34ku+YrjacBfVqIAkkwd3ZdIPGq9aQ== dependencies: - "@polkadot/util" "12.6.2" - "@substrate/ss58-registry" "^1.44.0" + "@polkadot/util" "13.0.2" + "@substrate/ss58-registry" "^1.46.0" tslib "^2.6.2" -"@polkadot/rpc-augment@12.0.1": - version "12.0.1" - resolved "https://registry.yarnpkg.com/@polkadot/rpc-augment/-/rpc-augment-12.0.1.tgz#256dbec4e76c64efda226bf5cb3c807242450f2f" - integrity sha512-mSVjr1aHcNFWq3tPb8Tntp1oFvc42zjurR+VHk0WIdJLkq7hVFO4X8j+Z5qKMomSE0thuhbnZm4Qgya8M9LNKQ== +"@polkadot/rpc-augment@12.3.1": + version "12.3.1" + resolved "https://registry.yarnpkg.com/@polkadot/rpc-augment/-/rpc-augment-12.3.1.tgz#9a896c4578753055ab25326243e716344a895a8a" + integrity sha512-/tZLl5IuQ4vdGlUAbd8x3ShZ35XDSeyknKHCC+9kIrM/+KIyoCYBob2RXP9uqX8m516AWkXUrjsSO6DFPBpRGg== dependencies: - "@polkadot/rpc-core" "12.0.1" - "@polkadot/types" "12.0.1" - "@polkadot/types-codec" "12.0.1" - "@polkadot/util" "^12.6.2" + "@polkadot/rpc-core" "12.3.1" + "@polkadot/types" "12.3.1" + "@polkadot/types-codec" "12.3.1" + "@polkadot/util" "^13.0.2" tslib "^2.6.2" -"@polkadot/rpc-core@12.0.1": - version "12.0.1" - resolved "https://registry.yarnpkg.com/@polkadot/rpc-core/-/rpc-core-12.0.1.tgz#031398576fd39c77dfec32c27f9e6e691ca34ebc" - integrity sha512-mSAvcUA+skCODKW4tJNR5fzxCmCHFYkLgKE8J3h7poaG1MX4xeSDaquvYFncC2wrhuP2Xxke1UYmFGZlrBq9tQ== +"@polkadot/rpc-core@12.3.1": + version "12.3.1" + resolved "https://registry.yarnpkg.com/@polkadot/rpc-core/-/rpc-core-12.3.1.tgz#6107c507c30839313e0325c82bffae9f1b08dbab" + integrity sha512-bNo26P20nRpLfANTK4sWEakxvqBJpKwAp/Gt7KlxoGgoTUbWFapyGKScFxp/pblycEziEbC+ZjkLMkaWaqi69g== dependencies: - "@polkadot/rpc-augment" "12.0.1" - "@polkadot/rpc-provider" "12.0.1" - "@polkadot/types" "12.0.1" - "@polkadot/util" "^12.6.2" + "@polkadot/rpc-augment" "12.3.1" + "@polkadot/rpc-provider" "12.3.1" + "@polkadot/types" "12.3.1" + "@polkadot/util" "^13.0.2" rxjs "^7.8.1" tslib "^2.6.2" -"@polkadot/rpc-provider@12.0.1": - version "12.0.1" - resolved "https://registry.yarnpkg.com/@polkadot/rpc-provider/-/rpc-provider-12.0.1.tgz#d56d1d674d5c79a3d1ad27b307601a387859b96d" - integrity sha512-3LyoGIl3lfDFVuajVZMvB+rVh5s2+PujdmHT4GFqH0XZm9tMBNzIT4kdC7VV5Ra728C6c6j1GTNJ0ARvxEPbww== - dependencies: - "@polkadot/keyring" "^12.6.2" - "@polkadot/types" "12.0.1" - "@polkadot/types-support" "12.0.1" - "@polkadot/util" "^12.6.2" - "@polkadot/util-crypto" "^12.6.2" - "@polkadot/x-fetch" "^12.6.2" - "@polkadot/x-global" "^12.6.2" - "@polkadot/x-ws" "^12.6.2" +"@polkadot/rpc-provider@12.3.1": + version "12.3.1" + resolved "https://registry.yarnpkg.com/@polkadot/rpc-provider/-/rpc-provider-12.3.1.tgz#90bfbb8518bd63d94141bf4d2643c89b89e61413" + integrity sha512-Tg1Oj/1ldivqwnnOWepcNHEHYgpOBffxlrZMEXH1XX6D3AZaUhAWbatizyisydpuMbknTQ9FGYSnb9rOc2QBJw== + dependencies: + "@polkadot/keyring" "^13.0.2" + "@polkadot/types" "12.3.1" + "@polkadot/types-support" "12.3.1" + "@polkadot/util" "^13.0.2" + "@polkadot/util-crypto" "^13.0.2" + "@polkadot/x-fetch" "^13.0.2" + "@polkadot/x-global" "^13.0.2" + "@polkadot/x-ws" "^13.0.2" eventemitter3 "^5.0.1" mock-socket "^9.3.1" nock "^13.5.0" @@ -770,93 +803,93 @@ optionalDependencies: "@substrate/connect" "0.8.10" -"@polkadot/types-augment@12.0.1": - version "12.0.1" - resolved "https://registry.yarnpkg.com/@polkadot/types-augment/-/types-augment-12.0.1.tgz#4f3cbc03d76775dc48417f3a6e74297e142e7c48" - integrity sha512-VwzAUJCLwuVabRFlUQOTgovYHXQdrgHF4Aaqxb4gTQEsaDnpdcGBypy1dS861qROMOlSMySanO82o3N3Nvexfg== +"@polkadot/types-augment@12.3.1": + version "12.3.1" + resolved "https://registry.yarnpkg.com/@polkadot/types-augment/-/types-augment-12.3.1.tgz#c7853049829d39d35b94fb01a84c1ea0d61ca9e0" + integrity sha512-I3ggJt7W3UOScP6WA6PNmNsmpCfZtXkRJvSJkX7bi2LsSm/iF0xo0KdpQK02dHu7nGRFD9O5cSoVawzZJifGLA== dependencies: - "@polkadot/types" "12.0.1" - "@polkadot/types-codec" "12.0.1" - "@polkadot/util" "^12.6.2" + "@polkadot/types" "12.3.1" + "@polkadot/types-codec" "12.3.1" + "@polkadot/util" "^13.0.2" tslib "^2.6.2" -"@polkadot/types-codec@12.0.1": - version "12.0.1" - resolved "https://registry.yarnpkg.com/@polkadot/types-codec/-/types-codec-12.0.1.tgz#97f9f470216be2d800e0b6083fba3caa29cf7a78" - integrity sha512-yF4ZOUlxzTMYwWw7CrXyehhQQhXnaojATTPbIDo3PRHKHAiZes1MXR6qHaBU7p/S6EaUPNOKBQmopSVYN+zUVg== +"@polkadot/types-codec@12.3.1": + version "12.3.1" + resolved "https://registry.yarnpkg.com/@polkadot/types-codec/-/types-codec-12.3.1.tgz#4eb113a5a2c9e7784f1393db4d6cfe39b24da014" + integrity sha512-yZ4exsQI+eVkE/fZNuJBOajAgOH/YncKWOOf0N4lc6iq28oYp22DCAXc50Ym372l4HO+uhC9QdMPH9EiWwT2pQ== dependencies: - "@polkadot/util" "^12.6.2" - "@polkadot/x-bigint" "^12.6.2" + "@polkadot/util" "^13.0.2" + "@polkadot/x-bigint" "^13.0.2" tslib "^2.6.2" -"@polkadot/types-create@12.0.1": - version "12.0.1" - resolved "https://registry.yarnpkg.com/@polkadot/types-create/-/types-create-12.0.1.tgz#e7337808ca0aa089a5594abdbe939d998202b205" - integrity sha512-zPzjRx+AjZk6F5VeAZnEx5ZF5cl0zngp3Ez0HbkM+5Jhh2d+j0dQkfNpf6h26prMTjYItsXMrr1xxWv1GgcFjg== +"@polkadot/types-create@12.3.1": + version "12.3.1" + resolved "https://registry.yarnpkg.com/@polkadot/types-create/-/types-create-12.3.1.tgz#867ff2971f0d1c7b68788eb3b9f7c060fcbc648f" + integrity sha512-Jf9BByWB64FPW3lM5/Mcc/foyPJ3L9t0QwHVHaYWaonZt6l7SPX71rQmD7twJiTj9q1d1WidDKg/TtRDNbm1yA== dependencies: - "@polkadot/types-codec" "12.0.1" - "@polkadot/util" "^12.6.2" + "@polkadot/types-codec" "12.3.1" + "@polkadot/util" "^13.0.2" tslib "^2.6.2" -"@polkadot/types-known@12.0.1": - version "12.0.1" - resolved "https://registry.yarnpkg.com/@polkadot/types-known/-/types-known-12.0.1.tgz#c55d2b1e58c01e9bbd89743aca1434568ad308e0" - integrity sha512-8VVSy9MthWNqzCQMPLR02GlJhYb4H7SlAk5/9OdAAuoA86svFItQTaKyfUGC26I3uaKtS3/8RgPo3SihJgPHEQ== +"@polkadot/types-known@12.3.1": + version "12.3.1" + resolved "https://registry.yarnpkg.com/@polkadot/types-known/-/types-known-12.3.1.tgz#11aade98492e37c2e6d095c78fcd229a212ee933" + integrity sha512-G8t0uiIW1iu3KwylHDPnqdHxg5qwBxzPZQJvsjnGx2qBUk2VqXditKWcNFLEwCTnJPL95t2AzEO711lS99WRbg== dependencies: - "@polkadot/networks" "^12.6.2" - "@polkadot/types" "12.0.1" - "@polkadot/types-codec" "12.0.1" - "@polkadot/types-create" "12.0.1" - "@polkadot/util" "^12.6.2" + "@polkadot/networks" "^13.0.2" + "@polkadot/types" "12.3.1" + "@polkadot/types-codec" "12.3.1" + "@polkadot/types-create" "12.3.1" + "@polkadot/util" "^13.0.2" tslib "^2.6.2" -"@polkadot/types-support@12.0.1": - version "12.0.1" - resolved "https://registry.yarnpkg.com/@polkadot/types-support/-/types-support-12.0.1.tgz#a5b65fe351a26348973a9bf019b3645be4637510" - integrity sha512-5Y5rTmgG0XSPIQR32+fdtvhU+VzahCs+vGnU9yuvT570aLHVqu0nNHRQa/uOtpLcHwgjZPr3ljOgAo0ViaL1UA== +"@polkadot/types-support@12.3.1": + version "12.3.1" + resolved "https://registry.yarnpkg.com/@polkadot/types-support/-/types-support-12.3.1.tgz#7111f3a7a55a5f4f50b11450c62b7fe5340e4a21" + integrity sha512-TwL5M5HkZ4jQGKekD+qJFLba7UXWASfwlPy2OpKj0LOnnmq4tudXgN13UFdQ7HoOmisPhr+vYo9vteYeBZ0jTA== dependencies: - "@polkadot/util" "^12.6.2" + "@polkadot/util" "^13.0.2" tslib "^2.6.2" -"@polkadot/types@12.0.1": - version "12.0.1" - resolved "https://registry.yarnpkg.com/@polkadot/types/-/types-12.0.1.tgz#800593a91ec752c43fb23c8e606ae923db59f315" - integrity sha512-4R3hwlMMThdF43DmbWnZTh2nQ1VwBJxKNx5mr7Pq8FereepW62W+1TkwcdekPtPZ+PmcbjmKxzt7JNmiXxjf+w== - dependencies: - "@polkadot/keyring" "^12.6.2" - "@polkadot/types-augment" "12.0.1" - "@polkadot/types-codec" "12.0.1" - "@polkadot/types-create" "12.0.1" - "@polkadot/util" "^12.6.2" - "@polkadot/util-crypto" "^12.6.2" +"@polkadot/types@12.3.1": + version "12.3.1" + resolved "https://registry.yarnpkg.com/@polkadot/types/-/types-12.3.1.tgz#46a44aaa672d9c3c8598bbf8b8668e575c55f76a" + integrity sha512-4MkTF1znpgp9mZc/ZZPdFe7/5it9v+EJmzXc/DEOX9kVWs2BuKOWopzOFyO3reVUUB+v7dxfSOArSsxkMUcuoA== + dependencies: + "@polkadot/keyring" "^13.0.2" + "@polkadot/types-augment" "12.3.1" + "@polkadot/types-codec" "12.3.1" + "@polkadot/types-create" "12.3.1" + "@polkadot/util" "^13.0.2" + "@polkadot/util-crypto" "^13.0.2" rxjs "^7.8.1" tslib "^2.6.2" -"@polkadot/util-crypto@12.6.2", "@polkadot/util-crypto@^12.6.2": - version "12.6.2" - resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-12.6.2.tgz#d2d51010e8e8ca88951b7d864add797dad18bbfc" - integrity sha512-FEWI/dJ7wDMNN1WOzZAjQoIcCP/3vz3wvAp5QQm+lOrzOLj0iDmaIGIcBkz8HVm3ErfSe/uKP0KS4jgV/ib+Mg== +"@polkadot/util-crypto@13.0.2", "@polkadot/util-crypto@^13.0.2": + version "13.0.2" + resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-13.0.2.tgz#fee602bcb39e9424300410f4144f170ee2a29292" + integrity sha512-woUsJJ6zd/caL7U+D30a5oM/+WK9iNI00Y8aNUHSj6Zq/KPzK9uqDBaLGWwlgrejoMQkxxiU2X0f2LzP15AtQg== dependencies: "@noble/curves" "^1.3.0" "@noble/hashes" "^1.3.3" - "@polkadot/networks" "12.6.2" - "@polkadot/util" "12.6.2" + "@polkadot/networks" "13.0.2" + "@polkadot/util" "13.0.2" "@polkadot/wasm-crypto" "^7.3.2" "@polkadot/wasm-util" "^7.3.2" - "@polkadot/x-bigint" "12.6.2" - "@polkadot/x-randomvalues" "12.6.2" + "@polkadot/x-bigint" "13.0.2" + "@polkadot/x-randomvalues" "13.0.2" "@scure/base" "^1.1.5" tslib "^2.6.2" -"@polkadot/util@12.6.2", "@polkadot/util@^12.6.2": - version "12.6.2" - resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-12.6.2.tgz#9396eff491221e1f0fd28feac55fc16ecd61a8dc" - integrity sha512-l8TubR7CLEY47240uki0TQzFvtnxFIO7uI/0GoWzpYD/O62EIAMRsuY01N4DuwgKq2ZWD59WhzsLYmA5K6ksdw== +"@polkadot/util@13.0.2", "@polkadot/util@^13.0.2": + version "13.0.2" + resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-13.0.2.tgz#f0a2572d74730fda8dfd690b60d53c131a688f3b" + integrity sha512-/6bS9sfhJLhs8QuqWaR1eRapzfDdGC5XAQZEPL9NN5sTTA7HxWos8rVleai0UERm8QUMabjZ9rK9KpzbXl7ojg== dependencies: - "@polkadot/x-bigint" "12.6.2" - "@polkadot/x-global" "12.6.2" - "@polkadot/x-textdecoder" "12.6.2" - "@polkadot/x-textencoder" "12.6.2" + "@polkadot/x-bigint" "13.0.2" + "@polkadot/x-global" "13.0.2" + "@polkadot/x-textdecoder" "13.0.2" + "@polkadot/x-textencoder" "13.0.2" "@types/bn.js" "^5.1.5" bn.js "^5.2.1" tslib "^2.6.2" @@ -914,62 +947,62 @@ dependencies: tslib "^2.6.2" -"@polkadot/x-bigint@12.6.2", "@polkadot/x-bigint@^12.6.2": - version "12.6.2" - resolved "https://registry.yarnpkg.com/@polkadot/x-bigint/-/x-bigint-12.6.2.tgz#59b7a615f205ae65e1ac67194aefde94d3344580" - integrity sha512-HSIk60uFPX4GOFZSnIF7VYJz7WZA7tpFJsne7SzxOooRwMTWEtw3fUpFy5cYYOeLh17/kHH1Y7SVcuxzVLc74Q== +"@polkadot/x-bigint@13.0.2", "@polkadot/x-bigint@^13.0.2": + version "13.0.2" + resolved "https://registry.yarnpkg.com/@polkadot/x-bigint/-/x-bigint-13.0.2.tgz#25adca9ce0c5ed691f9bced283f44f7e7d824300" + integrity sha512-h2jKT/UaxiEal8LhQeH6+GCjO7GwEqVAD2SNYteCOXff6yNttqAZYJuHZsndbVjVNwqRNf8D5q/zZkD0HUd6xQ== dependencies: - "@polkadot/x-global" "12.6.2" + "@polkadot/x-global" "13.0.2" tslib "^2.6.2" -"@polkadot/x-fetch@^12.6.2": - version "12.6.2" - resolved "https://registry.yarnpkg.com/@polkadot/x-fetch/-/x-fetch-12.6.2.tgz#b1bca028db90263bafbad2636c18d838d842d439" - integrity sha512-8wM/Z9JJPWN1pzSpU7XxTI1ldj/AfC8hKioBlUahZ8gUiJaOF7K9XEFCrCDLis/A1BoOu7Ne6WMx/vsJJIbDWw== +"@polkadot/x-fetch@^13.0.2": + version "13.0.2" + resolved "https://registry.yarnpkg.com/@polkadot/x-fetch/-/x-fetch-13.0.2.tgz#841d901fae36cbc4157297324ca0d73fbe4d200e" + integrity sha512-B/gf9iriUr6za/Ui7zIFBfHz7UBZ68rJEIteWHx1UHRCZPcLqv+hgpev6xIGrkfFljI0/lI7IwtN2qy6HYzFBg== dependencies: - "@polkadot/x-global" "12.6.2" + "@polkadot/x-global" "13.0.2" node-fetch "^3.3.2" tslib "^2.6.2" -"@polkadot/x-global@12.6.2", "@polkadot/x-global@^12.6.2": - version "12.6.2" - resolved "https://registry.yarnpkg.com/@polkadot/x-global/-/x-global-12.6.2.tgz#31d4de1c3d4c44e4be3219555a6d91091decc4ec" - integrity sha512-a8d6m+PW98jmsYDtAWp88qS4dl8DyqUBsd0S+WgyfSMtpEXu6v9nXDgPZgwF5xdDvXhm+P0ZfVkVTnIGrScb5g== +"@polkadot/x-global@13.0.2", "@polkadot/x-global@^13.0.2": + version "13.0.2" + resolved "https://registry.yarnpkg.com/@polkadot/x-global/-/x-global-13.0.2.tgz#77afc4fbd4cfac8ba78cf120836f30ecc7322a74" + integrity sha512-OoNIXLB5y8vIKpk4R+XmpDPhipNXWSUvEwUnpQT7NAxNLmzgMq1FhbrwBWWPRNHPrQonp7mqxV/X+v5lv1HW/g== dependencies: tslib "^2.6.2" -"@polkadot/x-randomvalues@12.6.2": - version "12.6.2" - resolved "https://registry.yarnpkg.com/@polkadot/x-randomvalues/-/x-randomvalues-12.6.2.tgz#13fe3619368b8bf5cb73781554859b5ff9d900a2" - integrity sha512-Vr8uG7rH2IcNJwtyf5ebdODMcr0XjoCpUbI91Zv6AlKVYOGKZlKLYJHIwpTaKKB+7KPWyQrk4Mlym/rS7v9feg== +"@polkadot/x-randomvalues@13.0.2": + version "13.0.2" + resolved "https://registry.yarnpkg.com/@polkadot/x-randomvalues/-/x-randomvalues-13.0.2.tgz#78ae28b345895cc816ffcad0b336c31cadfcf928" + integrity sha512-SGj+L0H/7TWZtSmtkWlixO4DFzXDdluI0UscN2h285os2Ns8PnmBbue+iJ8PVSzpY1BOxd66gvkkpboPz+jXFQ== dependencies: - "@polkadot/x-global" "12.6.2" + "@polkadot/x-global" "13.0.2" tslib "^2.6.2" -"@polkadot/x-textdecoder@12.6.2": - version "12.6.2" - resolved "https://registry.yarnpkg.com/@polkadot/x-textdecoder/-/x-textdecoder-12.6.2.tgz#b86da0f8e8178f1ca31a7158257e92aea90b10e4" - integrity sha512-M1Bir7tYvNappfpFWXOJcnxUhBUFWkUFIdJSyH0zs5LmFtFdbKAeiDXxSp2Swp5ddOZdZgPac294/o2TnQKN1w== +"@polkadot/x-textdecoder@13.0.2": + version "13.0.2" + resolved "https://registry.yarnpkg.com/@polkadot/x-textdecoder/-/x-textdecoder-13.0.2.tgz#662a6855af8e7a5af17f86890e59ab44f829243a" + integrity sha512-mauglOkTJxLGmLwLc3J5Jlq/W+SHP53eiy3F8/8JxxfnXrZKgWoQXGpvXYPjFnMZj0MzDSy/6GjyGWnDCgdQFA== dependencies: - "@polkadot/x-global" "12.6.2" + "@polkadot/x-global" "13.0.2" tslib "^2.6.2" -"@polkadot/x-textencoder@12.6.2": - version "12.6.2" - resolved "https://registry.yarnpkg.com/@polkadot/x-textencoder/-/x-textencoder-12.6.2.tgz#81d23bd904a2c36137a395c865c5fefa21abfb44" - integrity sha512-4N+3UVCpI489tUJ6cv3uf0PjOHvgGp9Dl+SZRLgFGt9mvxnvpW/7+XBADRMtlG4xi5gaRK7bgl5bmY6OMDsNdw== +"@polkadot/x-textencoder@13.0.2": + version "13.0.2" + resolved "https://registry.yarnpkg.com/@polkadot/x-textencoder/-/x-textencoder-13.0.2.tgz#5e178e0f759df50592e6870346c8db2a445af957" + integrity sha512-Lq08H2OnVXj97uaOwg7tcmRS7a4VJYkHEeWO4FyEMOk6P6lU6W8OVNjjxG0se9PCEgmyZPUDbJI//1ynzP4cXw== dependencies: - "@polkadot/x-global" "12.6.2" + "@polkadot/x-global" "13.0.2" tslib "^2.6.2" -"@polkadot/x-ws@^12.6.2": - version "12.6.2" - resolved "https://registry.yarnpkg.com/@polkadot/x-ws/-/x-ws-12.6.2.tgz#b99094d8e53a03be1de903d13ba59adaaabc767a" - integrity sha512-cGZWo7K5eRRQCRl2LrcyCYsrc3lRbTlixZh3AzgU8uX4wASVGRlNWi/Hf4TtHNe1ExCDmxabJzdIsABIfrr7xw== +"@polkadot/x-ws@^13.0.2": + version "13.0.2" + resolved "https://registry.yarnpkg.com/@polkadot/x-ws/-/x-ws-13.0.2.tgz#d0392a87adcba851a44fc6f7f56792e529228f3e" + integrity sha512-nC5e2eY5D5ZR5teQOB7ib+dWLbmNws86cTz3BjKCalSMBBIn6i3V9ElgABpierBmnSJe9D94EyrH1BxdVfDxUg== dependencies: - "@polkadot/x-global" "12.6.2" + "@polkadot/x-global" "13.0.2" tslib "^2.6.2" - ws "^8.15.1" + ws "^8.16.0" "@scure/base@^1.1.1", "@scure/base@^1.1.5": version "1.1.6" @@ -1423,10 +1456,10 @@ "@substrate/connect-known-chains" "^1.1.4" rxjs "^7.8.1" -"@substrate/ss58-registry@^1.44.0": - version "1.47.0" - resolved "https://registry.yarnpkg.com/@substrate/ss58-registry/-/ss58-registry-1.47.0.tgz#99b11fd3c16657f5eae483b3df7c545ca756d1fc" - integrity sha512-6kuIJedRcisUJS2pgksEH2jZf3hfSIVzqtFzs/AyjTW3ETbMg5q1Bb7VWa0WYaT6dTrEXp/6UoXM5B9pSIUmcw== +"@substrate/ss58-registry@^1.46.0": + version "1.49.0" + resolved "https://registry.yarnpkg.com/@substrate/ss58-registry/-/ss58-registry-1.49.0.tgz#ed9507316d13f49b2bccb65f08ec97180f71fc39" + integrity sha512-leW6Ix4LD7XgvxT7+aobPWSw+WvPcN2Rxof1rmd0mNC5t2n99k1N7UNEvz7YEFSOUeHWmKIY7F5q8KeIqYoHfA== "@szmarczak/http-timer@^4.0.0": version "4.0.6" @@ -1500,11 +1533,6 @@ dependencies: "@types/node" "*" -"@types/eslint-visitor-keys@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" - integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag== - "@types/express-serve-static-core@^4.17.18": version "4.19.0" resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.19.0.tgz#3ae8ab3767d98d0b682cda063c3339e1e86ccfaa" @@ -1547,7 +1575,7 @@ resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.4.tgz#7eb47726c391b7345a6ec35ad7f4de469cf5ba4f" integrity sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA== -"@types/json-schema@^7.0.3": +"@types/json-schema@^7.0.9": version "7.0.15" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== @@ -1613,6 +1641,11 @@ dependencies: "@types/node" "*" +"@types/semver@^7.3.12": + version "7.5.8" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.8.tgz#8268a8c57a3e4abd25c165ecd36237db7948a55e" + integrity sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ== + "@types/send@*": version "0.17.4" resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.4.tgz#6619cd24e7270793702e4e6a4b958a9010cfc57a" @@ -1680,48 +1713,89 @@ "@types/node" "*" "@types/webidl-conversions" "*" -"@typescript-eslint/eslint-plugin@2.34.0": - version "2.34.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.34.0.tgz#6f8ce8a46c7dea4a6f1d171d2bb8fbae6dac2be9" - integrity sha512-4zY3Z88rEE99+CNvTbXSyovv2z9PNOVffTWD2W8QF5s2prBQtwN2zadqERcrHpcR7O/+KMI3fcTAmUUhK/iQcQ== - dependencies: - "@typescript-eslint/experimental-utils" "2.34.0" - functional-red-black-tree "^1.0.1" - regexpp "^3.0.0" - tsutils "^3.17.1" - -"@typescript-eslint/experimental-utils@2.34.0": - version "2.34.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz#d3524b644cdb40eebceca67f8cf3e4cc9c8f980f" - integrity sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA== - dependencies: - "@types/json-schema" "^7.0.3" - "@typescript-eslint/typescript-estree" "2.34.0" - eslint-scope "^5.0.0" - eslint-utils "^2.0.0" - -"@typescript-eslint/parser@2.34.0": - version "2.34.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.34.0.tgz#50252630ca319685420e9a39ca05fe185a256bc8" - integrity sha512-03ilO0ucSD0EPTw2X4PntSIRFtDPWjrVq7C3/Z3VQHRC7+13YB55rcJI3Jt+YgeHbjUdJPcPa7b23rXCBokuyA== - dependencies: - "@types/eslint-visitor-keys" "^1.0.0" - "@typescript-eslint/experimental-utils" "2.34.0" - "@typescript-eslint/typescript-estree" "2.34.0" - eslint-visitor-keys "^1.1.0" +"@typescript-eslint/eslint-plugin@^5.26.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz#aeef0328d172b9e37d9bab6dbc13b87ed88977db" + integrity sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag== + dependencies: + "@eslint-community/regexpp" "^4.4.0" + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/type-utils" "5.62.0" + "@typescript-eslint/utils" "5.62.0" + debug "^4.3.4" + graphemer "^1.4.0" + ignore "^5.2.0" + natural-compare-lite "^1.4.0" + semver "^7.3.7" + tsutils "^3.21.0" + +"@typescript-eslint/parser@^5.26.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.62.0.tgz#1b63d082d849a2fcae8a569248fbe2ee1b8a56c7" + integrity sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA== + dependencies: + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/typescript-estree" "5.62.0" + debug "^4.3.4" + +"@typescript-eslint/scope-manager@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz#d9457ccc6a0b8d6b37d0eb252a23022478c5460c" + integrity sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w== + dependencies: + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/visitor-keys" "5.62.0" + +"@typescript-eslint/type-utils@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz#286f0389c41681376cdad96b309cedd17d70346a" + integrity sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew== + dependencies: + "@typescript-eslint/typescript-estree" "5.62.0" + "@typescript-eslint/utils" "5.62.0" + debug "^4.3.4" + tsutils "^3.21.0" + +"@typescript-eslint/types@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" + integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== + +"@typescript-eslint/typescript-estree@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b" + integrity sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA== + dependencies: + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/visitor-keys" "5.62.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.3.7" + tsutils "^3.21.0" + +"@typescript-eslint/utils@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.62.0.tgz#141e809c71636e4a75daa39faed2fb5f4b10df86" + integrity sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@types/json-schema" "^7.0.9" + "@types/semver" "^7.3.12" + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/typescript-estree" "5.62.0" + eslint-scope "^5.1.1" + semver "^7.3.7" -"@typescript-eslint/typescript-estree@2.34.0": - version "2.34.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz#14aeb6353b39ef0732cc7f1b8285294937cf37d5" - integrity sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg== +"@typescript-eslint/visitor-keys@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz#2174011917ce582875954ffe2f6912d5931e353e" + integrity sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw== dependencies: - debug "^4.1.1" - eslint-visitor-keys "^1.1.0" - glob "^7.1.6" - is-glob "^4.0.1" - lodash "^4.17.15" - semver "^7.3.2" - tsutils "^3.17.1" + "@typescript-eslint/types" "5.62.0" + eslint-visitor-keys "^3.3.0" "@ungap/promise-all-settled@1.1.2": version "1.1.2" @@ -1878,6 +1952,11 @@ array-flatten@1.1.1: resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + assertion-error@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" @@ -1959,6 +2038,13 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +braces@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== + dependencies: + fill-range "^7.1.1" + braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" @@ -2230,6 +2316,13 @@ debug@4.x, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: dependencies: ms "2.1.2" +debug@^4.3.4: + version "4.3.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.6.tgz#2ab2c38fbaffebf8aa95fdfe6d88438c7a13c52b" + integrity sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg== + dependencies: + ms "2.1.2" + decamelize@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" @@ -2298,6 +2391,13 @@ diff@^5.0.0: resolved "https://registry.yarnpkg.com/diff/-/diff-5.2.0.tgz#26ded047cd1179b78b9537d5ef725503ce1ae531" integrity sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A== +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + docker-cli-js@^2.7.1: version "2.10.0" resolved "https://registry.yarnpkg.com/docker-cli-js/-/docker-cli-js-2.10.0.tgz#460996595c9e2f74a97ff39e330ca708f36ba5dd" @@ -2395,7 +2495,7 @@ escape-string-regexp@^1.0.5: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== -eslint-scope@^5.0.0, eslint-scope@^5.1.1: +eslint-scope@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== @@ -2403,7 +2503,7 @@ eslint-scope@^5.0.0, eslint-scope@^5.1.1: esrecurse "^4.3.0" estraverse "^4.1.1" -eslint-utils@^2.0.0, eslint-utils@^2.1.0: +eslint-utils@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== @@ -2420,6 +2520,11 @@ eslint-visitor-keys@^2.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== +eslint-visitor-keys@^3.3.0: + version "3.4.3" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" + integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== + eslint@7.32.0: version "7.32.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d" @@ -2561,6 +2666,17 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== +fast-glob@^3.2.9: + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" @@ -2578,6 +2694,13 @@ fast-xml-parser@4.2.5: dependencies: strnum "^1.0.5" +fastq@^1.6.0: + version "1.17.1" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" + integrity sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w== + dependencies: + reusify "^1.0.4" + fecha@^4.2.0: version "4.2.3" resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.3.tgz#4d9ccdbc61e8629b259fdca67e65891448d569fd" @@ -2605,6 +2728,13 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== + dependencies: + to-regex-range "^5.0.1" + finalhandler@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" @@ -2753,7 +2883,7 @@ glob@7.2.0: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.1.3, glob@^7.1.6: +glob@^7.1.3: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -2772,6 +2902,18 @@ globals@^13.6.0, globals@^13.9.0: dependencies: type-fest "^0.20.2" +globby@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + gopd@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" @@ -2805,6 +2947,11 @@ graceful-fs@^4.1.6, graceful-fs@^4.2.0: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== +graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== + growl@1.10.5: version "1.10.5" resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" @@ -2889,6 +3036,11 @@ ignore@^4.0.6: resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== +ignore@^5.2.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" + integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== + import-fresh@^3.0.0, import-fresh@^3.2.1: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" @@ -2950,7 +3102,7 @@ is-fullwidth-code-point@^3.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== @@ -3187,11 +3339,24 @@ merge-descriptors@1.0.1: resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== +micromatch@^4.0.4: + version "4.0.7" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.7.tgz#33e8190d9fe474a9895525f5618eee136d46c2e5" + integrity sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q== + dependencies: + braces "^3.0.3" + picomatch "^2.3.1" + mime-db@1.52.0: version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" @@ -3345,6 +3510,11 @@ nanoid@3.3.1: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== +natural-compare-lite@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" + integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -3534,6 +3704,11 @@ path-to-regexp@^6.2.1: resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.2.2.tgz#324377a83e5049cbecadc5554d6a63a9a4866b36" integrity sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw== +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + pathval@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" @@ -3544,7 +3719,7 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== -picomatch@^2.0.4, picomatch@^2.2.1: +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== @@ -3606,6 +3781,11 @@ qs@6.11.0: dependencies: side-channel "^1.0.4" +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -3644,7 +3824,7 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" -regexpp@^3.0.0, regexpp@^3.1.0: +regexpp@^3.1.0: version "3.2.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== @@ -3671,6 +3851,11 @@ responselike@^2.0.0: dependencies: lowercase-keys "^2.0.0" +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + rimraf@^3.0.0, rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" @@ -3678,6 +3863,13 @@ rimraf@^3.0.0, rimraf@^3.0.2: dependencies: glob "^7.1.3" +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + rxjs@^7.8.1: version "7.8.1" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" @@ -3710,13 +3902,18 @@ semver-compare@^1.0.0: resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" integrity sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow== -semver@^7.2.1, semver@^7.3.2: +semver@^7.2.1: version "7.6.0" resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.0.tgz#1a46a4db4bffcccd97b743b5005c8325f23d4e2d" integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== dependencies: lru-cache "^6.0.0" +semver@^7.3.7: + version "7.6.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== + send@0.18.0: version "0.18.0" resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" @@ -3816,6 +4013,11 @@ sinon@13.0.2: nise "^5.1.1" supports-color "^7.2.0" +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + slice-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" @@ -4024,7 +4226,7 @@ tslib@^2.1.0, tslib@^2.3.1, tslib@^2.6.2: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== -tsutils@^3.17.1: +tsutils@^3.21.0: version "3.21.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== @@ -4206,7 +4408,12 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== -ws@^8.15.1, ws@^8.8.1: +ws@^8.16.0: + version "8.18.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc" + integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== + +ws@^8.8.1: version "8.16.0" resolved "https://registry.yarnpkg.com/ws/-/ws-8.16.0.tgz#d1cd774f36fbc07165066a60e40323eab6446fd4" integrity sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==