diff --git a/.gitignore b/.gitignore index 830a34c77..c2c428850 100644 --- a/.gitignore +++ b/.gitignore @@ -120,3 +120,7 @@ yalc.lock .idea/ .envrc .vscode + +# local-network override mode files +tap-contracts.json +config/config.yaml \ No newline at end of file diff --git a/README.md b/README.md index 1f02734ff..d58424fc9 100644 --- a/README.md +++ b/README.md @@ -44,107 +44,145 @@ $ graph-indexer-agent start --help Start the agent -Ethereum - --ethereum Ethereum node or provider URL [string] [required] - --ethereum-network Ethereum network [string] [default: "mainnet"] - --ethereum-polling-interval Polling interval for the Ethereum provider (ms) - [number] [default: 4000] - --gas-increase-timeout Time (in seconds) after which transactions will - be resubmitted with a higher gas price - [number] [default: 240] - --gas-increase-factor Factor by which gas prices are increased when - resubmitting transactions [number] [default: 1.2] - --gas-price-max The maximum gas price (gwei) to use for - transactions [deprecated] [number] [default: 100] - --base-fee-per-gas-max The maximum base fee per gas (gwei) to use for - transactions, for legacy transactions this will - be treated as the max gas price [number] - --transaction-attempts The maximum number of transaction attempts (Use 0 - for unlimited) [number] [default: 0] - --mnemonic Mnemonic for the operator wallet +Indexer Infrastructure + --indexer-management-port Port to serve the indexer management API at + [number] [default: 8000] + --metrics-port Port to serve Prometheus metrics at + [number] [default: 7300] + --syncing-port Port to serve the network subgraph and other + syncing data for indexer service at + [number] [default: 8002] + --log-level Log level [string] [default: "debug"] + --polling-interval Polling interval for data collection + [number] [default: 120000] + --ipfs-endpoint IPFS endpoint for querying manifests. + [string] [required] [default: "https://ipfs.network.thegraph.com"] + --graph-node-query-endpoint Graph Node endpoint for querying subgraphs [string] [required] - --indexer-address Ethereum address of the indexer + --graph-node-status-endpoint Graph Node endpoint for indexing statuses + etc. [string] [required] + --graph-node-admin-endpoint Graph Node endpoint for applying and + updating subgraph deployments [string] [required] + --enable-auto-migration-support Auto migrate allocations from L1 to L2 + (multi-network mode must be enabled) + [boolean] [default: false] + --deployment-management Subgraph deployments management mode + [choices: "auto", "manual"] [default: "auto"] + --public-indexer-url Indexer endpoint for receiving requests from + the network [string] [required] + --indexer-geo-coordinates Coordinates describing the Indexer's + location using latitude and longitude + [string] [default: ["31.780715","-41.179504"]] + --restake-rewards Restake claimed indexer rewards, if set to + 'false' rewards will be returned to the + wallet [boolean] [default: true] + --allocation-management Indexer agent allocation management + automation mode (auto|manual) + [string] [default: "auto"] + --auto-allocation-min-batch-size Minimum number of allocation transactions + inside a batch for auto allocation + management. No obvious upperbound, with + default of 1 [number] [default: 1] -Indexer Infrastructure - --graph-node-query-endpoint Graph Node endpoint for querying - subgraphs [string] [required] - --graph-node-status-endpoint Graph Node endpoint for indexing - statuses etc. [string] [required] - --graph-node-admin-endpoint Graph Node endpoint for applying and - updating subgraph deployments +Postgres + --postgres-host Postgres host [string] [required] + --postgres-port Postgres port [number] [default: 5432] + --postgres-username Postgres username [string] [default: "postgres"] + --postgres-password Postgres password [string] [default: ""] + --postgres-sslenabled Postgres SSL Enabled [boolean] [default: "false"] + --postgres-database Postgres database name [string] [required] + --postgres-pool-size Postgres maximum connection pool size + [number] [default: 50] + +Ethereum + --network-provider, --ethereum Ethereum node or provider URL [string] [required] - --public-indexer-url Indexer endpoint for receiving requests - from the network [string] [required] - --indexer-geo-coordinates Coordinates describing the Indexer's - location using latitude and longitude - [array] [default: ["31.780715","-41.179504"]] - --index-node-ids Node IDs of Graph nodes to use for - indexing (separated by commas) - [array] [required] - --indexer-management-port Port to serve the indexer management API - at [number] [default: 8000] - --metrics-port Port to serve Prometheus metrics at - [number] - --syncing-port Port to serve the network subgraph and - other syncing data for indexer service - at [number] [default: 8002] - --restake-rewards Restake claimed indexer rewards, if set - to 'false' rewards will be returned to - the wallet [boolean] [default: true] - --rebate-claim-threshold Minimum value of rebate for a single - allocation (in GRT) in order for it to - be included in a batch rebate claim - on-chain [string] [default: "1"] - --rebate-claim-batch-threshold Minimum total value of all rebates in an - batch (in GRT) before the batch is - claimed on-chain - [string] [default: "5"] - --rebate-claim-max-batch-size Maximum number of rebates inside a - batch. Upper bound is constrained by - available system memory, and by the - block gas limit [number] [default: 100] - --voucher-redemption-threshold Minimum value of rebate for a single - allocation (in GRT) in order for it to - be included in a batch rebate claim - on-chain [string] [default: "1"] - --voucher-redemption-batch-threshold Minimum total value of all rebates in an - batch (in GRT) before the batch is - claimed on-chain - [string] [default: "5"] - --voucher-redemption-max-batch-size Maximum number of rebates inside a - batch. Upper bound is constrained by - available system memory, and by the - block gas limit [number] [default: 100] - --log-level Log level [string] [default: "debug"] - --allocation-management Indexer agent allocation management - automation mode (auto|manual|oversight) - [string] [default: "auto"] - --auto-allocation-min-batch-size Minimum number of allocation - transactions inside a batch for AUTO - management mode [number] [default: 1] + --ethereum-polling-interval Polling interval for the Ethereum provider + (ms) [number] [default: 4000] + --gas-increase-timeout Time (in seconds) after which transactions + will be resubmitted with a higher gas price + [number] [default: 240] + --gas-increase-factor Factor by which gas prices are increased when + resubmitting transactions + [number] [default: 1.2] + --gas-price-max The maximum gas price (gwei) to use for + transactions + [deprecated] [number] [default: 100] + --base-fee-per-gas-max The maximum base fee per gas (gwei) to use for + transactions, for legacy transactions this + will be treated as the max gas price [number] + --transaction-attempts The maximum number of transaction attempts + (Use 0 for unlimited) [number] [default: 0] + --mnemonic Mnemonic for the operator wallet + [string] [required] + --indexer-address Ethereum address of the indexer + [string] [required] + --payments-destination Address where payments are sent to. If not + provided payments will be restaked. [string] Network Subgraph - --network-subgraph-deployment Network subgraph deployment [string] + --network-subgraph-deployment Network subgraph deployment (for local + hosting) [string] --network-subgraph-endpoint Endpoint to query the network subgraph from [string] --allocate-on-network-subgraph Whether to allocate to the network subgraph [boolean] [default: false] + --epoch-subgraph-deployment Epoch subgraph deployment (for local hosting) + [string] + +TAP Subgraph + --tap-subgraph-deployment TAP subgraph deployment (for local hosting)[string] + --tap-subgraph-endpoint Endpoint to query the tap subgraph from [string] Protocol - --default-allocation-amount Default amount of GRT to allocate to a subgraph - deployment [string] [default: "0.01"] - --register Whether to register the indexer on chain - [boolean] [default: true] - --epoch-subgraph-endpoint Endpoint to query epoch start blocks from + --epoch-subgraph-endpoint Endpoint to query the epoch block + oracle subgraph from [string] [required] + --subgraph-max-block-distance How many blocks subgraphs are allowed + to stay behind chain head + [number] [default: 1000] + --subgraph-freshness-sleep-milliseconds How long to wait before retrying + subgraph query if it is not fresh + [number] [default: 5000] + --default-allocation-amount Default amount of GRT to allocate to + a subgraph deployment + [number] [default: 0.01] + --register Whether to register the indexer on + chain [boolean] [default: true] + --max-provision-initial-size The maximum number of tokens for the + initial Subgraph Service provision + [number] [default: 0] -Postgres - --postgres-host Postgres host [string] [required] - --postgres-port Postgres port [number] [default: 5432] - --postgres-username Postgres username [string] [default: "postgres"] - --postgres-password Postgres password [string] [default: ""] - --postgres-database Postgres database name [string] [required] +Query Fees + --rebate-claim-threshold Minimum value of rebate for a single + allocation (in GRT) in order for it + to be included in a batch rebate + claim on-chain [number] [default: 1] + --rebate-claim-batch-threshold Minimum total value of all rebates + in an batch (in GRT) before the + batch is claimed on-chain + [number] [default: 5] + --rebate-claim-max-batch-size Maximum number of rebates inside a + batch. Upper bound is constrained by + available system memory, and by the + block gas limit + [number] [default: 100] + --voucher-redemption-threshold Minimum value of rebate for a single + allocation (in GRT) in order for it + to be included in a batch rebate + claim on-chain [number] [default: 1] + --voucher-redemption-batch-threshold Minimum total value of all rebates + in an batch (in GRT) before the + batch is claimed on-chain + [number] [default: 5] + --voucher-redemption-max-batch-size Maximum number of rebates inside a + batch. Upper bound is constrained by + available system memory, and by the + block gas limit + [number] [default: 100] + --gateway-endpoint, Gateway endpoint base URL + --collect-receipts-endpoint [string] [required] Disputes --poi-disputable-epochs The number of epochs in the past to look for @@ -152,23 +190,18 @@ Disputes --poi-dispute-monitoring Monitor the network for potential POI disputes [boolean] [default: false] -Query Fees - --vector-node URL of a vector node [string] - --vector-router Public identifier of the vector router[string] - --vector-transfer-definition Address of the Graph transfer definition - contract [string] [default: "auto"] - --vector-event-server External URL of the vector event server of the - agent [string] - --vector-event-server-port Port to serve the vector event server at - [number] [default: 8001] - --collect-receipts-endpoint Client endpoint for collecting receipts - [string] - Options: - --version Show version number [boolean] - --help Show help [boolean] - --offchain-subgraphs Subgraphs to index that are not on chain - (comma-separated) [array] [default: []] + --version Show version number [boolean] + --help Show help [boolean] + --offchain-subgraphs Subgraphs to index that are not on chain + (comma-separated) [array] [default: []] + --horizon-address-book Graph Horizon contracts address book file + path [string] + --subgraph-service-address-book Subgraph Service contracts address book file + path [string] + --tap-address-book TAP contracts address book file path [string] + --chain-finalize-time The time in seconds that the chain finalizes + blocks [number] [default: 3600] ``` ### Indexer CLI diff --git a/docs/action-queue.md b/docs/action-queue.md index e2591e599..b5cf0c5fd 100644 --- a/docs/action-queue.md +++ b/docs/action-queue.md @@ -8,8 +8,8 @@ The action execution worker will only grab items from the action queue to execut ## Allocation management modes: - `auto`: The indexer-agent will act similarly to the legacy paradigm. When it identifies allocation actions it will add them to the queue with ActionStatus = `approved`; the execution worker process will pick up the approved actions within 30 seconds and execute them. -- `manual`: The indexer-agent will not add any items to the action queue in this mode. It will spin up an indexer-management server which can be interacted with manually or integrated with 3rd party tools to add actions to the action queue and execute them. -- `oversight`: The indexer-agent will add run its reconciliation loop to make allocation decisions and when actions are identified it will queue them. These actions will then require approval before they can be executed. +- `manual`: The indexer-agent will not add any items to the action queue in this mode. It will spin up an indexer-management server which can be interacted with manually or integrated with 3rd party tools to add actions to the action queue and execute them. An exception to this is indexing agreements (DIPs), for which actions will be queued and executed even in this mode. +- `oversight`: The indexer-agent will add run its reconciliation loop to make allocation decisions and when actions are identified it will queue them. These actions will then require approval before they can be executed. An exception to this is indexing agreements (DIPs), for which actions will be queued as approved and executed even in this mode. ## Actions CLI The indexer-cli provides an `actions` module for manually working with the action queue. It uses the #Graphql API hosted by the indexer management server to interact with the actions queue. diff --git a/package.json b/package.json index 4db1da91b..3d54f2fad 100644 --- a/package.json +++ b/package.json @@ -23,20 +23,16 @@ "lerna": "6.1.0" }, "resolutions": { - "ethers": "5.7.0", + "ethers": "6.13.7", "sequelize": "6.33.0", - "@ethersproject/bignumber": "5.7.0", - "@ethersproject/providers": "5.7.0", "@urql/core": "3.1.0", "@urql/exchange-execute": "2.1.0", "punycode": "2.3.1", "uri-js": "4.2.2" }, "overrides": { - "ethers": "5.7.0", + "ethers": "6.13.7", "sequelize": "6.33.0", - "@ethersproject/bignumber": "5.7.0", - "@ethersproject/providers": "5.7.0", "@urql/core": "3.1.0", "@urql/exchange-execute": "2.1.0", "graphql": "16.8.0" diff --git a/packages/indexer-agent/jest.config.js b/packages/indexer-agent/jest.config.js index a48b3273c..1530aea77 100644 --- a/packages/indexer-agent/jest.config.js +++ b/packages/indexer-agent/jest.config.js @@ -11,6 +11,7 @@ module.exports = { preset: 'ts-jest', testEnvironment: 'node', testPathIgnorePatterns: ['/node_modules/', '/dist/', '.yalc'], + transformIgnorePatterns: ['!node_modules/'], globals: { __DATABASE__: { host: diff --git a/packages/indexer-agent/package.json b/packages/indexer-agent/package.json index 14635389c..33342a105 100644 --- a/packages/indexer-agent/package.json +++ b/packages/indexer-agent/package.json @@ -29,13 +29,13 @@ "graph-indexer-agent": "bin/graph-indexer-agent" }, "dependencies": { - "@graphprotocol/common-ts": "2.0.11", + "@graphprotocol/common-ts": "3.0.1", "@graphprotocol/indexer-common": "^0.23.8", "@thi.ng/heaps": "^1.3.1", "axios": "0.26.1", "bs58": "5.0.0", "delay": "^5.0.0", - "ethers": "5.7.0", + "ethers": "6.13.7", "evt": "1.9.12", "global": "4.4.0", "graphql": "16.8.0", @@ -80,10 +80,8 @@ "typescript": "5.2.2" }, "resolutions": { - "ethers": "5.7.0", - "sequelize": "6.33.0", - "@ethersproject/bignumber": "5.7.0", - "@ethersproject/providers": "5.7.0" + "ethers": "6.13.7", + "sequelize": "6.33.0" }, "gitHead": "972ab96774007b2aee15b1da169d2ff4be9f9d27" } diff --git a/packages/indexer-agent/src/__tests__/indexer.ts b/packages/indexer-agent/src/__tests__/indexer.ts index 69b3789bf..034f20ebf 100644 --- a/packages/indexer-agent/src/__tests__/indexer.ts +++ b/packages/indexer-agent/src/__tests__/indexer.ts @@ -21,7 +21,6 @@ import { MultiNetworks, loadTestYamlConfig, } from '@graphprotocol/indexer-common' -import { BigNumber } from 'ethers' import { Sequelize } from 'sequelize' const TEST_DISPUTE_1: POIDisputeAttributes = { @@ -69,7 +68,7 @@ const TEST_DISPUTE_2: POIDisputeAttributes = { const POI_DISPUTES_CONVERTERS_FROM_GRAPHQL: Record< keyof POIDisputeAttributes, - (x: never) => string | BigNumber | number | undefined + (x: never) => string | bigint | number | undefined > = { allocationID: x => x, subgraphDeploymentID: x => x, @@ -148,6 +147,7 @@ const setup = async () => { const network = await Network.create( logger, networkSpecification, + models, queryFeeModels, graphNode, metrics, diff --git a/packages/indexer-agent/src/agent.ts b/packages/indexer-agent/src/agent.ts index 82e14c57e..bc034b80f 100644 --- a/packages/indexer-agent/src/agent.ts +++ b/packages/indexer-agent/src/agent.ts @@ -38,6 +38,7 @@ import { DeploymentManagementMode, SubgraphStatus, sequentialTimerMap, + HorizonTransitionValue, } from '@graphprotocol/indexer-common' import PQueue from 'p-queue' @@ -47,7 +48,11 @@ import mapValues from 'lodash.mapvalues' import zip from 'lodash.zip' import { AgentConfigs, NetworkAndOperator } from './types' -type ActionReconciliationContext = [AllocationDecision[], number, number] +type ActionReconciliationContext = [ + AllocationDecision[], + number, + HorizonTransitionValue, +] const deploymentInList = ( list: SubgraphDeploymentID[], @@ -233,6 +238,7 @@ export class Agent { try { await operator.ensureGlobalIndexingRule() await this.ensureAllSubgraphsIndexing(network) + await network.provision() await network.register() } catch (err) { this.logger.critical( @@ -270,27 +276,42 @@ export class Agent { }, ) - const maxAllocationEpochs: Eventual> = - sequentialTimerMap( - { logger, milliseconds: requestIntervalLarge }, - () => - this.multiNetworks.map(({ network }) => { - logger.trace('Fetching max allocation epochs', { - protocolNetwork: network.specification.networkIdentifier, - }) - return network.contracts.staking.maxAllocationEpochs() - }), - { - onError: error => - logger.warn(`Failed to fetch max allocation epochs`, { error }), - }, - ) + const maxAllocationDuration: Eventual< + NetworkMapped + > = sequentialTimerMap( + { logger, milliseconds: requestIntervalLarge }, + () => + this.multiNetworks.map(({ network }) => { + logger.trace('Fetching max allocation duration', { + protocolNetwork: network.specification.networkIdentifier, + }) + return network.networkMonitor.maxAllocationDuration() + }), + { + onError: error => + logger.warn(`Failed to fetch max allocation duration`, { error }), + }, + ) const indexingRules: Eventual> = sequentialTimerMap( { logger, milliseconds: requestIntervalSmall }, async () => { return this.multiNetworks.map(async ({ network, operator }) => { + if (network.specification.indexerOptions.enableDips) { + // There should be a DipsManager in the operator + if (!operator.dipsManager) { + throw new Error('DipsManager is not available') + } + logger.debug('Ensuring indexing rules for DIPs', { + protocolNetwork: network.specification.networkIdentifier, + }) + await operator.dipsManager.ensureAgreementRules() + } else { + logger.debug( + 'DIPs is disabled, skipping indexing rule enforcement', + ) + } logger.trace('Fetching indexing rules', { protocolNetwork: network.specification.networkIdentifier, }) @@ -304,9 +325,9 @@ export class Agent { await network.networkMonitor.subgraphs(subgraphRuleIds) if (subgraphsMatchingRules.length >= 1) { const epochLength = - await network.contracts.epochManager.epochLength() + await network.contracts.EpochManager.epochLength() const blockPeriod = 15 - const bufferPeriod = epochLength.toNumber() * blockPeriod * 100 // 100 epochs + const bufferPeriod = Number(epochLength) * blockPeriod * 100 // 100 epochs rules = convertSubgraphBasedRulesToDeploymentBased( rules, subgraphsMatchingRules, @@ -324,12 +345,21 @@ export class Agent { }, ) - // Skip fetching active deployments if the deployment management mode is manual and POI tracking is disabled + // Skip fetching active deployments if the deployment management mode is manual, DIPs is disabled, and POI tracking is disabled const activeDeployments: Eventual = sequentialTimerMap( { logger, milliseconds: requestIntervalLarge }, async () => { - if (this.deploymentManagement === DeploymentManagementMode.AUTO) { + let dipsEnabled = false + await this.multiNetworks.map(async ({ network }) => { + if (network.specification.indexerOptions.enableDips) { + dipsEnabled = true + } + }) + if ( + this.deploymentManagement === DeploymentManagementMode.AUTO || + dipsEnabled + ) { logger.debug('Fetching active deployments') const assignments = await this.graphNode.subgraphDeploymentsAssignments( @@ -338,7 +368,7 @@ export class Agent { return assignments.map(assignment => assignment.id) } else { logger.info( - "Skipping fetching active deployments fetch since DeploymentManagementMode = 'manual' and POI tracking is disabled", + "Skipping fetching active deployments fetch since DeploymentManagementMode = 'manual' and DIPs is disabled", ) return [] } @@ -351,24 +381,50 @@ export class Agent { }, ) - const networkDeployments: Eventual> = - sequentialTimerMap( - { logger, milliseconds: requestIntervalSmall }, - async () => - await this.multiNetworks.map(({ network }) => { - logger.trace('Fetching network deployments', { - protocolNetwork: network.specification.networkIdentifier, - }) - return network.networkMonitor.subgraphDeployments() - }), - { - onError: error => - logger.warn( - `Failed to obtain network deployments, trying again later`, - { error }, - ), - }, - ) + const networkAndDipsDeployments: Eventual< + NetworkMapped + > = sequentialTimerMap( + { logger, milliseconds: requestIntervalSmall }, + async () => + await this.multiNetworks.map(async ({ network, operator }) => { + logger.trace('Fetching network deployments', { + protocolNetwork: network.specification.networkIdentifier, + }) + const deployments = network.networkMonitor.subgraphDeployments() + if (network.specification.indexerOptions.enableDips) { + if (!operator.dipsManager) { + throw new Error('DipsManager is not available') + } + const resolvedDeployments = await deployments + const dipsDeployments = await Promise.all( + (await operator.dipsManager.getActiveDipsDeployments()).map( + deployment => + network.networkMonitor.subgraphDeployment( + deployment.ipfsHash, + ), + ), + ) + for (const deployment of dipsDeployments) { + if ( + resolvedDeployments.find( + d => d.id.bytes32 === deployment.id.bytes32, + ) == null + ) { + resolvedDeployments.push(deployment) + } + } + return resolvedDeployments + } + return deployments + }), + { + onError: error => + logger.warn( + `Failed to obtain network deployments, trying again later`, + { error }, + ), + }, + ) const eligibleTransferDeployments: Eventual< NetworkMapped @@ -423,13 +479,13 @@ export class Agent { const intermediateNetworkDeploymentAllocationDecisions: Eventual< NetworkMapped > = join({ - networkDeployments, + networkAndDipsDeployments, indexingRules, }).tryMap( - ({ indexingRules, networkDeployments }) => { + ({ indexingRules, networkAndDipsDeployments }) => { return mapValues( - this.multiNetworks.zip(indexingRules, networkDeployments), - ([indexingRules, networkDeployments]: [ + this.multiNetworks.zip(indexingRules, networkAndDipsDeployments), + ([indexingRules, networkAndDipsDeployments]: [ IndexingRuleAttributes[], SubgraphDeployment[], ]) => { @@ -438,7 +494,11 @@ export class Agent { logger.trace('Evaluating which deployments are worth allocating to') return indexingRules.length === 0 ? [] - : evaluateDeployments(logger, networkDeployments, indexingRules) + : evaluateDeployments( + logger, + networkAndDipsDeployments, + indexingRules, + ) }, ) }, @@ -486,7 +546,7 @@ export class Agent { const matchingTransfer = eligibleTransferDeployments.find( deployment => deployment.ipfsHash == decision.deployment.ipfsHash && - deployment.startedTransferToL2At.toNumber() > oneWeekAgo, + Number(deployment.startedTransferToL2At) > oneWeekAgo, ) if (matchingTransfer) { logger.debug('Found a matching subgraph transfer', { @@ -652,7 +712,7 @@ export class Agent { join({ ticker: timer(requestIntervalLarge), currentEpochNumber, - maxAllocationEpochs, + maxAllocationDuration, activeDeployments, targetDeployments, activeAllocations, @@ -662,7 +722,7 @@ export class Agent { }).pipe( async ({ currentEpochNumber, - maxAllocationEpochs, + maxAllocationDuration, activeDeployments, targetDeployments, activeAllocations, @@ -682,7 +742,8 @@ export class Agent { currentEpochNumber: number, ) => currentEpochNumber - - network.specification.indexerOptions.poiDisputableEpochs, + (network.specification.indexerOptions + .poiDisputableEpochs as number), ) // Find disputable allocations @@ -729,9 +790,42 @@ export class Agent { } break case DeploymentManagementMode.MANUAL: - this.logger.debug( - `Skipping subgraph deployment reconciliation since DeploymentManagementMode = 'manual'`, - ) + await this.multiNetworks.map(async ({ network, operator }) => { + if (network.specification.indexerOptions.enableDips) { + // Reconcile DIPs deployments anyways + this.logger.warn( + `Deployment management is manual, but DIPs is enabled. Reconciling DIPs deployments anyways.`, + ) + if (!operator.dipsManager) { + throw new Error('DipsManager is not available') + } + const dipsDeployments = + await operator.dipsManager.getActiveDipsDeployments() + const newTargetDeployments = new Set([ + ...activeDeployments, + ...dipsDeployments, + ]) + try { + await this.reconcileDeployments( + activeDeployments, + Array.from(newTargetDeployments), + eligibleAllocations, + ) + } catch (err) { + logger.warn( + `Exited early while reconciling deployments. Skipped reconciling actions.`, + { + err: indexerError(IndexerErrorCode.IE005, err), + }, + ) + return + } + } else { + this.logger.debug( + `Skipping subgraph deployment reconciliation since DeploymentManagementMode = 'manual'`, + ) + } + }) break default: throw new Error( @@ -744,7 +838,7 @@ export class Agent { await this.reconcileActions( networkDeploymentAllocationDecisions, currentEpochNumber, - maxAllocationEpochs, + maxAllocationDuration, ) } catch (err) { logger.warn(`Exited early while reconciling actions`, { @@ -752,6 +846,23 @@ export class Agent { }) return } + + await this.multiNetworks.mapNetworkMapped( + activeAllocations, + async ({ network, operator }, activeAllocations: Allocation[]) => { + if (network.specification.indexerOptions.enableDips) { + if (!operator.dipsManager) { + throw new Error('DipsManager is not available') + } + this.logger.debug( + `Matching agreement allocations for network ${network.specification.networkIdentifier}`, + ) + await operator.dipsManager.matchAgreementAllocations( + activeAllocations, + ) + } + }, + ) }, ) } @@ -821,22 +932,22 @@ export class Agent { await network.networkProvider.getBlock( pool.previousEpochStartBlockHash!, ) - pool.closedAtEpochStartBlockNumber = closedAtEpochStartBlock.number + pool.closedAtEpochStartBlockNumber = closedAtEpochStartBlock!.number pool.referencePOI = await this.graphNode.proofOfIndexing( pool.subgraphDeployment, { - number: closedAtEpochStartBlock.number, - hash: closedAtEpochStartBlock.hash, + number: closedAtEpochStartBlock!.number, + hash: closedAtEpochStartBlock!.hash!, }, pool.allocationIndexer, ) - pool.previousEpochStartBlockHash = previousEpochStartBlock.hash - pool.previousEpochStartBlockNumber = previousEpochStartBlock.number + pool.previousEpochStartBlockHash = previousEpochStartBlock!.hash! + pool.previousEpochStartBlockNumber = previousEpochStartBlock!.number pool.referencePreviousPOI = await this.graphNode.proofOfIndexing( pool.subgraphDeployment, { - number: previousEpochStartBlock.number, - hash: previousEpochStartBlock.hash, + number: previousEpochStartBlock!.number, + hash: previousEpochStartBlock!.hash!, }, pool.allocationIndexer, ) @@ -1006,18 +1117,25 @@ export class Agent { activeAllocations: Allocation[], deploymentAllocationDecision: AllocationDecision, epoch: number, - maxAllocationEpochs: number, + maxAllocationDuration: HorizonTransitionValue, network: Network, ): Promise { - const desiredAllocationLifetime = deploymentAllocationDecision.ruleMatch - .rule?.allocationLifetime - ? deploymentAllocationDecision.ruleMatch.rule.allocationLifetime - : Math.max(1, maxAllocationEpochs - 1) - - // Identify expiring allocations let expiredAllocations = activeAllocations.filter( - allocation => - epoch >= allocation.createdAtEpoch + desiredAllocationLifetime, + async (allocation: Allocation) => { + let desiredAllocationLifetime: number = 0 + if (allocation.isLegacy) { + desiredAllocationLifetime = deploymentAllocationDecision.ruleMatch + .rule?.allocationLifetime + ? deploymentAllocationDecision.ruleMatch.rule.allocationLifetime + : Math.max(1, maxAllocationDuration.legacy - 1) + } else { + desiredAllocationLifetime = deploymentAllocationDecision.ruleMatch + .rule?.allocationLifetime + ? deploymentAllocationDecision.ruleMatch.rule.allocationLifetime + : maxAllocationDuration.horizon + } + return epoch >= allocation.createdAtEpoch + desiredAllocationLifetime + }, ) // The allocations come from the network subgraph; due to short indexing // latencies, this data may be slightly outdated. Cross-check with the @@ -1027,9 +1145,17 @@ export class Agent { expiredAllocations, async (allocation: Allocation) => { try { - const onChainAllocation = - await network.contracts.staking.getAllocation(allocation.id) - return onChainAllocation.closedAtEpoch.eq('0') + if (allocation.isLegacy) { + const onChainAllocation = + await network.contracts.LegacyStaking.getAllocation(allocation.id) + return onChainAllocation.closedAtEpoch == 0n + } else { + const onChainAllocation = + await network.contracts.SubgraphService.getAllocation( + allocation.id, + ) + return onChainAllocation.closedAt == 0n + } } catch (err) { this.logger.warn( `Failed to cross-check allocation state with contracts; assuming it needs to be closed`, @@ -1050,9 +1176,10 @@ export class Agent { deploymentAllocationDecision: AllocationDecision, activeAllocations: Allocation[], epoch: number, - maxAllocationEpochs: number, + maxAllocationDuration: HorizonTransitionValue, network: Network, operator: Operator, + forceAction: boolean = false, ): Promise { const logger = this.logger.child({ deployment: deploymentAllocationDecision.deployment.ipfsHash, @@ -1060,6 +1187,8 @@ export class Agent { epoch, }) + const isHorizon = await network.isHorizon.value() + // TODO: Can we replace `filter` for `find` here? Is there such a case when we // would have multiple allocations for the same subgraph? const activeDeploymentAllocations = activeAllocations.filter( @@ -1074,6 +1203,7 @@ export class Agent { logger, deploymentAllocationDecision, activeDeploymentAllocations, + forceAction, ) case true: { // If no active allocations and subgraph health passes safety check, create one @@ -1110,6 +1240,8 @@ export class Agent { logger, deploymentAllocationDecision, mostRecentlyClosedAllocation, + isHorizon, + forceAction, ) } } else if (activeDeploymentAllocations.length > 0) { @@ -1118,6 +1250,7 @@ export class Agent { logger, deploymentAllocationDecision, activeDeploymentAllocations, + forceAction, ) } else { // Refresh any expiring allocations @@ -1126,7 +1259,7 @@ export class Agent { activeDeploymentAllocations, deploymentAllocationDecision, epoch, - maxAllocationEpochs, + maxAllocationDuration, network, ) if (expiringAllocations.length > 0) { @@ -1134,6 +1267,7 @@ export class Agent { logger, deploymentAllocationDecision, expiringAllocations, + forceAction, ) } } @@ -1145,7 +1279,7 @@ export class Agent { async reconcileActions( networkDeploymentAllocationDecisions: NetworkMapped, epoch: NetworkMapped, - maxAllocationEpochs: NetworkMapped, + maxAllocationDuration: NetworkMapped, ): Promise { // -------------------------------------------------------------------------------- // Filter out networks set to `manual` allocation management mode, and ensure the @@ -1198,14 +1332,14 @@ export class Agent { this.multiNetworks.zip3( validatedAllocationDecisions, epoch, - maxAllocationEpochs, + maxAllocationDuration, ), async ( { network, operator }: NetworkAndOperator, [ allocationDecisions, epoch, - maxAllocationEpochs, + maxAllocationDuration, ]: ActionReconciliationContext, ) => { // Do nothing if there are already approved actions in the queue awaiting execution @@ -1230,7 +1364,7 @@ export class Agent { this.logger.trace(`Reconcile allocation actions`, { protocolNetwork: network.specification.networkIdentifier, epoch, - maxAllocationEpochs, + maxAllocationDuration, targetDeployments: allocationDecisions .filter(decision => decision.toAllocate) .map(decision => decision.deployment.ipfsHash), @@ -1246,7 +1380,7 @@ export class Agent { decision, activeAllocations, epoch, - maxAllocationEpochs, + maxAllocationDuration, network, operator, ), diff --git a/packages/indexer-agent/src/commands/start.ts b/packages/indexer-agent/src/commands/start.ts index bf688485f..1ece72417 100644 --- a/packages/indexer-agent/src/commands/start.ts +++ b/packages/indexer-agent/src/commands/start.ts @@ -31,7 +31,6 @@ import { createSyncingServer } from '../syncing-server' import { injectCommonStartupOptions } from './common-options' import pMap from 'p-map' import { NetworkSpecification } from '@graphprotocol/indexer-common/dist/network-specification' -import { BigNumber } from 'ethers' import { displayZodParsingError } from '@graphprotocol/indexer-common' import { readFileSync } from 'fs' import { AgentConfigs } from '../types' @@ -100,6 +99,13 @@ export const start = { default: 0, group: 'Ethereum', }) + .option('confirmation-blocks', { + description: + 'The number of blocks to wait for a transaction to be confirmed', + type: 'number', + default: 3, + group: 'Ethereum', + }) .option('mnemonic', { description: 'Mnemonic for the operator wallet', type: 'string', @@ -112,6 +118,12 @@ export const start = { required: true, group: 'Ethereum', }) + .option('payments-destination', { + description: + 'Address where payments are sent to. If not provided payments will be restaked.', + type: 'string', + group: 'Ethereum', + }) .option('public-indexer-url', { description: 'Indexer endpoint for receiving requests from the network', type: 'string', @@ -247,8 +259,13 @@ export const start = { default: 100, group: 'Query Fees', }) - .option('address-book', { - description: 'Graph contracts address book file path', + .option('horizon-address-book', { + description: 'Graph Horizon contracts address book file path', + type: 'string', + required: false, + }) + .option('subgraph-service-address-book', { + description: 'Subgraph Service contracts address book file path', type: 'string', required: false, }) @@ -268,6 +285,13 @@ export const start = { default: true, group: 'Protocol', }) + .option('max-provision-initial-size', { + description: + 'The maximum number of tokens for the initial Subgraph Service provision', + type: 'number', + default: 0, + group: 'Protocol', + }) .option('poi-disputable-epochs', { description: 'The number of epochs in the past to look for potential POI disputes', @@ -303,6 +327,26 @@ export const start = { default: 1, group: 'Indexer Infrastructure', }) + .option('enable-dips', { + description: 'Whether to enable Indexing Fees (DIPs)', + type: 'boolean', + default: false, + group: 'Indexing Fees ("DIPs")', + }) + .option('dipper-endpoint', { + description: 'Gateway endpoint for DIPs receipts', + type: 'string', + array: false, + required: false, + group: 'Indexing Fees ("DIPs")', + }) + .option('dips-allocation-amount', { + description: 'Amount of GRT to allocate for DIPs', + type: 'number', + default: 1, + required: false, + group: 'Indexing Fees ("DIPs")', + }) .check(argv => { if ( !argv['network-subgraph-endpoint'] && @@ -330,6 +374,9 @@ export const start = { ) { return 'Invalid --rebate-claim-max-batch-size provided. Must be > 0 and an integer.' } + if (argv['enable-dips'] && !argv['dipper-endpoint']) { + return 'Invalid --dipper-endpoint provided. Must be provided when --enable-dips is true.' + } return true }) }, @@ -347,6 +394,7 @@ export async function createNetworkSpecification( const indexerOptions = { address: argv.indexerAddress, + paymentsDestination: argv.paymentsDestination, mnemonic: argv.mnemonic, url: argv.publicIndexerUrl, geoCoordinates: argv.indexerGeoCoordinates, @@ -364,7 +412,12 @@ export async function createNetworkSpecification( autoAllocationMinBatchSize: argv.autoAllocationMinBatchSize, allocateOnNetworkSubgraph: argv.allocateOnNetworkSubgraph, register: argv.register, + maxProvisionInitialSize: argv.maxProvisionInitialSize, finalityTime: argv.chainFinalizeTime, + enableDips: argv.enableDips, + dipperEndpoint: argv.dipperEndpoint, + dipsAllocationAmount: argv.dipsAllocationAmount, + dipsEpochsMargin: argv.dipsEpochsMargin, } const transactionMonitoring = { @@ -373,6 +426,7 @@ export async function createNetworkSpecification( gasPriceMax: argv.gasPriceMax, baseFeePerGasMax: argv.baseFeeGasMax, maxTransactionAttempts: argv.maxTransactionAttempts, + confirmationBlocks: argv.confirmationBlocks, } const subgraphs = { @@ -444,8 +498,9 @@ export async function createNetworkSpecification( transactionMonitoring, subgraphs, networkProvider, - addressBook: argv.addressBook, - tapAddressBook, + horizonAddressBook: argv.horizonAddressBook, + subgraphServiceAddressBook: argv.subgraphServiceAddressBook, + tapAddressBook: tapAddressBook, }) } catch (parsingError) { displayZodParsingError(parsingError) @@ -583,7 +638,14 @@ export async function run( const networks: Network[] = await pMap( networkSpecifications, async (spec: NetworkSpecification) => - Network.create(logger, spec, queryFeeModels, graphNode, metrics), + Network.create( + logger, + spec, + managementModels, + queryFeeModels, + graphNode, + metrics, + ), ) // -------------------------------------------------------------------------------- @@ -601,7 +663,7 @@ export async function run( defaults: { globalIndexingRule: { // TODO: Update this, there will be defaults per network - allocationAmount: BigNumber.from(100), + allocationAmount: BigInt(100), parallelAllocations: 1, }, }, diff --git a/packages/indexer-agent/src/db/migrations/14-cost-models-history.ts b/packages/indexer-agent/src/db/migrations/14-cost-models-history.ts index dab5cc23f..90bb5e7a0 100644 --- a/packages/indexer-agent/src/db/migrations/14-cost-models-history.ts +++ b/packages/indexer-agent/src/db/migrations/14-cost-models-history.ts @@ -1,5 +1,5 @@ import { Logger } from '@graphprotocol/common-ts' -import { utils } from 'ethers' +import { isHexString } from 'ethers' import { QueryInterface, DataTypes } from 'sequelize' interface MigrationContext { @@ -45,7 +45,7 @@ export async function up({ context }: Context): Promise { throw new Error('Deployment ID must be a string') } // "0x..." and "global" is ok - if (utils.isHexString(value, 32) || value === COST_MODEL_GLOBAL) { + if (isHexString(value, 32) || value === COST_MODEL_GLOBAL) { return } diff --git a/packages/indexer-agent/src/db/migrations/19-actions-add-islegacy.ts b/packages/indexer-agent/src/db/migrations/19-actions-add-islegacy.ts new file mode 100644 index 000000000..1bf84cbbe --- /dev/null +++ b/packages/indexer-agent/src/db/migrations/19-actions-add-islegacy.ts @@ -0,0 +1,52 @@ +import { Logger } from '@graphprotocol/common-ts' +import { DataTypes, QueryInterface } from 'sequelize' + +interface MigrationContext { + queryInterface: QueryInterface + logger: Logger +} + +interface Context { + context: MigrationContext +} + +export async function up({ context }: Context): Promise { + const { queryInterface, logger } = context + + logger.debug(`Checking if 'Actions' table exists`) + const tables = await queryInterface.showAllTables() + if (!tables.includes('Actions')) { + logger.info(`Actions table does not exist, migration not necessary`) + return + } + + logger.debug(`Checking if 'Actions' table needs to be migrated`) + const table = await queryInterface.describeTable('Actions') + const isLegacy = table.isLegacy + if (isLegacy) { + logger.info(`'isLegacy' column already exists, migration not necessary`) + return + } + + logger.info(`Add 'isLegacy' column to 'Actions' table`) + await queryInterface.addColumn('Actions', 'isLegacy', { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: true, + }) +} + +export async function down({ context }: Context): Promise { + const { queryInterface, logger } = context + + return await queryInterface.sequelize.transaction({}, async transaction => { + const tables = await queryInterface.showAllTables() + + if (tables.includes('Actions')) { + logger.info(`Remove 'isLegacy' column`) + await context.queryInterface.removeColumn('Actions', 'isLegacy', { + transaction, + }) + } + }) +} diff --git a/packages/indexer-agent/src/db/migrations/19-add-dips-to-decision-basis.ts b/packages/indexer-agent/src/db/migrations/19-add-dips-to-decision-basis.ts new file mode 100644 index 000000000..793ef3ab3 --- /dev/null +++ b/packages/indexer-agent/src/db/migrations/19-add-dips-to-decision-basis.ts @@ -0,0 +1,38 @@ +import type { Logger } from '@graphprotocol/common-ts' +import type { QueryInterface } from 'sequelize' + +interface MigrationContext { + queryInterface: QueryInterface + logger: Logger +} + +interface Context { + context: MigrationContext +} + +export async function up({ context }: Context): Promise { + const { queryInterface, logger } = context + + if (await queryInterface.tableExists('IndexingRules')) { + logger.debug('Adding dips to decision basis') + + await queryInterface.sequelize.query( + `ALTER TYPE "enum_IndexingRules_decisionBasis" ADD VALUE 'dips'`, + ) + } else { + logger.debug('IndexingRules table does not exist, skipping migration') + } + + logger.info('Migration completed') +} + +export async function down({ context }: Context): Promise { + const { queryInterface, logger } = context + + logger.info('Removing dips from decision basis') + await queryInterface.sequelize.query( + `ALTER TYPE "enum_IndexingRules_decisionBasis" DROP VALUE 'dips'`, + ) + + logger.info('Migration completed') +} diff --git a/packages/indexer-agent/src/db/migrations/20-actions-add-poi-metadata.ts b/packages/indexer-agent/src/db/migrations/20-actions-add-poi-metadata.ts new file mode 100644 index 000000000..ba1b86abd --- /dev/null +++ b/packages/indexer-agent/src/db/migrations/20-actions-add-poi-metadata.ts @@ -0,0 +1,61 @@ +import { Logger } from '@graphprotocol/common-ts' +import { DataTypes, QueryInterface } from 'sequelize' + +interface MigrationContext { + queryInterface: QueryInterface + logger: Logger +} + +interface Context { + context: MigrationContext +} + +export async function up({ context }: Context): Promise { + const { queryInterface, logger } = context + + logger.debug(`Checking if 'Actions' table exists`) + const tables = await queryInterface.showAllTables() + if (!tables.includes('Actions')) { + logger.info(`Actions table does not exist, migration not necessary`) + return + } + + logger.debug(`Checking if 'Actions' table needs to be migrated`) + const table = await queryInterface.describeTable('Actions') + const publicPOI = table.publicPOI + const poiBlockNumber = table.poiBlockNumber + if (publicPOI && poiBlockNumber) { + logger.info( + `'publicPOI' and 'poiBlockNumber' columns already exist, migration not necessary`, + ) + return + } + + logger.info(`Add 'publicPOI' and 'poiBlockNumber' columns to 'Actions' table`) + await queryInterface.addColumn('Actions', 'publicPOI', { + type: DataTypes.STRING, + allowNull: true, + }) + await queryInterface.addColumn('Actions', 'poiBlockNumber', { + type: DataTypes.INTEGER, + allowNull: true, + }) +} + +export async function down({ context }: Context): Promise { + const { queryInterface, logger } = context + + return await queryInterface.sequelize.transaction({}, async transaction => { + const tables = await queryInterface.showAllTables() + + if (tables.includes('Actions')) { + logger.info(`Remove 'publicPOI' and 'poiBlockNumber' columns`) + await context.queryInterface.removeColumn('Actions', 'publicPOI', { + transaction, + }) + await context.queryInterface.removeColumn('Actions', 'poiBlockNumber', { + transaction, + }) + } + }) +} diff --git a/packages/indexer-agent/src/db/migrations/21-add-tap-horizon-table.ts b/packages/indexer-agent/src/db/migrations/21-add-tap-horizon-table.ts new file mode 100644 index 000000000..85ca3e1da --- /dev/null +++ b/packages/indexer-agent/src/db/migrations/21-add-tap-horizon-table.ts @@ -0,0 +1,284 @@ +import { Logger } from '@graphprotocol/common-ts' +import { QueryInterface, DataTypes } from 'sequelize' + +interface MigrationContext { + queryInterface: QueryInterface + logger: Logger +} + +interface Context { + context: MigrationContext +} + +export async function up({ context }: Context): Promise { + const { queryInterface, logger } = context + + const tables = await queryInterface.showAllTables() + logger.debug(`Checking if tap_horizon_receipts table exists`, { tables }) + + if (tables.includes('tap_horizon_receipts')) { + logger.debug(`tap_horizon_receipts already exist, migration not necessary`) + } else { + logger.info(`Create tap_horizon_receipts`) + await queryInterface.createTable('tap_horizon_receipts', { + id: { + type: DataTypes.BIGINT, + primaryKey: true, + autoIncrement: true, + }, + signer_address: { + type: DataTypes.CHAR(40), + allowNull: false, + }, + + // Values below are the individual fields of the EIP-712 receipt + signature: { + type: DataTypes.BLOB, + allowNull: false, + }, + collection_id: { + type: DataTypes.CHAR(64), + allowNull: false, + }, + payer: { + type: DataTypes.CHAR(40), + allowNull: false, + }, + data_service: { + type: DataTypes.CHAR(40), + allowNull: false, + }, + service_provider: { + type: DataTypes.CHAR(40), + allowNull: false, + }, + timestamp_ns: { + type: DataTypes.DECIMAL(20), + allowNull: false, + }, + nonce: { + type: DataTypes.DECIMAL, + allowNull: false, + }, + value: { + type: DataTypes.DECIMAL(39), + allowNull: false, + }, + }) + } + + logger.debug('Create function and trigger using raw SQL') + const functionSQL = ` + CREATE FUNCTION tap_horizon_receipt_notify() + RETURNS trigger AS + $$ + BEGIN + PERFORM pg_notify('tap_horizon_receipt_notification', format('{"id": %s, "collection_id": "%s", "signer_address": "%s", "timestamp_ns": %s, "value": %s}', NEW.id, NEW.collection_id, NEW.signer_address, NEW.timestamp_ns, NEW.value)); + RETURN NEW; + END; + $$ LANGUAGE 'plpgsql'; + ` + const triggerSQL = ` + CREATE TRIGGER receipt_update AFTER INSERT OR UPDATE + ON tap_horizon_receipts + FOR EACH ROW EXECUTE PROCEDURE tap_horizon_receipt_notify(); + ` + await queryInterface.sequelize.query(functionSQL) + await queryInterface.sequelize.query(triggerSQL) + + queryInterface.addIndex('tap_horizon_receipts', ['collection_id'], { + name: 'tap_horizon_receipts_collection_id_idx', + }) + queryInterface.addIndex('tap_horizon_receipts', ['timestamp_ns'], { + name: 'tap_horizon_receipts_timestamp_ns_idx', + }) + + if (tables.includes('tap_horizon_receipts_invalid')) { + logger.info( + `tap_horizon_receipts_invalid already exist, migration not necessary`, + ) + } else { + // Create the tap_horizon_ravs table if it doesn't exist + await queryInterface.createTable('tap_horizon_receipts_invalid', { + id: { + type: DataTypes.BIGINT, + primaryKey: true, + autoIncrement: true, + }, + signer_address: { + type: DataTypes.CHAR(40), + allowNull: false, + }, + + // Values below are the individual fields of the EIP-712 receipt + signature: { + type: DataTypes.BLOB, + allowNull: false, + }, + collection_id: { + type: DataTypes.CHAR(64), + allowNull: false, + }, + payer: { + type: DataTypes.CHAR(40), + allowNull: false, + }, + data_service: { + type: DataTypes.CHAR(40), + allowNull: false, + }, + service_provider: { + type: DataTypes.CHAR(40), + allowNull: false, + }, + timestamp_ns: { + type: DataTypes.DECIMAL(20), + allowNull: false, + }, + nonce: { + type: DataTypes.DECIMAL, + allowNull: false, + }, + value: { + type: DataTypes.DECIMAL(20), + allowNull: false, + }, + error_log: { + type: DataTypes.TEXT, + allowNull: true, + }, + }) + } + + if (tables.includes('tap_horizon_ravs')) { + logger.info(`tap_horizon_ravs already exist, migration not necessary`) + } else { + // Create the tap_horizon_ravs table if it doesn't exist + await queryInterface.createTable('tap_horizon_ravs', { + // Values below are the individual fields of the EIP-712 receipt + signature: { + type: DataTypes.BLOB, + allowNull: false, + }, + collection_id: { + type: DataTypes.CHAR(64), + allowNull: false, + }, + payer: { + type: DataTypes.CHAR(40), + allowNull: false, + }, + data_service: { + type: DataTypes.CHAR(40), + allowNull: false, + }, + service_provider: { + type: DataTypes.CHAR(40), + allowNull: false, + }, + timestamp_ns: { + type: DataTypes.DECIMAL(20), + allowNull: false, + }, + value_aggregate: { + type: DataTypes.DECIMAL(39), + allowNull: false, + }, + metadata: { + type: DataTypes.BLOB, + allowNull: false, + }, + + last: { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: false, + }, + final: { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: false, + }, + + redeemed_at: { + type: DataTypes.DATE, + allowNull: true, + }, + created_at: { + type: DataTypes.DATE, + allowNull: false, + }, + updated_at: { + type: DataTypes.DATE, + allowNull: false, + }, + }) + } + + logger.info(`Add primary key`) + await queryInterface.addConstraint('tap_horizon_ravs', { + fields: ['payer', 'data_service', 'service_provider', 'collection_id'], + type: 'primary key', + name: 'pk_tap_horizon_ravs', + }) + + await queryInterface.createTable('tap_horizon_rav_requests_failed', { + id: { + type: DataTypes.BIGINT, + primaryKey: true, + autoIncrement: true, + }, + collection_id: { + type: DataTypes.CHAR(64), + allowNull: false, + }, + payer: { + type: DataTypes.CHAR(40), + allowNull: false, + }, + data_service: { + type: DataTypes.CHAR(40), + allowNull: false, + }, + service_provider: { + type: DataTypes.CHAR(40), + allowNull: false, + }, + expected_rav: { + type: DataTypes.JSON, + allowNull: false, + }, + rav_response: { + type: DataTypes.JSON, + allowNull: false, + }, + reason: { + allowNull: false, + type: DataTypes.TEXT, + }, + }) +} + +export async function down({ context }: Context): Promise { + const { queryInterface, logger } = context + // Drop the tap_horizon_ravs table + logger.info(`Drop table`) + await queryInterface.dropTable('tap_horizon_ravs') + + logger.info(`Drop function, trigger, indices, and table`) + await queryInterface.sequelize.query( + 'DROP TRIGGER IF EXISTS receipt_update ON tap_horizon_receipts', + ) + await queryInterface.sequelize.query( + 'DROP FUNCTION IF EXISTS tap_horizon_receipt_notify', + ) + await queryInterface.removeIndex( + 'tap_horizon_receipts', + 'tap_horizon_receipts_collection_id_idx', + ) + await queryInterface.removeIndex( + 'tap_horizon_receipts', + 'tap_horizon_receipts_timestamp_ns_idx', + ) + await queryInterface.dropTable('tap_horizon_receipts') +} diff --git a/packages/indexer-agent/src/db/migrations/22-add-tap-horizon-deny-list.ts b/packages/indexer-agent/src/db/migrations/22-add-tap-horizon-deny-list.ts new file mode 100644 index 000000000..413e3b457 --- /dev/null +++ b/packages/indexer-agent/src/db/migrations/22-add-tap-horizon-deny-list.ts @@ -0,0 +1,77 @@ +import { Logger } from '@graphprotocol/common-ts' + +import { QueryInterface, DataTypes } from 'sequelize' + +interface MigrationContext { + queryInterface: QueryInterface + logger: Logger +} + +interface Context { + context: MigrationContext +} + +export async function up({ context }: Context): Promise { + const { queryInterface, logger } = context + + const tables = await queryInterface.showAllTables() + logger.debug(`Checking if tap_horizon_denylist table exists`, { tables }) + + if (tables.includes('tap_horizon_denylist')) { + logger.debug(`tap_horizon_denylist already exist, migration not necessary`) + } else { + logger.info(`Create tap_horizon_denylist`) + await queryInterface.createTable('tap_horizon_denylist', { + id: { + type: DataTypes.BIGINT, + primaryKey: true, + autoIncrement: true, + }, + sender_address: { + type: DataTypes.CHAR(40), + allowNull: false, + }, + }) + } + const functionSQL = ` + CREATE FUNCTION tap_horizon_deny_notify() + RETURNS trigger AS + $$ + BEGIN + IF TG_OP = 'DELETE' THEN + PERFORM pg_notify('tap_horizon_deny_notification', format('{"tg_op": "DELETE", "sender_address": "%s"}', OLD.sender_address)); + RETURN OLD; + ELSIF TG_OP = 'INSERT' THEN + PERFORM pg_notify('tap_horizon_deny_notification', format('{"tg_op": "INSERT", "sender_address": "%s"}', NEW.sender_address)); + RETURN NEW; + ELSE -- UPDATE OR TRUNCATE, should never happen + PERFORM pg_notify('tap_horizon_deny_notification', format('{"tg_op": "%s", "sender_address": null}', TG_OP, NEW.sender_address)); + RETURN NEW; + END IF; + END; + $$ LANGUAGE 'plpgsql'; + ` + const triggerSQL = ` + CREATE TRIGGER deny_update AFTER INSERT OR UPDATE OR DELETE + ON tap_horizon_denylist + FOR EACH ROW EXECUTE PROCEDURE tap_horizon_deny_notify(); + ` + + await queryInterface.sequelize.query(functionSQL) + await queryInterface.sequelize.query(triggerSQL) +} + +export async function down({ context }: Context): Promise { + const { queryInterface, logger } = context + + logger.info(`Drop tap_horizon_denylist`) + await queryInterface.sequelize.query( + 'DROP TRIGGER IF EXISTS deny_update ON tap_horizon_denylist', + ) + logger.info(`Drop function tap_horizon_deny_notify`) + await queryInterface.sequelize.query( + 'DROP FUNCTION IF EXISTS tap_horizon_deny_notify', + ) + logger.info(`Drop table tap_horizon_denylist`) + await queryInterface.dropTable('tap_horizon_denylist') +} diff --git a/packages/indexer-cli/package.json b/packages/indexer-cli/package.json index 4da11add7..ea23edc96 100644 --- a/packages/indexer-cli/package.json +++ b/packages/indexer-cli/package.json @@ -26,19 +26,20 @@ "test:watch": "jest --watch --detectOpenHandles --verbose" }, "dependencies": { - "@graphprotocol/common-ts": "2.0.11", + "@graphprotocol/common-ts": "3.0.1", "@graphprotocol/indexer-common": "^0.23.8", "@iarna/toml": "2.2.5", "@thi.ng/iterators": "5.1.74", "@urql/core": "3.1.0", "chalk": "4.1.2", "env-paths": "2.2.1", - "ethers": "5.7.0", + "ethers": "6.13.7", "gluegun": "4.7.0", "graphql-tag": "2.12.6", "isomorphic-fetch": "3.0.0", "table": "6.7.5", - "yaml": "1.10.2" + "yaml": "1.10.2", + "wrap-ansi": "9.0.0" }, "devDependencies": { "@types/isomorphic-fetch": "0.0.36", @@ -53,7 +54,7 @@ "typescript": "5.2.2" }, "resolutions": { - "ethers": "5.7.0", + "ethers": "6.13.7", "sequelize": "6.33.0" }, "gitHead": "972ab96774007b2aee15b1da169d2ff4be9f9d27" diff --git a/packages/indexer-cli/src/__tests__/references/indexer-actions-get-first.stdout b/packages/indexer-cli/src/__tests__/references/indexer-actions-get-first.stdout index 8a9613df1..dd32934db 100644 --- a/packages/indexer-cli/src/__tests__/references/indexer-actions-get-first.stdout +++ b/packages/indexer-cli/src/__tests__/references/indexer-actions-get-first.stdout @@ -1,5 +1,5 @@ -┌────┬──────────────────┬────────────┬────────────────────────────────────────────────┬──────────────┬────────┬──────┬───────┬──────────┬────────┬────────┬───────────────┬─────────────┬────────┐ -│ id │ protocolNetwork │ type │ deploymentID │ allocationID │ amount │ poi │ force │ priority │ status │ source │ failureReason │ transaction │ reason │ -├────┼──────────────────┼────────────┼────────────────────────────────────────────────┼──────────────┼────────┼──────┼───────┼──────────┼────────┼────────┼───────────────┼─────────────┼────────┤ -│ 2 │ arbitrum-sepolia │ unallocate │ QmSrf6VVPyg9NGdS1xhLmoosk3qZQaWhfoSTHE2H7sht6Q │ null │ null │ null │ null │ 0 │ failed │ test │ null │ null │ test │ -└────┴──────────────────┴────────────┴────────────────────────────────────────────────┴──────────────┴────────┴──────┴───────┴──────────┴────────┴────────┴───────────────┴─────────────┴────────┘ +┌────┬──────────────────┬────────────┬────────────────────────────────────────────────┬──────────────┬────────┬──────┬───────────┬────────────────┬───────┬──────────┬────────┬────────┬───────────────┬─────────────┬────────┬──────────┐ +│ id │ protocolNetwork │ type │ deploymentID │ allocationID │ amount │ poi │ publicPOI │ poiBlockNumber │ force │ priority │ status │ source │ failureReason │ transaction │ reason │ isLegacy │ +├────┼──────────────────┼────────────┼────────────────────────────────────────────────┼──────────────┼────────┼──────┼───────────┼────────────────┼───────┼──────────┼────────┼────────┼───────────────┼─────────────┼────────┼──────────┤ +│ 2 │ arbitrum-sepolia │ unallocate │ QmSrf6VVPyg9NGdS1xhLmoosk3qZQaWhfoSTHE2H7sht6Q │ null │ null │ null │ null │ null │ null │ 0 │ failed │ test │ null │ null │ test │ false │ +└────┴──────────────────┴────────────┴────────────────────────────────────────────────┴──────────────┴────────┴──────┴───────────┴────────────────┴───────┴──────────┴────────┴────────┴───────────────┴─────────────┴────────┴──────────┘ diff --git a/packages/indexer-cli/src/__tests__/references/indexer-actions-get.stdout b/packages/indexer-cli/src/__tests__/references/indexer-actions-get.stdout index 1d0ac63da..1055b1e43 100644 --- a/packages/indexer-cli/src/__tests__/references/indexer-actions-get.stdout +++ b/packages/indexer-cli/src/__tests__/references/indexer-actions-get.stdout @@ -1,7 +1,7 @@ -┌────┬──────────────────┬────────────┬────────────────────────────────────────────────┬──────────────┬────────┬──────┬───────┬──────────┬─────────┬────────┬───────────────┬─────────────┬────────┐ -│ id │ protocolNetwork │ type │ deploymentID │ allocationID │ amount │ poi │ force │ priority │ status │ source │ failureReason │ transaction │ reason │ -├────┼──────────────────┼────────────┼────────────────────────────────────────────────┼──────────────┼────────┼──────┼───────┼──────────┼─────────┼────────┼───────────────┼─────────────┼────────┤ -│ 2 │ arbitrum-sepolia │ unallocate │ QmSrf6VVPyg9NGdS1xhLmoosk3qZQaWhfoSTHE2H7sht6Q │ null │ null │ null │ null │ 0 │ failed │ test │ null │ null │ test │ -├────┼──────────────────┼────────────┼────────────────────────────────────────────────┼──────────────┼────────┼──────┼───────┼──────────┼─────────┼────────┼───────────────┼─────────────┼────────┤ -│ 1 │ arbitrum-sepolia │ allocate │ QmSrf6VVPyg9NGdS1xhLmoosk3qZQaWhfoSTHE2H7sht6Q │ null │ null │ null │ null │ 0 │ success │ test │ null │ null │ test │ -└────┴──────────────────┴────────────┴────────────────────────────────────────────────┴──────────────┴────────┴──────┴───────┴──────────┴─────────┴────────┴───────────────┴─────────────┴────────┘ +┌────┬──────────────────┬────────────┬────────────────────────────────────────────────┬──────────────┬────────┬──────┬───────────┬────────────────┬───────┬──────────┬─────────┬────────┬───────────────┬─────────────┬────────┬──────────┐ +│ id │ protocolNetwork │ type │ deploymentID │ allocationID │ amount │ poi │ publicPOI │ poiBlockNumber │ force │ priority │ status │ source │ failureReason │ transaction │ reason │ isLegacy │ +├────┼──────────────────┼────────────┼────────────────────────────────────────────────┼──────────────┼────────┼──────┼───────────┼────────────────┼───────┼──────────┼─────────┼────────┼───────────────┼─────────────┼────────┼──────────┤ +│ 2 │ arbitrum-sepolia │ unallocate │ QmSrf6VVPyg9NGdS1xhLmoosk3qZQaWhfoSTHE2H7sht6Q │ null │ null │ null │ null │ null │ null │ 0 │ failed │ test │ null │ null │ test │ false │ +├────┼──────────────────┼────────────┼────────────────────────────────────────────────┼──────────────┼────────┼──────┼───────────┼────────────────┼───────┼──────────┼─────────┼────────┼───────────────┼─────────────┼────────┼──────────┤ +│ 1 │ arbitrum-sepolia │ allocate │ QmSrf6VVPyg9NGdS1xhLmoosk3qZQaWhfoSTHE2H7sht6Q │ null │ null │ null │ null │ null │ null │ 0 │ success │ test │ null │ null │ test │ false │ +└────┴──────────────────┴────────────┴────────────────────────────────────────────────┴──────────────┴────────┴──────┴───────────┴────────────────┴───────┴──────────┴─────────┴────────┴───────────────┴─────────────┴────────┴──────────┘ diff --git a/packages/indexer-cli/src/__tests__/references/indexer-help.stdout b/packages/indexer-cli/src/__tests__/references/indexer-help.stdout index 86d97c23f..8b6f5671d 100644 --- a/packages/indexer-cli/src/__tests__/references/indexer-help.stdout +++ b/packages/indexer-cli/src/__tests__/references/indexer-help.stdout @@ -10,6 +10,12 @@ Manage indexer configuration indexer rules delete Remove one or many indexing rules indexer rules clear (reset) Clear one or more indexing rules indexer rules Configure indexing rules + indexer provision thaw Thaw stake from the indexer's provision + indexer provision remove Remove thawed stake from the indexer's provision + indexer provision list-thaw List thaw requests for the indexer's provision + indexer provision get List indexer provision details + indexer provision add Add stake to the indexer's provision + indexer provision Manage indexer's provision indexer disputes get Cross-check POIs submitted in the network indexer disputes Configure allocation POI monitoring indexer cost set model Update a cost model diff --git a/packages/indexer-cli/src/__tests__/references/indexer-rules-invalid-set-arg.stdout b/packages/indexer-cli/src/__tests__/references/indexer-rules-invalid-set-arg.stdout index 332674874..50ffde39a 100644 --- a/packages/indexer-cli/src/__tests__/references/indexer-rules-invalid-set-arg.stdout +++ b/packages/indexer-cli/src/__tests__/references/indexer-rules-invalid-set-arg.stdout @@ -1,4 +1 @@ -Error: Indexing rule attribute 'allocationAmoewt' not supported, did you mean? -- allocationAmount -- allocationLifetime -- maxAllocationPercentage +Error: allocationAmoewt diff --git a/packages/indexer-cli/src/__tests__/references/indexer.stdout b/packages/indexer-cli/src/__tests__/references/indexer.stdout index dd33b2010..4be8ef97d 100644 --- a/packages/indexer-cli/src/__tests__/references/indexer.stdout +++ b/packages/indexer-cli/src/__tests__/references/indexer.stdout @@ -10,6 +10,12 @@ Manage indexer configuration indexer rules delete Remove one or many indexing rules indexer rules clear (reset) Clear one or more indexing rules indexer rules Configure indexing rules + indexer provision thaw Thaw stake from the indexer's provision + indexer provision remove Remove thawed stake from the indexer's provision + indexer provision list-thaw List thaw requests for the indexer's provision + indexer provision get List indexer provision details + indexer provision add Add stake to the indexer's provision + indexer provision Manage indexer's provision indexer disputes get Cross-check POIs submitted in the network indexer disputes Configure allocation POI monitoring indexer cost set model Update a cost model diff --git a/packages/indexer-cli/src/__tests__/util.ts b/packages/indexer-cli/src/__tests__/util.ts index bf702416a..51dc630bf 100644 --- a/packages/indexer-cli/src/__tests__/util.ts +++ b/packages/indexer-cli/src/__tests__/util.ts @@ -5,7 +5,6 @@ import { Socket } from 'net' import { URL } from 'url' import path from 'path' import { Sequelize } from 'sequelize' -import stripAnsi from 'strip-ansi' import { ActionStatus, ActionType, @@ -56,6 +55,22 @@ let metrics: Metrics const yamlObj = loadTestYamlConfig() const testNetworkSpecification = specification.NetworkSpecification.parse(yamlObj) +// Replace strip-ansi with a simple function using the same regex pattern +// Based on ansi-regex v6.1.0 pattern +function stripAnsi(str: string): string { + if (typeof str !== 'string') { + throw new TypeError(`Expected a string, got ${typeof str}`) + } + + // Regex pattern from ansi-regex + const pattern = [ + '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?(?:\\u0007|\\u001B\\u005C|\\u009C))', + '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))', + ].join('|') + + return str.replace(new RegExp(pattern, 'g'), '') +} + export const setupMultiNetworks = async () => { return await setup(true) } @@ -93,6 +108,7 @@ export const setup = async (multiNetworksEnabled: boolean) => { const network = await Network.create( logger, testNetworkSpecification, + models, queryFeeModels, graphNode, metrics, @@ -279,6 +295,7 @@ export const seedActions = async () => { source: 'test', reason: 'test', protocolNetwork: 'eip155:421614', + isLegacy: false, }) await models.Action.create({ id: 2, @@ -288,6 +305,7 @@ export const seedActions = async () => { source: 'test', reason: 'test', protocolNetwork: 'eip155:421614', + isLegacy: false, }) } catch (e) { logger.error('Failed to seed ', { error: e }) diff --git a/packages/indexer-cli/src/actions.ts b/packages/indexer-cli/src/actions.ts index f7ccab61c..7545d80ba 100644 --- a/packages/indexer-cli/src/actions.ts +++ b/packages/indexer-cli/src/actions.ts @@ -14,8 +14,8 @@ import { } from '@graphprotocol/indexer-common' import { validatePOI, validateRequiredParams } from './command-helpers' import gql from 'graphql-tag' -import { utils } from 'ethers' -import { parseGRT } from '@graphprotocol/common-ts' +import { hexlify } from 'ethers' +import { formatGRT, parseGRT } from '@graphprotocol/common-ts' export interface GenericActionInputParams { targetDeployment: string @@ -23,6 +23,8 @@ export interface GenericActionInputParams { param2: string | undefined param3: string | undefined param4: string | undefined + param5: string | undefined + param6: string | undefined } // Make separate functions for each action type parsing from generic? @@ -36,6 +38,11 @@ export async function buildActionInput( protocolNetwork: string, ): Promise { await validateActionInput(type, actionParams) + + // TODO HORIZON: we could check isHorizon status here to set the proper value for isLegacy, but it requires multiNetworks + // The IndexerManagementServer will set the correct value anyways + const isLegacy = false + switch (type) { case ActionType.ALLOCATE: return { @@ -47,16 +54,19 @@ export async function buildActionInput( status, priority, protocolNetwork, + isLegacy, } case ActionType.UNALLOCATE: { let poi = actionParams.param2 if (poi == '0' || poi == '0x0') { - poi = utils.hexlify(Array(32).fill(0)) + poi = hexlify(new Uint8Array(32).fill(0)) } return { deploymentID: actionParams.targetDeployment, allocationID: actionParams.param1, poi: poi, + publicPOI: actionParams.param5, + poiBlockNumber: actionParams.param4 ? Number(actionParams.param4) : undefined, force: actionParams.param3 === 'true', type, source, @@ -64,18 +74,21 @@ export async function buildActionInput( status, priority, protocolNetwork, + isLegacy, } } case ActionType.REALLOCATE: { let poi = actionParams.param3 if (poi == '0' || poi == '0x0') { - poi = utils.hexlify(Array(32).fill(0)) + poi = hexlify(new Uint8Array(32).fill(0)) } return { deploymentID: actionParams.targetDeployment, allocationID: actionParams.param1, amount: actionParams.param2?.toString(), poi: poi, + publicPOI: actionParams.param6, + poiBlockNumber: actionParams.param5 ? Number(actionParams.param5) : undefined, force: actionParams.param4 === 'true', type, source, @@ -83,6 +96,7 @@ export async function buildActionInput( status, priority, protocolNetwork, + isLegacy, } } } @@ -182,12 +196,15 @@ export async function queueActions( allocationID amount poi + publicPOI + poiBlockNumber force source reason priority status protocolNetwork + isLegacy } } `, @@ -208,11 +225,33 @@ const ACTION_PARAMS_PARSERS: Record any> allocationID: x => x, amount: nullPassThrough(parseGRT), poi: nullPassThrough((x: string) => validatePOI(x)), + publicPOI: nullPassThrough((x: string) => validatePOI(x)), + poiBlockNumber: nullPassThrough((x: string) => Number(x)), force: x => parseBoolean(x), type: x => validateActionType(x), status: x => validateActionStatus(x), reason: nullPassThrough, protocolNetwork: x => validateNetworkIdentifier(x), + isLegacy: x => parseBoolean(x), +} + +const ACTION_CONVERTERS_TO_GRAPHQL: Record< + keyof ActionUpdateInput, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (x: never) => any +> = { + deploymentID: x => x, + allocationID: x => x, + amount: nullPassThrough((x: bigint) => formatGRT(x)), + poi: x => x, + publicPOI: x => x, + poiBlockNumber: nullPassThrough((x: number) => x), + force: x => x, + type: x => x, + status: x => x, + reason: x => x, + protocolNetwork: x => x, + isLegacy: x => x, } /** @@ -232,6 +271,22 @@ export const parseActionUpdateInput = (input: object): ActionUpdateInput => { return obj as ActionUpdateInput } +/** + * Converts a normalized action to a representation + * compatible with the indexer management GraphQL API. + */ +export const actionToGraphQL = ( + action: Partial, +): Partial => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const obj = {} as any + for (const [key, value] of Object.entries(action)) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + obj[key] = (ACTION_CONVERTERS_TO_GRAPHQL as any)[key](value) + } + return obj as Partial +} + export async function executeApprovedActions( client: IndexerManagementClient, ): Promise { @@ -248,11 +303,14 @@ export async function executeApprovedActions( allocationID amount poi + publicPOI + poiBlockNumber force source reason transaction failureReason + isLegacy } } `, @@ -282,6 +340,8 @@ export async function approveActions( deploymentID amount poi + publicPOI + poiBlockNumber force source reason @@ -289,6 +349,7 @@ export async function approveActions( transaction status protocolNetwork + isLegacy } } `, @@ -319,12 +380,15 @@ export async function cancelActions( deploymentID amount poi + publicPOI + poiBlockNumber force source reason priority transaction status + isLegacy } } `, @@ -355,12 +419,15 @@ export async function fetchAction( deploymentID amount poi + publicPOI + poiBlockNumber force source reason priority transaction status + isLegacy } } `, @@ -404,6 +471,8 @@ export async function fetchActions( deploymentID amount poi + publicPOI + poiBlockNumber force source reason @@ -411,6 +480,7 @@ export async function fetchActions( transaction status failureReason + isLegacy } } `, @@ -441,6 +511,8 @@ export async function deleteActions( deploymentID amount poi + publicPOI + poiBlockNumber force source reason @@ -448,6 +520,7 @@ export async function deleteActions( transaction status failureReason + isLegacy } } `, @@ -478,6 +551,8 @@ export async function updateActions( deploymentID amount poi + publicPOI + poiBlockNumber force source reason @@ -486,10 +561,11 @@ export async function updateActions( status failureReason protocolNetwork + isLegacy } } `, - { filter, action }, + { filter, action: actionToGraphQL(action) }, ) .toPromise() diff --git a/packages/indexer-cli/src/allocations.ts b/packages/indexer-cli/src/allocations.ts index 16cd86fdd..445582059 100644 --- a/packages/indexer-cli/src/allocations.ts +++ b/packages/indexer-cli/src/allocations.ts @@ -1,9 +1,8 @@ -import { SubgraphDeploymentID, formatGRT } from '@graphprotocol/common-ts' +import { SubgraphDeploymentID, formatGRT, commify } from '@graphprotocol/common-ts' import yaml from 'yaml' import { GluegunPrint } from 'gluegun' import { table, getBorderCharacters } from 'table' -import { BigNumber, utils } from 'ethers' -import { OutputFormat, parseOutputFormat, pickFields } from './command-helpers' +import { OutputFormat, parseOutputFormat, pickFields, wrapCell } from './command-helpers' import { IndexerManagementClient } from '@graphprotocol/indexer-common' import gql from 'graphql-tag' import { @@ -17,19 +16,20 @@ export interface IndexerAllocation { id: number indexer: string subgraphDeployment: string - allocatedTokens: BigNumber - signalledTokens: BigNumber - stakedTokens: BigNumber + allocatedTokens: bigint + signalledTokens: bigint + stakedTokens: bigint createdAtEpoch: number closedAtEpoch: number | null ageInEpochs: number closeDeadlineEpoch: number closeDeadlineBlocksRemaining: number closeDeadlineTimeRemaining: number - indexingRewards: BigNumber - queryFeesCollected: BigNumber + indexingRewards: bigint + queryFeesCollected: bigint status: string protocolNetwork: string + isLegacy: boolean } const ALLOCATION_CONVERTERS_FROM_GRAPHQL: Record< @@ -41,19 +41,20 @@ const ALLOCATION_CONVERTERS_FROM_GRAPHQL: Record< indexer: x => x, subgraphDeployment: (d: SubgraphDeploymentID) => typeof d === 'string' ? d : d.ipfsHash, - allocatedTokens: nullPassThrough((x: string) => BigNumber.from(x)), - signalledTokens: nullPassThrough((x: string) => BigNumber.from(x)), - stakedTokens: nullPassThrough((x: string) => BigNumber.from(x)), + allocatedTokens: nullPassThrough((x: string) => BigInt(x)), + signalledTokens: nullPassThrough((x: string) => BigInt(x)), + stakedTokens: nullPassThrough((x: string) => BigInt(x)), createdAtEpoch: nullPassThrough((x: string) => parseInt(x)), closedAtEpoch: nullPassThrough((x: string) => parseInt(x)), ageInEpochs: nullPassThrough((x: string) => parseInt(x)), closeDeadlineEpoch: nullPassThrough((x: string) => parseInt(x)), closeDeadlineBlocksRemaining: nullPassThrough((x: string) => parseInt(x)), closeDeadlineTimeRemaining: nullPassThrough((x: string) => parseInt(x)), - indexingRewards: nullPassThrough((x: string) => BigNumber.from(x)), - queryFeesCollected: nullPassThrough((x: string) => BigNumber.from(x)), + indexingRewards: nullPassThrough((x: string) => BigInt(x)), + queryFeesCollected: nullPassThrough((x: string) => BigInt(x)), status: x => x, protocolNetwork: x => x, + isLegacy: x => x, } const ALLOCATION_FORMATTERS: Record< @@ -64,19 +65,20 @@ const ALLOCATION_FORMATTERS: Record< indexer: nullPassThrough(x => x), subgraphDeployment: (d: SubgraphDeploymentID) => typeof d === 'string' ? d : d.ipfsHash, - allocatedTokens: x => utils.commify(formatGRT(x)), - signalledTokens: x => utils.commify(formatGRT(x)), - stakedTokens: x => utils.commify(formatGRT(x)), + allocatedTokens: x => commify(formatGRT(x)), + signalledTokens: x => commify(formatGRT(x)), + stakedTokens: x => commify(formatGRT(x)), createdAtEpoch: x => x, closedAtEpoch: x => x, ageInEpochs: x => x, closeDeadlineEpoch: x => x, closeDeadlineBlocksRemaining: x => x, closeDeadlineTimeRemaining: x => x, - indexingRewards: x => utils.commify(formatGRT(x)), - queryFeesCollected: x => utils.commify(formatGRT(x)), + indexingRewards: x => commify(formatGRT(x)), + queryFeesCollected: x => commify(formatGRT(x)), status: x => x, protocolNetwork: resolveChainAlias, + isLegacy: x => (x ? 'Yes' : 'No'), } /** @@ -119,16 +121,17 @@ export const printIndexerAllocations = ( | Partial[] | null, keys: (keyof IndexerAllocation)[], + wrapWidth: number = 0, ): void => { parseOutputFormat(print, outputFormat) if (Array.isArray(allocationOrAllocations)) { const allocations = allocationOrAllocations.map(allocation => formatIndexerAllocation(pickFields(allocation, keys)), ) - print.info(displayIndexerAllocations(outputFormat, allocations)) + print.info(displayIndexerAllocations(outputFormat, allocations, wrapWidth)) } else if (allocationOrAllocations) { const allocation = formatIndexerAllocation(pickFields(allocationOrAllocations, keys)) - print.info(displayIndexerAllocation(outputFormat, allocation)) + print.info(displayIndexerAllocation(outputFormat, allocation, wrapWidth)) } else { print.error(`No allocations found`) } @@ -137,6 +140,7 @@ export const printIndexerAllocations = ( export const displayIndexerAllocations = ( outputFormat: OutputFormat, allocations: Partial[], + wrapWidth: number, ): string => outputFormat === OutputFormat.Json ? JSON.stringify(allocations, null, 2) @@ -147,7 +151,9 @@ export const displayIndexerAllocations = ( : table( [ Object.keys(allocations[0]), - ...allocations.map(allocation => Object.values(allocation)), + ...allocations.map(allocation => + Object.values(allocation).map(value => wrapCell(value, wrapWidth)), + ), ], { border: getBorderCharacters('norc'), @@ -157,14 +163,21 @@ export const displayIndexerAllocations = ( export const displayIndexerAllocation = ( outputFormat: OutputFormat, allocation: Partial, + wrapWidth: number, ): string => outputFormat === OutputFormat.Json ? JSON.stringify(allocation, null, 2) : outputFormat === OutputFormat.Yaml ? yaml.stringify(allocation).trim() - : table([Object.keys(allocation), Object.values(allocation)], { - border: getBorderCharacters('norc'), - }).trim() + : table( + [ + Object.keys(allocation), + Object.values(allocation).map(value => wrapCell(value, wrapWidth)), + ], + { + border: getBorderCharacters('norc'), + }, + ).trim() function nullPassThrough(fn: (x: T) => U): (x: T | null) => U | null { return (x: T | null) => (x === null ? null : fn(x)) @@ -173,7 +186,7 @@ function nullPassThrough(fn: (x: T) => U): (x: T | null) => U | null { export const createAllocation = async ( client: IndexerManagementClient, deployment: string, - amount: BigNumber, + amount: bigint, indexNode: string | undefined, protocolNetwork: string, ): Promise => { @@ -219,6 +232,8 @@ export const closeAllocation = async ( client: IndexerManagementClient, allocationID: string, poi: string | undefined, + blockNumber: number | undefined, + publicPOI: string | undefined, force: boolean, protocolNetwork: string, ): Promise => { @@ -228,19 +243,22 @@ export const closeAllocation = async ( mutation closeAllocation( $allocation: String! $poi: String + $blockNumber: Int + $publicPOI: String $force: Boolean $protocolNetwork: String! ) { closeAllocation( allocation: $allocation poi: $poi + blockNumber: $blockNumber + publicPOI: $publicPOI force: $force protocolNetwork: $protocolNetwork ) { allocation allocatedTokens indexingRewards - receiptsWorthCollecting protocolNetwork } } @@ -248,6 +266,8 @@ export const closeAllocation = async ( { allocation: allocationID, poi, + blockNumber: blockNumber, + publicPOI, force, protocolNetwork, }, @@ -265,7 +285,9 @@ export const reallocateAllocation = async ( client: IndexerManagementClient, allocationID: string, poi: string | undefined, - amount: BigNumber, + blockNumber: number | undefined, + publicPOI: string | undefined, + amount: bigint, force: boolean, protocolNetwork: string, ): Promise => { @@ -275,6 +297,8 @@ export const reallocateAllocation = async ( mutation reallocateAllocation( $allocation: String! $poi: String + $blockNumber: Int + $publicPOI: String $amount: String! $force: Boolean $protocolNetwork: String! @@ -282,13 +306,14 @@ export const reallocateAllocation = async ( reallocateAllocation( allocation: $allocation poi: $poi + blockNumber: $blockNumber + publicPOI: $publicPOI amount: $amount force: $force protocolNetwork: $protocolNetwork ) { closedAllocation indexingRewardsCollected - receiptsWorthCollecting createdAllocation createdAllocationStake protocolNetwork @@ -298,6 +323,8 @@ export const reallocateAllocation = async ( { allocation: allocationID, poi, + blockNumber: blockNumber, + publicPOI, amount: amount.toString(), force, protocolNetwork, diff --git a/packages/indexer-cli/src/command-helpers.ts b/packages/indexer-cli/src/command-helpers.ts index 2d8b1aef8..212a9b7c8 100644 --- a/packages/indexer-cli/src/command-helpers.ts +++ b/packages/indexer-cli/src/command-helpers.ts @@ -27,6 +27,7 @@ // parameters array and returns the result of that. import { table, getBorderCharacters } from 'table' +import wrapAnsi from 'wrap-ansi' export enum OutputFormat { Table = 'table', @@ -35,8 +36,8 @@ export enum OutputFormat { } import yaml from 'yaml' import { GluegunParameters, GluegunPrint } from 'gluegun' -import { utils } from 'ethers' import { validateNetworkIdentifier } from '@graphprotocol/indexer-common' +import { hexlify, isHexString } from 'ethers' export const fixParameters = ( parameters: GluegunParameters, @@ -104,29 +105,48 @@ export function pickFields( return obj } -export function displayObjectData(outputFormat: OutputFormat, data: object): string { - return outputFormat === OutputFormat.Json - ? JSON.stringify(data, null, 2) - : outputFormat === OutputFormat.Yaml - ? yaml.stringify(data).trim() - : table([Object.keys(data), Object.values(data)], { - border: getBorderCharacters('norc'), - }).trim() +export function displayObjectData( + outputFormat: OutputFormat, + data: object, + wrapWidth: number, +): string { + if (outputFormat === OutputFormat.Json) { + return JSON.stringify(data, null, 2) + } else if (outputFormat === OutputFormat.Yaml) { + return yaml.stringify(data).trim() + } else { + const keys = Object.keys(data) + const values = Object.values(data).map(value => wrapCell(value, wrapWidth)) + + return table([keys, values], { + border: getBorderCharacters('norc'), + }).trim() + } } export function displayObjectArrayData( outputFormat: OutputFormat, data: object[], + wrapWidth: number, ): string { - return outputFormat === OutputFormat.Json - ? JSON.stringify(data, null, 2) - : outputFormat === OutputFormat.Yaml - ? yaml.stringify(data).trim() - : data.length === 0 - ? 'No items found' - : table([Object.keys(data[0]), ...data.map(item => Object.values(item))], { - border: getBorderCharacters('norc'), - }).trim() + if (outputFormat === OutputFormat.Json) { + return JSON.stringify(data, null, 2) + } else if (outputFormat === OutputFormat.Yaml) { + return yaml.stringify(data).trim() + } else if (data.length === 0) { + return 'No items found' + } else { + const keys = Object.keys(data[0]) + + const tableData = [ + keys, + ...data.map(item => keys.map(key => wrapCell((item as any)[key], wrapWidth))), + ] + + return table(tableData, { + border: getBorderCharacters('norc'), + }).trim() + } } export function printObjectOrArray( @@ -134,12 +154,13 @@ export function printObjectOrArray( outputFormat: OutputFormat, data: object | object[], keys: string[], + wrapWidth: number = 0, ): void { if (Array.isArray(data)) { const formatted = data.map(item => pickFields(item, keys)) - print.info(displayObjectArrayData(outputFormat, formatted)) + print.info(displayObjectArrayData(outputFormat, formatted, wrapWidth)) } else if (data) { - print.info(displayObjectData(outputFormat, pickFields(data, keys))) + print.info(displayObjectData(outputFormat, pickFields(data, keys), wrapWidth)) } else { print.error(`No items returned`) } @@ -159,13 +180,13 @@ export async function validateRequiredParams( export function validatePOI(poi: string | undefined): string | undefined { if (poi !== undefined) { if (typeof poi == 'number' && poi == 0) { - poi = utils.hexlify(Array(32).fill(0)) + poi = hexlify(new Uint8Array(32).fill(0)) } if (typeof poi == 'string' && poi == '0') { - poi = utils.hexlify(Array(32).fill(0)) + poi = hexlify(new Uint8Array(32).fill(0)) } // Ensure user provided POI is formatted properly - '0x...' (32 bytes) - const isHex = utils.isHexString(poi, 32) + const isHex = isHexString(poi, 32) if (!isHex) { throw new Error( `Invalid POI provided ('${poi}'): Must be a 32 byte length hex string`, @@ -251,3 +272,9 @@ export function requireProtocolNetworkOption(options: { [key: string]: any }): s } return protocolNetwork } + +export function wrapCell(value: unknown, wrapWidth: number): string { + return wrapWidth > 0 + ? wrapAnsi(String(value), wrapWidth, { hard: true }) + : String(value) +} diff --git a/packages/indexer-cli/src/commands/indexer/actions/approve.ts b/packages/indexer-cli/src/commands/indexer/actions/approve.ts index 52e32f55c..f6ce87520 100644 --- a/packages/indexer-cli/src/commands/indexer/actions/approve.ts +++ b/packages/indexer-cli/src/commands/indexer/actions/approve.ts @@ -114,11 +114,14 @@ module.exports = { 'allocationID', 'amount', 'poi', + 'publicPOI', + 'poiBlockNumber', 'force', 'priority', 'status', 'source', 'reason', + 'isLegacy', ]) } catch (error) { actionSpinner.fail(error.toString()) diff --git a/packages/indexer-cli/src/commands/indexer/actions/cancel.ts b/packages/indexer-cli/src/commands/indexer/actions/cancel.ts index d5b74701c..3fc105951 100644 --- a/packages/indexer-cli/src/commands/indexer/actions/cancel.ts +++ b/packages/indexer-cli/src/commands/indexer/actions/cancel.ts @@ -80,11 +80,14 @@ module.exports = { 'allocationID', 'amount', 'poi', + 'publicPOI', + 'poiBlockNumber', 'force', 'priority', 'status', 'source', 'reason', + 'isLegacy', ]) } catch (error) { actionSpinner.fail(error.toString()) diff --git a/packages/indexer-cli/src/commands/indexer/actions/execute.ts b/packages/indexer-cli/src/commands/indexer/actions/execute.ts index a742f21cd..422879651 100644 --- a/packages/indexer-cli/src/commands/indexer/actions/execute.ts +++ b/packages/indexer-cli/src/commands/indexer/actions/execute.ts @@ -74,12 +74,15 @@ module.exports = { 'allocationID', 'amount', 'poi', + 'publicPOI', + 'poiBlockNumber', 'force', 'priority', 'transaction', 'failureReason', 'source', 'reason', + 'isLegacy', ]) } catch (error) { spinner.fail(error.toString()) diff --git a/packages/indexer-cli/src/commands/indexer/actions/get.ts b/packages/indexer-cli/src/commands/indexer/actions/get.ts index f1916eb04..38b6c3a53 100644 --- a/packages/indexer-cli/src/commands/indexer/actions/get.ts +++ b/packages/indexer-cli/src/commands/indexer/actions/get.ts @@ -32,6 +32,7 @@ ${chalk.dim('Options:')} --first [N] Fetch only the N first records (default: all records) --fields [field1,field2,...] Comma-separated names of the fields to display (no spaces allowed between fields) -o, --output table|json|yaml Choose the output format: table (default), JSON, or YAML + -w, --wrap [N] Wrap the output to a specific width (default: 0, no wrapping) ` const actionFields: (keyof Action)[] = [ @@ -42,6 +43,8 @@ const actionFields: (keyof Action)[] = [ 'allocationID', 'amount', 'poi', + 'publicPOI', + 'poiBlockNumber', 'force', 'priority', 'status', @@ -49,6 +52,7 @@ const actionFields: (keyof Action)[] = [ 'failureReason', 'transaction', 'reason', + 'isLegacy', ] /// Validates input for the `--fieds` option. @@ -89,12 +93,15 @@ module.exports = { output, first, fields, + w, + wrap, } = parameters.options const [action] = fixParameters(parameters, { h, help }) || [] let orderByParam = ActionParams.ID let orderDirectionValue = OrderDirection.DESC const outputFormat = o || output || 'table' + const wrapWidth = w || wrap || 0 const protocolNetwork: string | undefined = extractProtocolNetworkOption( parameters.options, @@ -223,7 +230,7 @@ module.exports = { action => (action.protocolNetwork = resolveChainAlias(action.protocolNetwork)), ) - printObjectOrArray(print, outputFormat, actions, displayProperties) + printObjectOrArray(print, outputFormat, actions, displayProperties, wrapWidth) } catch (error) { actionSpinner.fail(error.toString()) process.exitCode = 1 diff --git a/packages/indexer-cli/src/commands/indexer/actions/queue.ts b/packages/indexer-cli/src/commands/indexer/actions/queue.ts index ef1d74ddb..0e13d33f0 100644 --- a/packages/indexer-cli/src/commands/indexer/actions/queue.ts +++ b/packages/indexer-cli/src/commands/indexer/actions/queue.ts @@ -17,23 +17,25 @@ import { const HELP = ` ${chalk.bold( 'graph indexer actions queue', -)} [options] +)} [options] ${chalk.bold('graph indexer actions queue')} [options] allocate ${chalk.bold( 'graph indexer actions queue', -)} [options] unallocate +)} [options] unallocate ${chalk.bold( 'graph indexer actions queue', -)} [options] reallocate +)} [options] reallocate ${chalk.dim('Options:')} -h, --help Show usage information - -n, --network [Required] The protocol network for this action (mainnet, arbitrum-one, sepolia, arbitrum-sepolia) + -n, --network The protocol network for this action (mainnet, arbitrum-one, sepolia, arbitrum-sepolia) -o, --output table|json|yaml Choose the output format: table (default), JSON, or YAML -s, --source Specify the source of the action decision -r, --reason Specify the reason for the action to be taken -p, --priority Define a priority order for the action + + For action type specific options, see the help for the specific action type. ` module.exports = { @@ -62,7 +64,7 @@ module.exports = { return } - const [type, targetDeployment, param1, param2, param3, param4] = + const [type, targetDeployment, param1, param2, param3, param4, param5, param6] = parameters.array || [] let actionInputParams: ActionInput @@ -77,7 +79,7 @@ module.exports = { actionInputParams = await buildActionInput( validateActionType(type), - { targetDeployment, param1, param2, param3, param4 }, + { targetDeployment, param1, param2, param3, param4, param5, param6 }, decisionSource, decisionReason, ActionStatus.QUEUED, @@ -117,11 +119,14 @@ module.exports = { 'allocationID', 'amount', 'poi', + 'publicPOI', + 'poiBlockNumber', 'force', 'priority', 'status', 'source', 'reason', + 'isLegacy', ]) } catch (error) { actionSpinner.fail(error.toString()) diff --git a/packages/indexer-cli/src/commands/indexer/actions/update.ts b/packages/indexer-cli/src/commands/indexer/actions/update.ts index 0d27d8f31..cfadabdc8 100644 --- a/packages/indexer-cli/src/commands/indexer/actions/update.ts +++ b/packages/indexer-cli/src/commands/indexer/actions/update.ts @@ -108,6 +108,8 @@ module.exports = { 'allocationID', 'amount', 'poi', + 'publicPOI', + 'poiBlockNumber', 'force', 'priority', 'status', @@ -115,6 +117,7 @@ module.exports = { 'failureReason', 'transaction', 'reason', + 'isLegacy', ] // Format Actions 'protocolNetwork' field to display human-friendly chain aliases instead of CAIP2-IDs diff --git a/packages/indexer-cli/src/commands/indexer/allocations/close.ts b/packages/indexer-cli/src/commands/indexer/allocations/close.ts index 796493939..3e4c033c4 100644 --- a/packages/indexer-cli/src/commands/indexer/allocations/close.ts +++ b/packages/indexer-cli/src/commands/indexer/allocations/close.ts @@ -4,20 +4,30 @@ import chalk from 'chalk' import { loadValidatedConfig } from '../../../config' import { createIndexerManagementClient } from '../../../client' import { closeAllocation } from '../../../allocations' -import { validatePOI, printObjectOrArray } from '../../../command-helpers' -import { validateNetworkIdentifier } from '@graphprotocol/indexer-common' +import { + validatePOI, + printObjectOrArray, + extractProtocolNetworkOption, +} from '../../../command-helpers' const HELP = ` -${chalk.bold('graph indexer allocations close')} [options] +${chalk.bold( + 'graph indexer allocations close', +)} [options] ${chalk.dim('Options:')} -h, --help Show usage information - -f, --force Bypass POIaccuracy checks and submit transaction with provided data + -n, --network The network to close the allocation on: mainnet, arbitrum-one, sepolia or arbitrum sepolia + -f, --force Bypass POI accuracy checks and submit transaction with provided data -o, --output table|json|yaml Choose the output format: table (default), JSON, or YAML + -w, --wrap [N] Wrap the output to a specific width (default: 0, no wrapping) -${chalk.dim('Networks:')} - mainnet, arbitrum-one, sepolia or arbitrum sepolia +${chalk.dim('Arguments:')} + The allocation id to close + (optional) The POI to close the allocation with + (optional, horizon only) The block number the POI was computed at. Must be set if POI is provided. + (optional, horizon only) The public POI to close the allocation with. Must be same block height as POI. ` module.exports = { @@ -29,11 +39,12 @@ module.exports = { const spinner = toolbox.print.spin('Processing inputs') - const { h, help, f, force, o, output } = parameters.options + const { h, help, f, force, o, output, w, wrap } = parameters.options const outputFormat = o || output || 'table' const toHelp = help || h || undefined const toForce = force || f || false + const wrapWidth = w || wrap || 0 if (toHelp) { spinner.stopAndPersist({ symbol: '💁', text: HELP }) @@ -46,7 +57,8 @@ module.exports = { return } - const [network, id, unformattedPoi] = parameters.array || [] + const [id, unformattedPoi, unformattedBlockNumber, unformattedPublicPOI] = + parameters.array || [] if (id === undefined) { spinner.fail(`Missing required argument: 'id'`) @@ -55,44 +67,50 @@ module.exports = { return } - let protocolNetwork: string - if (!network) { - spinner.fail(`Missing required argument: 'network'`) - print.info(HELP) - process.exitCode = 1 - return - } else { - try { - protocolNetwork = validateNetworkIdentifier(network) - } catch (error) { - spinner.fail(`Invalid value for argument 'network': '${network}' `) - process.exitCode = 1 - return - } - } - let poi: string | undefined + let blockNumber: number | undefined + let publicPOI: string | undefined try { poi = validatePOI(unformattedPoi) + publicPOI = validatePOI(unformattedPublicPOI) + blockNumber = + unformattedBlockNumber === undefined ? undefined : Number(unformattedBlockNumber) } catch (error) { - spinner.fail(`Invalid POI provided, '${unformattedPoi}'. ` + error.message) + spinner.fail(`Invalid value provided: ` + error.message) process.exitCode = 1 return } spinner.text = `Closing allocation '${id}` try { + const protocolNetwork = extractProtocolNetworkOption(parameters.options, true) + + if (!protocolNetwork) { + throw new Error( + 'Must provide a network identifier' + `(network: '${protocolNetwork}')`, + ) + } + const config = loadValidatedConfig() const client = await createIndexerManagementClient({ url: config.api }) - const closeResult = await closeAllocation(client, id, poi, toForce, protocolNetwork) + const closeResult = await closeAllocation( + client, + id, + poi, + blockNumber, + publicPOI, + toForce, + protocolNetwork, + ) spinner.succeed('Allocation closed') - printObjectOrArray(print, outputFormat, closeResult, [ - 'allocation', - 'allocatedTokens', - 'indexingRewards', - 'receiptsWorthCollecting', - ]) + printObjectOrArray( + print, + outputFormat, + closeResult, + ['allocation', 'allocatedTokens', 'indexingRewards'], + wrapWidth, + ) } catch (error) { spinner.fail(error.toString()) process.exitCode = 1 diff --git a/packages/indexer-cli/src/commands/indexer/allocations/collect.ts b/packages/indexer-cli/src/commands/indexer/allocations/collect.ts index 4730988d2..d0b293b17 100644 --- a/packages/indexer-cli/src/commands/indexer/allocations/collect.ts +++ b/packages/indexer-cli/src/commands/indexer/allocations/collect.ts @@ -4,7 +4,7 @@ import chalk from 'chalk' import { loadValidatedConfig } from '../../../config' import { createIndexerManagementClient } from '../../../client' import { submitCollectReceiptsJob } from '../../../allocations' -import { validateNetworkIdentifier } from '@graphprotocol/indexer-common' +import { extractProtocolNetworkOption } from '../../../command-helpers' const HELP = ` ${chalk.bold('graph indexer allocations collect')} [options] @@ -12,10 +12,8 @@ ${chalk.bold('graph indexer allocations collect')} [options] ${chalk.dim('Options:')} -h, --help Show usage information + -n, --network The protocol network for this action (mainnet, arbitrum-one, sepolia, arbitrum-sepolia) -o, --output table|json|yaml Choose the output format: table (default), JSON, or YAML - -${chalk.dim('Networks:')} - mainnet, arbitrum-one, sepolia or arbitrum sepolia ` module.exports = { @@ -43,7 +41,7 @@ module.exports = { return } - const [network, id] = parameters.array || [] + const [id] = parameters.array || [] if (id === undefined) { spinner.fail(`Missing required argument: 'id'`) @@ -52,24 +50,16 @@ module.exports = { return } - let protocolNetwork: string - if (!network) { - spinner.fail(`Missing required argument: 'network'`) - print.info(HELP) - process.exitCode = 1 - return - } else { - try { - protocolNetwork = validateNetworkIdentifier(network) - } catch (error) { - spinner.fail(`Invalid value for argument 'network': '${network}' `) - process.exitCode = 1 - return - } - } - spinner.text = `Collecting receipts for allocation '${id}` try { + const protocolNetwork = extractProtocolNetworkOption(parameters.options, true) + + if (!protocolNetwork) { + throw new Error( + 'Must provide a network identifier' + `(network: '${protocolNetwork}')`, + ) + } + const config = loadValidatedConfig() const client = await createIndexerManagementClient({ url: config.api }) await submitCollectReceiptsJob(client, id, protocolNetwork) diff --git a/packages/indexer-cli/src/commands/indexer/allocations/create.ts b/packages/indexer-cli/src/commands/indexer/allocations/create.ts index 6986bfbe2..f635e4d34 100644 --- a/packages/indexer-cli/src/commands/indexer/allocations/create.ts +++ b/packages/indexer-cli/src/commands/indexer/allocations/create.ts @@ -3,28 +3,24 @@ import chalk from 'chalk' import { loadValidatedConfig } from '../../../config' import { createIndexerManagementClient } from '../../../client' -import { BigNumber } from 'ethers' import { createAllocation } from '../../../allocations' +import { processIdentifier, SubgraphIdentifierType } from '@graphprotocol/indexer-common' import { - processIdentifier, - SubgraphIdentifierType, - validateNetworkIdentifier, -} from '@graphprotocol/indexer-common' -import { printObjectOrArray } from '../../../command-helpers' + extractProtocolNetworkOption, + printObjectOrArray, +} from '../../../command-helpers' const HELP = ` ${chalk.bold( 'graph indexer allocations create', -)} [options] +)} [options] ${chalk.dim('Options:')} -h, --help Show usage information - -f, --force Bypass POI accuracy checks and submit transaction with provided data + -n, --network The protocol network for this action (mainnet, arbitrum-one, sepolia, arbitrum-sepolia) -o, --output table|json|yaml Choose the output format: table (default), JSON, or YAML - -${chalk.dim('Networks:')} - mainnet, arbitrum-one, sepolia or arbitrum sepolia + -w, --wrap [N] Wrap the output to a specific width (default: 0, no wrapping) ` module.exports = { @@ -36,10 +32,11 @@ module.exports = { const spinner = toolbox.print.spin('Processing inputs') - const { h, help, o, output } = parameters.options + const { h, help, o, output, w, wrap } = parameters.options const outputFormat = o || output || 'table' const toHelp = help || h || undefined + const wrapWidth = w || wrap || 0 if (toHelp) { spinner.stopAndPersist({ symbol: '💁', text: HELP }) @@ -52,9 +49,11 @@ module.exports = { return } - const [deploymentID, protocolNetwork, amount, indexNode] = parameters.array || [] + const [deploymentID, amount, indexNode] = parameters.array || [] try { + const protocolNetwork = extractProtocolNetworkOption(parameters.options, true) + if (!deploymentID || !amount || !protocolNetwork) { throw new Error( 'Must provide a deployment ID, a network identifier and allocation amount' + @@ -62,13 +61,6 @@ module.exports = { ) } - // This nested try block is necessary to complement the parsing error with the 'network' field. - try { - validateNetworkIdentifier(protocolNetwork) - } catch (parsingError) { - throw new Error(`Invalid 'network' provided. ${parsingError}`) - } - const [deploymentString, type] = await processIdentifier(deploymentID, { all: false, global: false, @@ -78,7 +70,7 @@ module.exports = { `Invalid 'deploymentID' provided (${deploymentID}), must be bytes32 or base58 formatted)`, ) } - const allocationAmount = BigNumber.from(amount) + const allocationAmount = BigInt(amount) const config = loadValidatedConfig() const client = await createIndexerManagementClient({ url: config.api }) @@ -93,12 +85,13 @@ module.exports = { ) spinner.succeed('Allocation created') - printObjectOrArray(print, outputFormat, allocateResult, [ - 'allocation', - 'deployment', - 'allocatedTokens', - 'protocolNetwork', - ]) + printObjectOrArray( + print, + outputFormat, + allocateResult, + ['allocation', 'deployment', 'allocatedTokens', 'protocolNetwork'], + wrapWidth, + ) } catch (error) { spinner.fail(error.toString()) process.exitCode = 1 diff --git a/packages/indexer-cli/src/commands/indexer/allocations/get.ts b/packages/indexer-cli/src/commands/indexer/allocations/get.ts index 2ab707567..5be6a6f70 100644 --- a/packages/indexer-cli/src/commands/indexer/allocations/get.ts +++ b/packages/indexer-cli/src/commands/indexer/allocations/get.ts @@ -8,7 +8,7 @@ import gql from 'graphql-tag' import { SubgraphDeploymentID } from '@graphprotocol/common-ts' import { processIdentifier, SubgraphIdentifierType } from '@graphprotocol/indexer-common' import { IndexerAllocation, printIndexerAllocations } from '../../../allocations' -import { utils } from 'ethers' +import { isHexString } from 'ethers' const HELP = ` ${chalk.bold('graph indexer allocations get')} [options] @@ -18,10 +18,11 @@ ${chalk.bold('graph indexer allocations get')} [options] all ${chalk.dim('Options:')} -h, --help Show usage information - -n, --network Filter allocations by their protocol network (mainnet, arbitrum-one, sepolia, arbitrum-sepolia) + -n, --network Filter allocations by their protocol network (mainnet, arbitrum-one, sepolia, arbitrum-sepolia) --status active|closed|claimable Filter by status --deployment Fetch only allocations for a specific subgraph deployment -o, --output table|json|yaml Choose the output format: table (default), JSON, or YAML + -w, --wrap [N] Wrap the output to a specific width (default: 0, no wrapping) ` module.exports = { @@ -33,10 +34,11 @@ module.exports = { const spinner = toolbox.print.spin('Processing inputs') - const { status, deployment, h, help, o, output } = parameters.options + const { status, deployment, h, help, o, output, w, wrap } = parameters.options const [allocation] = fixParameters(parameters, { h, help }) || [] const outputFormat = o || output || 'table' + const wrapWidth = w || wrap || 0 if (help || h) { spinner.stopAndPersist({ symbol: '💁', text: HELP }) @@ -44,7 +46,7 @@ module.exports = { } try { - const protocolNetwork = extractProtocolNetworkOption(parameters.options) + const protocolNetwork = extractProtocolNetworkOption(parameters.options, true) if (!['json', 'yaml', 'table'].includes(outputFormat)) { throw Error( @@ -59,7 +61,7 @@ module.exports = { } if (allocation) { - if (allocation !== 'all' && !utils.isHexString(allocation, 20)) { + if (allocation !== 'all' && !isHexString(allocation, 20)) { throw Error( `Invalid 'allocation-id' provided ('${allocation}'), must be a bytes20 string or 'all'`, ) @@ -99,6 +101,7 @@ module.exports = { query allocations($filter: AllocationFilter!) { allocations(filter: $filter) { id + isLegacy protocolNetwork indexer subgraphDeployment @@ -145,6 +148,7 @@ module.exports = { let displayProperties: (keyof IndexerAllocation)[] = [ 'id', + 'isLegacy', 'protocolNetwork', 'indexer', 'subgraphDeployment', @@ -167,7 +171,13 @@ module.exports = { ) } spinner.succeed('Allocations') - printIndexerAllocations(print, outputFormat, allocations, displayProperties) + printIndexerAllocations( + print, + outputFormat, + allocations, + displayProperties, + wrapWidth, + ) } catch (error) { spinner.fail(error.toString()) process.exitCode = 1 diff --git a/packages/indexer-cli/src/commands/indexer/allocations/reallocate.ts b/packages/indexer-cli/src/commands/indexer/allocations/reallocate.ts index 08abaccc2..95923c4ac 100644 --- a/packages/indexer-cli/src/commands/indexer/allocations/reallocate.ts +++ b/packages/indexer-cli/src/commands/indexer/allocations/reallocate.ts @@ -3,22 +3,31 @@ import chalk from 'chalk' import { loadValidatedConfig } from '../../../config' import { createIndexerManagementClient } from '../../../client' -import { BigNumber } from 'ethers' import { reallocateAllocation } from '../../../allocations' -import { printObjectOrArray, validatePOI } from '../../../command-helpers' +import { + extractProtocolNetworkOption, + printObjectOrArray, + validatePOI, +} from '../../../command-helpers' const HELP = ` ${chalk.bold( 'graph indexer allocations reallocate', -)} [options] +)} [options] ${chalk.dim('Options:')} -h, --help Show usage information + -n, --network The protocol network for this action (mainnet, arbitrum-one, sepolia, arbitrum-sepolia) -f, --force Bypass POI accuracy checks and submit transaction with provided data - -${chalk.dim('Networks:')} - mainnet, arbitrum-one, sepolia or arbitrum sepolia + -w, --wrap [N] Wrap the output to a specific width (default: 0, no wrapping) + + ${chalk.dim('Arguments:')} + The allocation id to close + The amount of GRT to reallocate + (optional) The POI to close the allocation with + (optional, horizon only) The block number the POI was computed at. Must be set if POI is provided. + (optional, horizon only) The public POI to close the allocation with. Must be same block height as POI. ` module.exports = { @@ -30,11 +39,12 @@ module.exports = { const spinner = toolbox.print.spin('Processing inputs') - const { h, help, f, force, o, output } = parameters.options + const { h, help, f, force, o, output, w, wrap } = parameters.options const outputFormat = o || output || 'table' const toHelp = help || h || undefined const toForce = force || f || false + const wrapWidth = w || wrap || 0 if (toHelp) { spinner.stopAndPersist({ symbol: '💁', text: HELP }) @@ -48,14 +58,7 @@ module.exports = { } // eslint-disable-next-line prefer-const - let [network, id, amount, poi] = parameters.array || [] - - if (network === undefined) { - spinner.fail(`Missing required argument: 'network'`) - print.info(HELP) - process.exitCode = 1 - return - } + let [id, amount, poi, unformattedBlockNumber, publicPOI] = parameters.array || [] if (id === undefined) { spinner.fail(`Missing required argument: 'id'`) @@ -72,8 +75,17 @@ module.exports = { } try { + const protocolNetwork = extractProtocolNetworkOption(parameters.options, true) + + if (!protocolNetwork) { + throw new Error( + 'Must provide a network identifier' + `(network: '${protocolNetwork}')`, + ) + } + validatePOI(poi) - const allocationAmount = BigNumber.from(amount) + validatePOI(publicPOI) + const allocationAmount = BigInt(amount) const config = loadValidatedConfig() const client = await createIndexerManagementClient({ url: config.api }) @@ -82,9 +94,11 @@ module.exports = { client, id, poi, + Number(unformattedBlockNumber), + publicPOI, allocationAmount, toForce, - network, + protocolNetwork, ) spinner.succeed('Reallocated') @@ -95,10 +109,10 @@ module.exports = { [ 'closedAllocation', 'indexingRewardsCollected', - 'receiptsWorthCollecting', 'createdAllocation', 'createdAllocationStake', ], + wrapWidth, ) } catch (error) { spinner.fail(error.toString()) diff --git a/packages/indexer-cli/src/commands/indexer/provision.ts b/packages/indexer-cli/src/commands/indexer/provision.ts new file mode 100644 index 000000000..90e214ceb --- /dev/null +++ b/packages/indexer-cli/src/commands/indexer/provision.ts @@ -0,0 +1,15 @@ +import { GluegunToolbox } from 'gluegun' + +module.exports = { + name: 'provision', + alias: [], + description: "Manage indexer's provision", + hidden: false, + dashed: false, + run: async (toolbox: GluegunToolbox) => { + const { print } = toolbox + print.info(toolbox.command?.description) + print.printCommands(toolbox, ['indexer', 'provision']) + process.exitCode = 1 + }, +} diff --git a/packages/indexer-cli/src/commands/indexer/provision/add.ts b/packages/indexer-cli/src/commands/indexer/provision/add.ts new file mode 100644 index 000000000..ce4be5257 --- /dev/null +++ b/packages/indexer-cli/src/commands/indexer/provision/add.ts @@ -0,0 +1,105 @@ +import { GluegunToolbox } from 'gluegun' +import chalk from 'chalk' + +import { loadValidatedConfig } from '../../../config' +import { createIndexerManagementClient } from '../../../client' +import { extractProtocolNetworkOption } from '../../../command-helpers' +import gql from 'graphql-tag' +import { IndexerProvision, printIndexerProvisions } from '../../../provisions' + +const HELP = ` +${chalk.bold('graph indexer provision add')} [options] + +${chalk.dim('Options:')} + + -h, --help Show usage information + -n, --network Filter provisions by their protocol network (mainnet, arbitrum-one, sepolia, arbitrum-sepolia) + -o, --output table|json|yaml Choose the output format: table (default), JSON, or YAML +` + +module.exports = { + name: 'add', + alias: [], + description: "Add stake to the indexer's provision", + run: async (toolbox: GluegunToolbox) => { + const { print, parameters } = toolbox + + const spinner = toolbox.print.spin('Processing inputs') + + const { h, help, o, output } = parameters.options + + const outputFormat = o || output || 'table' + + if (help || h) { + spinner.stopAndPersist({ symbol: '💁', text: HELP }) + return + } + + const [amount] = parameters.array || [] + + try { + if (!amount) { + throw new Error('Must provide an amount to add to the provision') + } + + const protocolNetwork = extractProtocolNetworkOption(parameters.options, true) + + if (!['json', 'yaml', 'table'].includes(outputFormat)) { + throw Error( + `Invalid output format "${outputFormat}" must be one of 'json', 'yaml' or 'table'`, + ) + } + + spinner.text = 'Adding stake to the provision' + const config = loadValidatedConfig() + const client = await createIndexerManagementClient({ url: config.api }) + + const result = await client + .mutation( + gql` + mutation addToProvision($protocolNetwork: String!, $amount: String!) { + addToProvision(protocolNetwork: $protocolNetwork, amount: $amount) { + id + dataService + indexer + tokensProvisioned + protocolNetwork + } + } + `, + { + protocolNetwork, + amount: amount.toString(), + }, + ) + .toPromise() + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + if (result.error) { + throw result.error + } + + const displayProperties: (keyof IndexerProvision)[] = [ + 'dataService', + 'protocolNetwork', + 'tokensProvisioned', + ] + + if (result.data.addToProvision) { + spinner.succeed('Stake added to the provision') + printIndexerProvisions( + print, + outputFormat, + result.data.addToProvision, + displayProperties, + ) + } else { + spinner.fail('Failed to add stake to the provision') + } + } catch (error) { + spinner.fail(error.toString()) + process.exitCode = 1 + return + } + }, +} diff --git a/packages/indexer-cli/src/commands/indexer/provision/get.ts b/packages/indexer-cli/src/commands/indexer/provision/get.ts new file mode 100644 index 000000000..31e9dad99 --- /dev/null +++ b/packages/indexer-cli/src/commands/indexer/provision/get.ts @@ -0,0 +1,114 @@ +import { GluegunToolbox } from 'gluegun' +import chalk from 'chalk' + +import { loadValidatedConfig } from '../../../config' +import { createIndexerManagementClient } from '../../../client' +import { extractProtocolNetworkOption } from '../../../command-helpers' +import gql from 'graphql-tag' +import { IndexerProvision, printIndexerProvisions } from '../../../provisions' +import { commify, formatGRT } from '@graphprotocol/common-ts' + +const HELP = ` +${chalk.bold('graph indexer provision get')} [options] + +${chalk.dim('Options:')} + + -h, --help Show usage information + -n, --network Filter provisions by their protocol network (mainnet, arbitrum-one, sepolia, arbitrum-sepolia) + -o, --output table|json|yaml Choose the output format: table (default), JSON, or YAML +` + +module.exports = { + name: 'get', + alias: [], + description: 'List indexer provision details', + run: async (toolbox: GluegunToolbox) => { + const { print, parameters } = toolbox + + const spinner = toolbox.print.spin('Processing inputs') + + const { h, help, o, output } = parameters.options + + const outputFormat = o || output || 'table' + + if (help || h) { + spinner.stopAndPersist({ symbol: '💁', text: HELP }) + return + } + + try { + const protocolNetwork = extractProtocolNetworkOption(parameters.options, true) + + if (!['json', 'yaml', 'table'].includes(outputFormat)) { + throw Error( + `Invalid output format "${outputFormat}" must be one of 'json', 'yaml' or 'table'`, + ) + } + + spinner.text = 'Querying indexer management server' + const config = loadValidatedConfig() + const client = await createIndexerManagementClient({ url: config.api }) + + const result = await client + .query( + gql` + query provisions($protocolNetwork: String!) { + provisions(protocolNetwork: $protocolNetwork) { + id + dataService + indexer + tokensProvisioned + tokensAllocated + tokensThawing + thawingPeriod + maxVerifierCut + protocolNetwork + idleStake + } + } + `, + { + protocolNetwork, + }, + ) + .toPromise() + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + if (result.error) { + throw result.error + } + + const displayProperties: (keyof IndexerProvision)[] = [ + 'dataService', + 'protocolNetwork', + 'tokensProvisioned', + 'tokensAllocated', + 'tokensThawing', + 'maxVerifierCut', + 'thawingPeriod', + ] + + spinner.succeed('Provisions') + printIndexerProvisions( + print, + outputFormat, + result.data.provisions, + displayProperties, + ) + + print.info('') + print.info( + `Indexer's idle stake: ${commify( + formatGRT(result.data.provisions[0].idleStake), + )} GRT`, + ) + print.info( + "To add this stake to the Subgraph Service provision, run 'graph indexer provision add '", + ) + } catch (error) { + spinner.fail(error.toString()) + process.exitCode = 1 + return + } + }, +} diff --git a/packages/indexer-cli/src/commands/indexer/provision/list-thaw.ts b/packages/indexer-cli/src/commands/indexer/provision/list-thaw.ts new file mode 100644 index 000000000..167c2844a --- /dev/null +++ b/packages/indexer-cli/src/commands/indexer/provision/list-thaw.ts @@ -0,0 +1,110 @@ +import { GluegunToolbox } from 'gluegun' +import chalk from 'chalk' + +import { loadValidatedConfig } from '../../../config' +import { createIndexerManagementClient } from '../../../client' +import { extractProtocolNetworkOption } from '../../../command-helpers' +import gql from 'graphql-tag' +import { IndexerThawRequest, printIndexerThawRequests } from '../../../thaw-requests' + +const HELP = ` +${chalk.bold('graph indexer provision list-thaw')} [options] + +${chalk.dim('Options:')} + + -h, --help Show usage information + -n, --network Filter provisions by their protocol network (mainnet, arbitrum-one, sepolia, arbitrum-sepolia) + -o, --output table|json|yaml Choose the output format: table (default), JSON, or YAML +` + +module.exports = { + name: 'list-thaw', + alias: [], + description: "List thaw requests for the indexer's provision", + run: async (toolbox: GluegunToolbox) => { + const { print, parameters } = toolbox + + const spinner = toolbox.print.spin('Processing inputs') + + const { h, help, o, output } = parameters.options + + const outputFormat = o || output || 'table' + + if (help || h) { + spinner.stopAndPersist({ symbol: '💁', text: HELP }) + return + } + + try { + const protocolNetwork = extractProtocolNetworkOption(parameters.options, true) + + if (!['json', 'yaml', 'table'].includes(outputFormat)) { + throw Error( + `Invalid output format "${outputFormat}" must be one of 'json', 'yaml' or 'table'`, + ) + } + + spinner.text = 'Getting thaw requests for the provision' + const config = loadValidatedConfig() + const client = await createIndexerManagementClient({ url: config.api }) + + const result = await client + .query( + gql` + query thawRequests($protocolNetwork: String!) { + thawRequests(protocolNetwork: $protocolNetwork) { + id + fulfilled + dataService + indexer + shares + thawingUntil + protocolNetwork + currentBlockTimestamp + } + } + `, + { + protocolNetwork, + }, + ) + .toPromise() + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + if (result.error) { + throw result.error + } + + const displayProperties: (keyof IndexerThawRequest)[] = [ + 'id', + 'fulfilled', + 'protocolNetwork', + 'shares', + 'thawingUntil', + ] + + if (result.data.thawRequests) { + spinner.succeed('Got thaw requests') + printIndexerThawRequests( + print, + outputFormat, + result.data.thawRequests, + displayProperties, + ) + + print.info('') + print.info( + `Latest block timestamp: ${new Date( + Number(result.data.thawRequests[0].currentBlockTimestamp) * 1000, + ).toLocaleString()}`, + ) + } else { + spinner.fail('Failed to get thaw requests') + } + } catch (error) { + spinner.fail(error.toString()) + process.exitCode = 1 + return + } + }, +} diff --git a/packages/indexer-cli/src/commands/indexer/provision/remove.ts b/packages/indexer-cli/src/commands/indexer/provision/remove.ts new file mode 100644 index 000000000..c585ef5aa --- /dev/null +++ b/packages/indexer-cli/src/commands/indexer/provision/remove.ts @@ -0,0 +1,116 @@ +import { GluegunToolbox } from 'gluegun' +import chalk from 'chalk' + +import { loadValidatedConfig } from '../../../config' +import { createIndexerManagementClient } from '../../../client' +import { extractProtocolNetworkOption } from '../../../command-helpers' +import gql from 'graphql-tag' +import { IndexerProvision, printIndexerProvisions } from '../../../provisions' +import { commify } from '@graphprotocol/common-ts' +import { formatGRT } from '@graphprotocol/common-ts' + +const HELP = ` +${chalk.bold('graph indexer provision remove')} [options] + +${chalk.dim('Options:')} + + -h, --help Show usage information + -n, --network Filter provisions by their protocol network (mainnet, arbitrum-one, sepolia, arbitrum-sepolia) + -o, --output table|json|yaml Choose the output format: table (default), JSON, or YAML +` + +module.exports = { + name: 'remove', + alias: [], + description: "Remove thawed stake from the indexer's provision", + run: async (toolbox: GluegunToolbox) => { + const { print, parameters } = toolbox + + const spinner = toolbox.print.spin('Processing inputs') + + const { h, help, o, output } = parameters.options + + const outputFormat = o || output || 'table' + + if (help || h) { + spinner.stopAndPersist({ symbol: '💁', text: HELP }) + return + } + + try { + const protocolNetwork = extractProtocolNetworkOption(parameters.options, true) + + if (!['json', 'yaml', 'table'].includes(outputFormat)) { + throw Error( + `Invalid output format "${outputFormat}" must be one of 'json', 'yaml' or 'table'`, + ) + } + + spinner.text = 'Removing thawed stake from the provision' + const config = loadValidatedConfig() + const client = await createIndexerManagementClient({ url: config.api }) + + const result = await client + .mutation( + gql` + mutation removeFromProvision($protocolNetwork: String!) { + removeFromProvision(protocolNetwork: $protocolNetwork) { + id + dataService + indexer + tokensProvisioned + tokensThawing + tokensRemoved + protocolNetwork + } + } + `, + { + protocolNetwork, + }, + ) + .toPromise() + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + if (result.error) { + throw result.error + } + + const displayProperties: (keyof IndexerProvision)[] = [ + 'dataService', + 'protocolNetwork', + 'tokensProvisioned', + 'tokensThawing', + ] + + if (result.data.removeFromProvision) { + if (result.data.removeFromProvision.tokensRemoved > 0) { + spinner.succeed('Thawed stake removed from the provision') + printIndexerProvisions( + print, + outputFormat, + result.data.removeFromProvision, + displayProperties, + ) + + print.info('') + print.info( + `Removed ${commify( + formatGRT(result.data.removeFromProvision.tokensRemoved), + )} GRT from the provision`, + ) + } else { + spinner.fail( + 'No thawed stake to remove from the provision. Run `graph indexer provision list-thaw` to see thawing details.', + ) + } + } else { + spinner.fail('Failed to remove thawed stake from the provision') + } + } catch (error) { + spinner.fail(error.toString()) + process.exitCode = 1 + return + } + }, +} diff --git a/packages/indexer-cli/src/commands/indexer/provision/thaw.ts b/packages/indexer-cli/src/commands/indexer/provision/thaw.ts new file mode 100644 index 000000000..2e4dda78a --- /dev/null +++ b/packages/indexer-cli/src/commands/indexer/provision/thaw.ts @@ -0,0 +1,109 @@ +import { GluegunToolbox } from 'gluegun' +import chalk from 'chalk' + +import { loadValidatedConfig } from '../../../config' +import { createIndexerManagementClient } from '../../../client' +import { extractProtocolNetworkOption } from '../../../command-helpers' +import gql from 'graphql-tag' +import { IndexerProvision, printIndexerProvisions } from '../../../provisions' + +const HELP = ` +${chalk.bold('graph indexer provision thaw')} [options] + +${chalk.dim('Options:')} + + -h, --help Show usage information + -n, --network Filter provisions by their protocol network (mainnet, arbitrum-one, sepolia, arbitrum-sepolia) + -o, --output table|json|yaml Choose the output format: table (default), JSON, or YAML +` + +module.exports = { + name: 'thaw', + alias: [], + description: "Thaw stake from the indexer's provision", + run: async (toolbox: GluegunToolbox) => { + const { print, parameters } = toolbox + + const spinner = toolbox.print.spin('Processing inputs') + + const { h, help, o, output } = parameters.options + + const outputFormat = o || output || 'table' + + if (help || h) { + spinner.stopAndPersist({ symbol: '💁', text: HELP }) + return + } + + const [amount] = parameters.array || [] + + try { + if (!amount) { + throw new Error('Must provide an amount to thaw from the provision') + } + + const protocolNetwork = extractProtocolNetworkOption(parameters.options, true) + + if (!['json', 'yaml', 'table'].includes(outputFormat)) { + throw Error( + `Invalid output format "${outputFormat}" must be one of 'json', 'yaml' or 'table'`, + ) + } + + spinner.text = 'Thawing stake from the provision' + const config = loadValidatedConfig() + const client = await createIndexerManagementClient({ url: config.api }) + + const result = await client + .mutation( + gql` + mutation thawFromProvision($protocolNetwork: String!, $amount: String!) { + thawFromProvision(protocolNetwork: $protocolNetwork, amount: $amount) { + id + dataService + indexer + tokensThawing + thawingPeriod + thawingUntil + protocolNetwork + } + } + `, + { + protocolNetwork, + amount: amount.toString(), + }, + ) + .toPromise() + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + if (result.error) { + throw result.error + } + + const displayProperties: (keyof IndexerProvision)[] = [ + 'dataService', + 'protocolNetwork', + 'tokensThawing', + 'thawingPeriod', + 'thawingUntil', + ] + + if (result.data.thawFromProvision) { + spinner.succeed('Stake thawed from the provision') + printIndexerProvisions( + print, + outputFormat, + result.data.thawFromProvision, + displayProperties, + ) + } else { + spinner.fail('Failed to thaw stake from the provision') + } + } catch (error) { + spinner.fail(error.toString()) + process.exitCode = 1 + return + } + }, +} diff --git a/packages/indexer-cli/src/commands/indexer/rules/set.ts b/packages/indexer-cli/src/commands/indexer/rules/set.ts index 09de0bbc0..596c5c6ed 100644 --- a/packages/indexer-cli/src/commands/indexer/rules/set.ts +++ b/packages/indexer-cli/src/commands/indexer/rules/set.ts @@ -102,10 +102,17 @@ module.exports = { const valid_commands = Object.keys(tmpRules).filter( c => c != 'parallelAllocations', ) - throw new Error( - `Indexing rule attribute '${error.message}' not supported, did you mean?\n` + - stringify(suggestCommands(error.message, valid_commands)).replace(/\n$/, ''), - ) + if (valid_commands.includes(error.message)) { + throw new Error( + `Indexing rule attribute '${error.message}' not supported, did you mean?\n` + + stringify(suggestCommands(error.message, valid_commands)).replace( + /\n$/, + '', + ), + ) + } else { + throw error + } } } catch (error) { print.error(error.toString()) diff --git a/packages/indexer-cli/src/commands/indexer/status.ts b/packages/indexer-cli/src/commands/indexer/status.ts index 79a9636fa..5c849ad40 100644 --- a/packages/indexer-cli/src/commands/indexer/status.ts +++ b/packages/indexer-cli/src/commands/indexer/status.ts @@ -25,10 +25,12 @@ ${chalk.dim('Options:')} ` interface Endpoint { + name: string url: string | null healthy: boolean protocolNetwork: string tests: any[] + isLegacy: boolean } interface Endpoints { @@ -80,6 +82,7 @@ module.exports = { latitude longitude } + isLegacy } indexerDeployments { @@ -118,6 +121,7 @@ module.exports = { indexerEndpoints(protocolNetwork: $protocolNetwork) { service { + name url healthy protocolNetwork @@ -126,8 +130,10 @@ module.exports = { error possibleActions } + isLegacy } status { + name url healthy protocolNetwork @@ -136,6 +142,7 @@ module.exports = { error possibleActions } + isLegacy } } @@ -181,12 +188,16 @@ module.exports = { } if (result.data.indexerRegistration) { - data.registration = pickFields(result.data.indexerRegistration, []) - if (data.registration.location) { - data.registration.location = `${data.registration.location.latitude},${data.registration.location.longitude}` - } else { - data.registration.location = 'No location specified' - } + data.registration = result.data.indexerRegistration.map((registration: any) => { + return pickFields(registration, []) + }) + data.registration.forEach((registration: any) => { + if (registration.location) { + registration.location = `${registration.location.latitude},${registration.location.longitude}` + } else { + registration.location = 'No location specified' + } + }) } else { data.registration = { error: @@ -199,18 +210,20 @@ module.exports = { const { service, status } = endpoints return [ { - name: 'service', + name: service.name, url: service.url, tests: service.tests, protocolNetwork: resolveChainAlias(service.protocolNetwork), status: formatStatus(outputFormat, service.healthy), + isLegacy: service.isLegacy, }, { - name: 'status', + name: status.name, url: status.url, tests: status.tests, protocolNetwork: resolveChainAlias(status.protocolNetwork), status: formatStatus(outputFormat, status.healthy), + isLegacy: status.isLegacy, }, ] }) @@ -249,7 +262,21 @@ module.exports = { if (outputFormat === 'table') { print.info(chalk.cyan('Registration')) - print.info(formatData(data.registration, outputFormat)) + print.info( + formatData( + data.registration.map((registration: any) => + pickFields(registration, [ + 'url', + 'address', + 'protocolNetwork', + 'registered', + 'isLegacy', + 'location', + ]), + ), + outputFormat, + ), + ) print.info(chalk.cyan('\nEndpoints')) if (data.endpoints.error) { print.error(formatData([data.endpoints], outputFormat)) @@ -257,7 +284,13 @@ module.exports = { print.info( formatData( data.endpoints.map((endpoint: any) => - pickFields(endpoint, ['name', 'protocolNetwork', 'url', 'status']), + pickFields(endpoint, [ + 'name', + 'protocolNetwork', + 'url', + 'status', + 'isLegacy', + ]), ), outputFormat, ), diff --git a/packages/indexer-cli/src/provisions.ts b/packages/indexer-cli/src/provisions.ts new file mode 100644 index 000000000..175024e4c --- /dev/null +++ b/packages/indexer-cli/src/provisions.ts @@ -0,0 +1,113 @@ +import { formatGRT, commify } from '@graphprotocol/common-ts' +import yaml from 'yaml' +import { GluegunPrint } from 'gluegun' +import { table, getBorderCharacters } from 'table' +import { OutputFormat, parseOutputFormat, pickFields } from './command-helpers' +import { resolveChainAlias } from '@graphprotocol/indexer-common' +import { BigNumberish } from 'ethers' + +function formatPPM(x: BigNumberish): string { + return ((Number(x) / 1_000_000) * 100).toString() +} + +export interface IndexerProvision { + id: string + dataService: string + indexer: string + tokensProvisioned: bigint + tokensAllocated: bigint + tokensThawing: bigint + maxVerifierCut: bigint + thawingPeriod: bigint + + protocolNetwork: string + + // This is not really a provision property, but useful to avoid creating new types + thawingUntil: string +} + +const PROVISION_FORMATTERS: Record string | null> = + { + id: nullPassThrough(x => x), + dataService: nullPassThrough(x => x), + indexer: nullPassThrough(x => x), + tokensProvisioned: x => commify(formatGRT(x)), + tokensAllocated: x => commify(formatGRT(x)), + tokensThawing: x => commify(formatGRT(x)), + maxVerifierCut: x => commify(formatPPM(x)), + thawingPeriod: x => x, + thawingUntil: x => new Date(Number(x) * 1000).toLocaleString(), + protocolNetwork: resolveChainAlias, + } + +/** + * Formats an indexer provision for display in the console. + */ +export const formatIndexerProvision = ( + provision: Partial, +): Partial => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const obj = {} as any + for (const [key, value] of Object.entries(provision)) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + obj[key] = (PROVISION_FORMATTERS as any)[key](value) + } + + return obj as Partial +} + +export const printIndexerProvisions = ( + print: GluegunPrint, + outputFormat: OutputFormat, + provisionOrProvisions: Partial | Partial[] | null, + keys: (keyof IndexerProvision)[], +): void => { + parseOutputFormat(print, outputFormat) + if (Array.isArray(provisionOrProvisions)) { + const provisions = provisionOrProvisions.map(provision => + formatIndexerProvision(pickFields(provision, keys)), + ) + print.info(displayIndexerProvisions(outputFormat, provisions)) + } else if (provisionOrProvisions) { + const provision = formatIndexerProvision(pickFields(provisionOrProvisions, keys)) + print.info(displayIndexerProvision(outputFormat, provision)) + } else { + print.error(`No provisions found`) + } +} + +export const displayIndexerProvisions = ( + outputFormat: OutputFormat, + provisions: Partial[], +): string => + outputFormat === OutputFormat.Json + ? JSON.stringify(provisions, null, 2) + : outputFormat === OutputFormat.Yaml + ? yaml.stringify(provisions).trim() + : provisions.length === 0 + ? 'No provisions found' + : table( + [ + Object.keys(provisions[0]), + ...provisions.map(provision => Object.values(provision)), + ], + { + border: getBorderCharacters('norc'), + }, + ).trim() + +export const displayIndexerProvision = ( + outputFormat: OutputFormat, + provision: Partial, +): string => + outputFormat === OutputFormat.Json + ? JSON.stringify(provision, null, 2) + : outputFormat === OutputFormat.Yaml + ? yaml.stringify(provision).trim() + : table([Object.keys(provision), Object.values(provision)], { + border: getBorderCharacters('norc'), + }).trim() + +function nullPassThrough(fn: (x: T) => U): (x: T | null) => U | null { + return (x: T | null) => (x === null ? null : fn(x)) +} diff --git a/packages/indexer-cli/src/rules.ts b/packages/indexer-cli/src/rules.ts index e50027849..e37fc9da3 100644 --- a/packages/indexer-cli/src/rules.ts +++ b/packages/indexer-cli/src/rules.ts @@ -1,4 +1,9 @@ -import { SubgraphDeploymentID, parseGRT, formatGRT } from '@graphprotocol/common-ts' +import { + SubgraphDeploymentID, + parseGRT, + formatGRT, + commify, +} from '@graphprotocol/common-ts' import { nullPassThrough, parseBoolean, @@ -12,7 +17,7 @@ import { import gql from 'graphql-tag' import yaml from 'yaml' import { table, getBorderCharacters } from 'table' -import { BigNumber, utils } from 'ethers' + import { OutputFormat, pickFields } from './command-helpers' import chalk from 'chalk' @@ -47,15 +52,15 @@ const INDEXING_RULE_FORMATTERS: Record< //deployment: (d: SubgraphDeploymentIDIsh) => (typeof d === 'string' ? d : d.ipfsHash), identifier: x => x, identifierType: x => x, - allocationAmount: nullPassThrough(x => utils.commify(formatGRT(x))), + allocationAmount: nullPassThrough(x => commify(formatGRT(x))), allocationLifetime: nullPassThrough((x: number) => x.toString()), autoRenewal: x => x, parallelAllocations: nullPassThrough((x: number) => x.toString()), - maxSignal: nullPassThrough(x => utils.commify(formatGRT(x))), - minSignal: nullPassThrough(x => utils.commify(formatGRT(x))), - minStake: nullPassThrough(x => utils.commify(formatGRT(x))), + maxSignal: nullPassThrough(x => commify(formatGRT(x))), + minSignal: nullPassThrough(x => commify(formatGRT(x))), + minStake: nullPassThrough(x => commify(formatGRT(x))), maxAllocationPercentage: nullPassThrough((x: number) => x.toPrecision(2)), - minAverageQueryFees: nullPassThrough(x => utils.commify(formatGRT(x))), + minAverageQueryFees: nullPassThrough(x => commify(formatGRT(x))), decisionBasis: x => x, custom: nullPassThrough(JSON.stringify), requireSupported: x => x, @@ -71,15 +76,15 @@ const INDEXING_RULE_CONVERTERS_FROM_GRAPHQL: Record< id: x => x, identifier: x => x, identifierType: x => x, - allocationAmount: nullPassThrough((x: string) => BigNumber.from(x)), + allocationAmount: nullPassThrough((x: string) => BigInt(x)), allocationLifetime: nullPassThrough((x: string) => parseInt(x)), autoRenewal: x => x, parallelAllocations: nullPassThrough((x: string) => parseInt(x)), - minSignal: nullPassThrough((x: string) => BigNumber.from(x)), - maxSignal: nullPassThrough((x: string) => BigNumber.from(x)), - minStake: nullPassThrough((x: string) => BigNumber.from(x)), + minSignal: nullPassThrough((x: string) => BigInt(x)), + maxSignal: nullPassThrough((x: string) => BigInt(x)), + minStake: nullPassThrough((x: string) => BigInt(x)), maxAllocationPercentage: nullPassThrough((x: string) => parseFloat(x)), - minAverageQueryFees: nullPassThrough((x: string) => BigNumber.from(x)), + minAverageQueryFees: nullPassThrough((x: string) => BigInt(x)), decisionBasis: x => x, custom: nullPassThrough(JSON.stringify), requireSupported: x => x, @@ -95,15 +100,15 @@ const INDEXING_RULE_CONVERTERS_TO_GRAPHQL: Record< id: x => x, identifier: x => x, identifierType: x => x, - allocationAmount: nullPassThrough((x: BigNumber) => x.toString()), + allocationAmount: nullPassThrough((x: bigint) => x.toString()), allocationLifetime: nullPassThrough((x: number) => x), autoRenewal: x => x, parallelAllocations: nullPassThrough((x: number) => x), - minSignal: nullPassThrough((x: BigNumber) => x.toString()), - maxSignal: nullPassThrough((x: BigNumber) => x.toString()), - minStake: nullPassThrough((x: BigNumber) => x.toString()), + minSignal: nullPassThrough((x: bigint) => x.toString()), + maxSignal: nullPassThrough((x: bigint) => x.toString()), + minStake: nullPassThrough((x: bigint) => x.toString()), maxAllocationPercentage: nullPassThrough((x: number) => x), - minAverageQueryFees: nullPassThrough((x: BigNumber) => x.toString()), + minAverageQueryFees: nullPassThrough((x: bigint) => x.toString()), decisionBasis: x => x, custom: nullPassThrough(JSON.stringify), requireSupported: x => x, diff --git a/packages/indexer-cli/src/run.ts b/packages/indexer-cli/src/run.ts new file mode 100644 index 000000000..b59c5b834 --- /dev/null +++ b/packages/indexer-cli/src/run.ts @@ -0,0 +1,2 @@ +// eslint-disable-next-line @typescript-eslint/no-var-requires +require('./cli').run(process.argv) diff --git a/packages/indexer-cli/src/thaw-requests.ts b/packages/indexer-cli/src/thaw-requests.ts new file mode 100644 index 000000000..47c7465b0 --- /dev/null +++ b/packages/indexer-cli/src/thaw-requests.ts @@ -0,0 +1,106 @@ +import { formatGRT, commify } from '@graphprotocol/common-ts' +import yaml from 'yaml' +import { GluegunPrint } from 'gluegun' +import { table, getBorderCharacters } from 'table' +import { OutputFormat, parseOutputFormat, pickFields } from './command-helpers' +import { resolveChainAlias } from '@graphprotocol/indexer-common' + +export interface IndexerThawRequest { + id: string + fulfilled: string + dataService: string + indexer: string + shares: string + thawingUntil: string + protocolNetwork: string +} + +const THAW_REQUEST_FORMATTERS: Record< + keyof IndexerThawRequest, + (x: never) => string | null +> = { + id: nullPassThrough(x => x), + fulfilled: nullPassThrough(x => x), + dataService: nullPassThrough(x => x), + indexer: nullPassThrough(x => x), + shares: x => commify(formatGRT(x)), + thawingUntil: x => new Date(Number(x) * 1000).toLocaleString(), + protocolNetwork: resolveChainAlias, +} + +/** + * Formats an indexer thaw request for display in the console. + */ +export const formatIndexerThawRequest = ( + thawRequest: Partial, +): Partial => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const obj = {} as any + for (const [key, value] of Object.entries(thawRequest)) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + obj[key] = (THAW_REQUEST_FORMATTERS as any)[key](value) + } + + return obj as Partial +} + +export const printIndexerThawRequests = ( + print: GluegunPrint, + outputFormat: OutputFormat, + thawRequestOrThawRequests: + | Partial + | Partial[] + | null, + keys: (keyof IndexerThawRequest)[], +): void => { + parseOutputFormat(print, outputFormat) + if (Array.isArray(thawRequestOrThawRequests)) { + const thawRequests = thawRequestOrThawRequests.map(thawRequest => + formatIndexerThawRequest(pickFields(thawRequest, keys)), + ) + print.info(displayIndexerThawRequests(outputFormat, thawRequests)) + } else if (thawRequestOrThawRequests) { + const thawRequest = formatIndexerThawRequest( + pickFields(thawRequestOrThawRequests, keys), + ) + print.info(displayIndexerThawRequest(outputFormat, thawRequest)) + } else { + print.error(`No thaw requests found`) + } +} + +export const displayIndexerThawRequests = ( + outputFormat: OutputFormat, + thawRequests: Partial[], +): string => + outputFormat === OutputFormat.Json + ? JSON.stringify(thawRequests, null, 2) + : outputFormat === OutputFormat.Yaml + ? yaml.stringify(thawRequests).trim() + : thawRequests.length === 0 + ? 'No thaw requests found' + : table( + [ + Object.keys(thawRequests[0]), + ...thawRequests.map(thawRequest => Object.values(thawRequest)), + ], + { + border: getBorderCharacters('norc'), + }, + ).trim() + +export const displayIndexerThawRequest = ( + outputFormat: OutputFormat, + thawRequest: Partial, +): string => + outputFormat === OutputFormat.Json + ? JSON.stringify(thawRequest, null, 2) + : outputFormat === OutputFormat.Yaml + ? yaml.stringify(thawRequest).trim() + : table([Object.keys(thawRequest), Object.values(thawRequest)], { + border: getBorderCharacters('norc'), + }).trim() + +function nullPassThrough(fn: (x: T) => U): (x: T | null) => U | null { + return (x: T | null) => (x === null ? null : fn(x)) +} diff --git a/packages/indexer-common/jest.config.js b/packages/indexer-common/jest.config.js index bca010358..26ebe5fde 100644 --- a/packages/indexer-common/jest.config.js +++ b/packages/indexer-common/jest.config.js @@ -6,7 +6,7 @@ const bail = (s) => { process.env.NODE_NO_WARNINGS = '1' module.exports = { - collectCoverage: true, + collectCoverage: false, preset: 'ts-jest', forceExit: true, testEnvironment: 'node', diff --git a/packages/indexer-common/package.json b/packages/indexer-common/package.json index 07e103743..97ce6969b 100644 --- a/packages/indexer-common/package.json +++ b/packages/indexer-common/package.json @@ -23,8 +23,14 @@ }, "dependencies": { "@pinax/graph-networks-registry": "0.6.7", - "@graphprotocol/common-ts": "2.0.11", - "@semiotic-labs/tap-contracts-bindings": "^1.2.1", + "@bufbuild/protobuf": "2.2.3", + "@graphprotocol/common-ts": "3.0.1", + "@graphprotocol/dips-proto": "0.3.0", + "@graphprotocol/horizon": "0.4.1", + "@graphprotocol/subgraph-service": "0.4.1", + "@graphprotocol/toolshed": "0.6.5", + "@grpc/grpc-js": "^1.12.6", + "@semiotic-labs/tap-contracts-bindings": "2.0.0", "@thi.ng/heaps": "1.2.38", "@types/lodash.clonedeep": "^4.5.7", "@types/lodash.intersection": "^4.4.7", @@ -35,7 +41,7 @@ "axios": "1.6.2", "body-parser": "1.20.2", "cors": "2.8.5", - "ethers": "5.7.0", + "ethers": "6.13.7", "evt": "1.10.1", "express": "4.18.2", "fastify": "3.25.0", @@ -82,9 +88,8 @@ "typescript": "5.2.2" }, "resolutions": { - "ethers": "5.7.0", + "ethers": "6.13.7", "sequelize": "6.33.0", - "@ethersproject/bignumber": "5.7.0", "@urql/exchange-execute/@urql/core": "3.1.0" }, "babel": { diff --git a/packages/indexer-common/src/__tests__/ipfs.test.ts b/packages/indexer-common/src/__tests__/ipfs.test.ts index 8e94fe8cc..7432a7cb6 100644 --- a/packages/indexer-common/src/__tests__/ipfs.test.ts +++ b/packages/indexer-common/src/__tests__/ipfs.test.ts @@ -2,15 +2,15 @@ import { createLogger, SubgraphDeploymentID } from '@graphprotocol/common-ts' import { SubgraphDependencies, SubgraphManifestResolver } from '../graph-node' import express, { Request, Response } from 'express' import { AddressInfo } from 'net' -import { utils } from 'ethers' +import { keccak256, toUtf8Bytes } from 'ethers' const EXAMPLE_VALID_IPFS_HASH = 'Qmd9nZKCH8UZU1pBzk7G8ECJr3jX3a2vAf3vowuTwFvrQg' const EXAMPLE_NON_MANIFEST_VALID_IPFS_HASH = 'QmddQDkcHHM7mGvYrrnoGnQ1q9GdHQfbTvj2mfbyz2Q49K' function mockManifestHash(input: string): string { - const utf8Bytes = utils.toUtf8Bytes(input) - const hash = utils.keccak256(utf8Bytes) // Generate a keccak256 hash of the input + const utf8Bytes = toUtf8Bytes(input) + const hash = keccak256(utf8Bytes) // Generate a keccak256 hash of the input return new SubgraphDeploymentID(hash).ipfsHash } diff --git a/packages/indexer-common/src/__tests__/network-specification-files/invalid-payments-destination.yml b/packages/indexer-common/src/__tests__/network-specification-files/invalid-payments-destination.yml new file mode 100644 index 000000000..67d184698 --- /dev/null +++ b/packages/indexer-common/src/__tests__/network-specification-files/invalid-payments-destination.yml @@ -0,0 +1,36 @@ +networkIdentifier: mainnet +gateway: + url: http://gateway +indexerOptions: + address: "0x4e8a4C63Df58bf59Fef513aB67a76319a9faf448" + paymentsDestination: "0xclearlynotanaddress" + mnemonic: word ivory whale diesel slab pelican voyage oxygen chat find tobacco sport + url: http://indexer + geoCoordinates: [25.1, -71.2] + restakeRewards: true + rebateClaimThreshold: 400 + rebateClaimBatchThreshold: 5000 + rebateClaimMaxBatchSize: 10 + poiDisputeMonitoring: false + poiDisputableEpochs: 5 + defaultAllocationAmount: 0.05 + voucherRedemptionThreshold: 2 + voucherRedemptionBatchThreshold: 2000 + voucherRedemptionMaxBatchSize: 15 + allocationManagementMode: "auto" + autoAllocationMinBatchSize: 20 + maxProvisionInitialSize: 100000 +transactionMonitoring: + gasIncreaseTimeout: 10 + gasIncreaseFactor: 10 + baseFeePerGasMax: 10 + maxTransactionAttempts: 10 +subgraphs: + networkSubgraph: + deployment: QmPK1s3pNYLi9ERiq3BDxKa4XosgWwFRQUydHUtz4YgpqB + epochSubgraph: + url: http://subgraph + tapSubgraph: + url: http://subgraph +networkProvider: + url: http://provider diff --git a/packages/indexer-common/src/__tests__/network-specification-files/invalid-provision-size.yml b/packages/indexer-common/src/__tests__/network-specification-files/invalid-provision-size.yml new file mode 100644 index 000000000..75b6cb2c3 --- /dev/null +++ b/packages/indexer-common/src/__tests__/network-specification-files/invalid-provision-size.yml @@ -0,0 +1,35 @@ +networkIdentifier: mainnet +gateway: + url: http://gateway +indexerOptions: + address: "0x4e8a4C63Df58bf59Fef513aB67a76319a9faf448" + mnemonic: word ivory whale diesel slab pelican voyage oxygen chat find tobacco sport + url: http://indexer + geoCoordinates: [25.1, -71.2] + restakeRewards: true + rebateClaimThreshold: 400 + rebateClaimBatchThreshold: 5000 + rebateClaimMaxBatchSize: 10 + poiDisputeMonitoring: false + poiDisputableEpochs: 5 + defaultAllocationAmount: 0.05 + voucherRedemptionThreshold: 2 + voucherRedemptionBatchThreshold: 2000 + voucherRedemptionMaxBatchSize: 15 + allocationManagementMode: "auto" + autoAllocationMinBatchSize: 20 + maxProvisionInitialSize: 99999 +transactionMonitoring: + gasIncreaseTimeout: 10 + gasIncreaseFactor: 10 + baseFeePerGasMax: 10 + maxTransactionAttempts: 10 +subgraphs: + networkSubgraph: + deployment: QmPK1s3pNYLi9ERiq3BDxKa4XosgWwFRQUydHUtz4YgpqB + epochSubgraph: + url: http://subgraph + tapSubgraph: + url: http://subgraph +networkProvider: + url: http://provider diff --git a/packages/indexer-common/src/__tests__/network-specification-files/valid-missing.yml b/packages/indexer-common/src/__tests__/network-specification-files/valid-missing.yml index 76c051f50..944a88f0a 100644 --- a/packages/indexer-common/src/__tests__/network-specification-files/valid-missing.yml +++ b/packages/indexer-common/src/__tests__/network-specification-files/valid-missing.yml @@ -19,6 +19,7 @@ indexerOptions: voucherRedemptionMaxBatchSize: 15 allocationManagementMode: "auto" autoAllocationMinBatchSize: 20 + maxProvisionInitialSize: 0 subgraphs: networkSubgraph: deployment: QmPK1s3pNYLi9ERiq3BDxKa4XosgWwFRQUydHUtz4YgpqB diff --git a/packages/indexer-common/src/__tests__/network-specification-files/valid.yml b/packages/indexer-common/src/__tests__/network-specification-files/valid.yml index 51538b31a..e3f802e1c 100644 --- a/packages/indexer-common/src/__tests__/network-specification-files/valid.yml +++ b/packages/indexer-common/src/__tests__/network-specification-files/valid.yml @@ -18,6 +18,7 @@ indexerOptions: voucherRedemptionMaxBatchSize: 15 allocationManagementMode: "auto" autoAllocationMinBatchSize: 20 + maxProvisionInitialSize: 100000 transactionMonitoring: gasIncreaseTimeout: 10 gasIncreaseFactor: 10 diff --git a/packages/indexer-common/src/__tests__/network-specification.test.ts b/packages/indexer-common/src/__tests__/network-specification.test.ts index 6c8afefe2..22464e33c 100644 --- a/packages/indexer-common/src/__tests__/network-specification.test.ts +++ b/packages/indexer-common/src/__tests__/network-specification.test.ts @@ -70,6 +70,16 @@ describe('Failed deserialization', () => { path: ['subgraphs', 'maxBlockDistance'], message: 'Number must be greater than or equal to 0', }, + { + file: 'invalid-provision-size.yml', + path: ['indexerOptions', 'maxProvisionInitialSize'], + message: 'Must be greater or equal than 100000 GRT', + }, + { + file: 'invalid-payments-destination.yml', + path: ['indexerOptions', 'paymentsDestination'], + message: 'Invalid contract address', + }, ] test.each(failedTests)( diff --git a/packages/indexer-common/src/actions.ts b/packages/indexer-common/src/actions.ts index afa265d02..68769dc9b 100644 --- a/packages/indexer-common/src/actions.ts +++ b/packages/indexer-common/src/actions.ts @@ -11,6 +11,8 @@ export interface ActionParamsInput { allocationID?: string amount?: string poi?: string + publicPOI?: string + poiBlockNumber?: number force?: boolean } @@ -20,6 +22,7 @@ export interface ActionItem { reason: string status?: ActionStatus protocolNetwork: string + isLegacy?: boolean } export interface ActionUpdateInput { @@ -27,11 +30,14 @@ export interface ActionUpdateInput { allocationID?: string amount?: string poi?: string + publicPOI?: string + poiBlockNumber?: number force?: boolean type?: ActionType status?: ActionStatus reason?: string protocolNetwork?: string + isLegacy?: boolean } export interface ActionInput { @@ -40,12 +46,15 @@ export interface ActionInput { allocationID?: string amount?: string poi?: string + publicPOI?: string + poiBlockNumber?: number force?: boolean source: string reason: string status: ActionStatus priority: number | undefined protocolNetwork: string + isLegacy: boolean } export const isValidActionInput = ( @@ -63,12 +72,28 @@ export const isValidActionInput = ( case ActionType.UNALLOCATE: hasActionParams = 'deploymentID' in variableToCheck && 'allocationID' in variableToCheck + + if (!variableToCheck.isLegacy && variableToCheck.poi !== undefined) { + hasActionParams = + hasActionParams && + 'poi' in variableToCheck && + 'publicPOI' in variableToCheck && + 'poiBlockNumber' in variableToCheck + } break case ActionType.REALLOCATE: hasActionParams = 'deploymentID' in variableToCheck && 'allocationID' in variableToCheck && 'amount' in variableToCheck + + if (!variableToCheck.isLegacy && variableToCheck.poi !== undefined) { + hasActionParams = + hasActionParams && + 'poi' in variableToCheck && + 'publicPOI' in variableToCheck && + 'poiBlockNumber' in variableToCheck + } } return ( hasActionParams && @@ -161,6 +186,7 @@ export interface ActionFilter { reason?: string updatedAt?: WhereOperators protocolNetwork?: string + isLegacy?: boolean } export const actionFilterToWhereOptions = (filter: ActionFilter): WhereOptions => { @@ -184,6 +210,8 @@ export interface ActionResult { allocationID: string | null amount: string | null poi: string | null + publicPOI: string | null + poiBlockNumber: number | null force: boolean | null source: string reason: string @@ -192,6 +220,7 @@ export interface ActionResult { failureReason: string | null transaction: string | null protocolNetwork: string + isLegacy: boolean } export enum ActionType { @@ -219,6 +248,8 @@ export enum ActionParams { TRANSACTION = 'transaction', AMOUNT = 'amount', POI = 'poi', + PUBLIC_POI = 'publicPOI', + POI_BLOCK_NUMBER = 'poiBlockNumber', FORCE = 'force', SOURCE = 'source', REASON = 'reason', @@ -226,4 +257,5 @@ export enum ActionParams { CREATED_AT = 'createdAt', UPDATED_AT = 'updatedAt', PROTOCOL_NETWORK = 'protocolNetwork', + IS_LEGACY = 'isLegacy', } diff --git a/packages/indexer-common/src/allocations/__tests__/tap-pagination.test.ts b/packages/indexer-common/src/allocations/__tests__/tap-pagination.test.ts index cbddb3fc5..ea2f387f1 100644 --- a/packages/indexer-common/src/allocations/__tests__/tap-pagination.test.ts +++ b/packages/indexer-common/src/allocations/__tests__/tap-pagination.test.ts @@ -10,10 +10,10 @@ import { TapTransaction, TransactionManager, } from '@graphprotocol/indexer-common' -import { NetworkContracts as TapContracts } from '@semiotic-labs/tap-contracts-bindings' import { NetworkSpecification } from 'indexer-common/src/network-specification' import { createMockAllocation } from '../../indexer-management/__tests__/helpers.test' -import { getContractAddress } from 'ethers/lib/utils' +import { getCreateAddress } from 'ethers' +import { NetworkContracts as TapContracts } from '@semiotic-labs/tap-contracts-bindings' const timeout = 30_000 @@ -29,7 +29,7 @@ for (let i = 0; i < 2999; i++) { const mockAllocation = createMockAllocation() allocations.push({ ...mockAllocation, - id: getContractAddress({ from, nonce: i }) as Address, + id: getCreateAddress({ from, nonce: i }) as Address, }) } @@ -191,7 +191,7 @@ describe.skip('TAP Pagination', () => { const mockAllocation = createMockAllocation() allocations.push({ ...mockAllocation, - id: getContractAddress({ from, nonce: 3000 }) as Address, + id: getCreateAddress({ from, nonce: 3000 }) as Address, }) { const allocations = await tapCollector['getAllocationsfromAllocationIds']([]) diff --git a/packages/indexer-common/src/allocations/__tests__/tap.test.ts b/packages/indexer-common/src/allocations/__tests__/tap.test.ts index d85e50c8f..16ded8f55 100644 --- a/packages/indexer-common/src/allocations/__tests__/tap.test.ts +++ b/packages/indexer-common/src/allocations/__tests__/tap.test.ts @@ -7,6 +7,7 @@ import { TapSubgraphResponse, TapCollector, Allocation, + defineIndexerManagementModels, } from '@graphprotocol/indexer-common' import { Address, @@ -19,7 +20,7 @@ import { } from '@graphprotocol/common-ts' import { testNetworkSpecification } from '../../indexer-management/__tests__/util' import { Op, Sequelize } from 'sequelize' -import { utils } from 'ethers' +import { hexlify, verifyTypedData } from 'ethers' // Make global Jest variables available // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -43,6 +44,7 @@ const setup = async () => { // Clearing the registry prevents duplicate metric registration in the default registry. metrics.registry.clear() sequelize = await connectDatabase(__DATABASE__) + const models = defineIndexerManagementModels(sequelize) queryFeeModels = defineQueryFeeModels(sequelize) sequelize = await sequelize.sync({ force: true }) @@ -57,6 +59,7 @@ const setup = async () => { const network = await Network.create( logger, testNetworkSpecification, + models, queryFeeModels, graphNode, metrics, @@ -482,7 +485,7 @@ describe('TAP', () => { const [first] = await queryFeeModels.receiptAggregateVouchers.findAll() const signedRav = first.getSignedRAV() - const signerAddress = utils.verifyTypedData( + const signerAddress = verifyTypedData( domain, { ReceiptAggregateVoucher: [ @@ -492,7 +495,7 @@ describe('TAP', () => { ], }, signedRav.rav, - signedRav.signature, + hexlify(signedRav.signature), ) expect(signerAddress).toEqual('0x886574712d0ca20C36FD090A594Df7eCa17cd38e') diff --git a/packages/indexer-common/src/allocations/__tests__/validate-queries.test.ts b/packages/indexer-common/src/allocations/__tests__/validate-queries.test.ts index 0eaf46722..0ef0b3082 100644 --- a/packages/indexer-common/src/allocations/__tests__/validate-queries.test.ts +++ b/packages/indexer-common/src/allocations/__tests__/validate-queries.test.ts @@ -1,4 +1,5 @@ import { + defineIndexerManagementModels, defineQueryFeeModels, GraphNode, Network, @@ -36,6 +37,7 @@ const setup = async () => { // Clearing the registry prevents duplicate metric registration in the default registry. metrics.registry.clear() sequelize = await connectDatabase(__DATABASE__) + const models = defineIndexerManagementModels(sequelize) queryFeeModels = defineQueryFeeModels(sequelize) sequelize = await sequelize.sync({ force: true }) @@ -50,6 +52,7 @@ const setup = async () => { const network = await Network.create( logger, testNetworkSpecification, + models, queryFeeModels, graphNode, metrics, diff --git a/packages/indexer-common/src/allocations/escrow-accounts.ts b/packages/indexer-common/src/allocations/escrow-accounts.ts index 1d126fd94..45402171c 100644 --- a/packages/indexer-common/src/allocations/escrow-accounts.ts +++ b/packages/indexer-common/src/allocations/escrow-accounts.ts @@ -13,6 +13,14 @@ export type EscrowAccountResponse = { }[] } +export type EscrowSenderResponse = { + signer: { + sender: { + id: string + } + } +} + export class EscrowAccounts { constructor(private sendersBalances: Map) {} @@ -65,3 +73,26 @@ export const getEscrowAccounts = async ( } return EscrowAccounts.fromResponse(result.data) } + +export const getEscrowSenderForSigner = async ( + tapSubgraph: SubgraphClient, + signer: Address, +): Promise
=> { + const signerLower = signer.toLowerCase() + const result = await tapSubgraph.query( + gql` + query EscrowAccountQuery($signer: ID!) { + signer(id: $signer) { + sender { + id + } + } + } + `, + { signer: signerLower }, + ) + if (!result.data) { + throw `There was an error while querying Tap Subgraph. Errors: ${result.error}` + } + return toAddress(result.data.signer.sender.id) +} diff --git a/packages/indexer-common/src/allocations/graph-tally-collector.ts b/packages/indexer-common/src/allocations/graph-tally-collector.ts new file mode 100644 index 000000000..1108b10a3 --- /dev/null +++ b/packages/indexer-common/src/allocations/graph-tally-collector.ts @@ -0,0 +1,791 @@ +import { Counter, Gauge, Histogram } from 'prom-client' +import { + Logger, + toAddress, + formatGRT, + Address, + Metrics, + Eventual, +} from '@graphprotocol/common-ts' +import { + Allocation, + indexerError, + IndexerErrorCode, + QueryFeeModels, + ensureAllocationSummary, + TransactionManager, + specification as spec, + SignedRAVv2, + parseGraphQLAllocation, + sequentialTimerMap, + ReceiptAggregateVoucherV2, +} from '..' +import pReduce from 'p-reduce' +import { SubgraphClient, QueryResult } from '../subgraph-client' +import gql from 'graphql-tag' +import { getEscrowAccounts } from './horizon-escrow-accounts' +import { + GraphHorizonContracts, + SubgraphServiceContracts, +} from '@graphprotocol/toolshed/deployments' +import { encodeCollectQueryFeesData, PaymentTypes } from '@graphprotocol/toolshed' +import { zeroPadValue, dataSlice } from 'ethers' + +// every 15 minutes +const RAV_CHECK_INTERVAL_MS = 900_000 + +// 1000 here was leading to http 413 request entity too large +const PAGE_SIZE = 200 + +interface RavMetrics { + ravRedeemsSuccess: Counter + ravRedeemsInvalid: Counter + ravRedeemsFailed: Counter + ravsRedeemDuration: Histogram + ravCollectedFees: Gauge +} + +interface TapCollectorOptions { + logger: Logger + metrics: Metrics + transactionManager: TransactionManager + contracts: GraphHorizonContracts & SubgraphServiceContracts + allocations: Eventual + models: QueryFeeModels + networkSpecification: spec.NetworkSpecification + networkSubgraph: SubgraphClient +} + +interface ValidRavs { + belowThreshold: RavWithAllocation[] + eligible: RavWithAllocation[] +} + +export interface RavWithAllocation { + rav: SignedRAVv2 + allocation: Allocation + payer: string +} + +export interface SubgraphResponse { + transactions: GraphTallyTransaction[] + _meta: GraphTallyMeta +} + +interface GraphTallyMeta { + block: { + timestamp: number + hash: string + } +} + +export interface GraphTallyTransaction { + id: string + allocationId: string + timestamp: number + payer: { + id: string + } +} + +export interface AllocationsResponse { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + allocations: any[] + meta: { + block: { + hash: string + } + } +} + +export class GraphTallyCollector { + declare logger: Logger + declare metrics: RavMetrics + declare models: QueryFeeModels + declare transactionManager: TransactionManager + declare contracts: GraphHorizonContracts & SubgraphServiceContracts + declare allocations: Eventual + declare ravRedemptionThreshold: bigint + declare protocolNetwork: string + declare networkSubgraph: SubgraphClient + declare finalityTime: number + declare indexerAddress: Address + + // eslint-disable-next-line @typescript-eslint/no-empty-function -- Private constructor to prevent direct instantiation + private constructor() {} + + public static create({ + logger, + metrics, + transactionManager, + models, + contracts, + allocations, + networkSpecification, + networkSubgraph, + }: TapCollectorOptions): GraphTallyCollector { + const collector = new GraphTallyCollector() + collector.logger = logger.child({ component: 'GraphTallyCollector' }) + collector.metrics = registerReceiptMetrics( + metrics, + networkSpecification.networkIdentifier, + ) + collector.transactionManager = transactionManager + collector.models = models + collector.contracts = contracts + collector.allocations = allocations + collector.protocolNetwork = networkSpecification.networkIdentifier + collector.networkSubgraph = networkSubgraph + + const { voucherRedemptionThreshold, finalityTime, address } = + networkSpecification.indexerOptions + collector.ravRedemptionThreshold = voucherRedemptionThreshold + collector.finalityTime = finalityTime + collector.indexerAddress = address + + collector.logger.info(`RAV v2 processing is initiated`) + collector.startRAVProcessing() + return collector + } + + startRAVProcessing() { + const notifyAndMapEligible = (signedRavs: ValidRavs) => { + if (signedRavs.belowThreshold.length > 0) { + const logger = this.logger.child({ function: 'startRAVProcessingV2()' }) + const totalValueGRT = formatGRT( + signedRavs.belowThreshold.reduce( + (total, signedRav) => total + BigInt(signedRav.rav.rav.valueAggregate), + 0n, + ), + ) + logger.info(`Query RAVs v2 below the redemption threshold`, { + hint: 'If you would like to redeem RAVs v2 like this, reduce the voucher redemption threshold', + ravRedemptionThreshold: formatGRT(this.ravRedemptionThreshold), + belowThresholdCount: signedRavs.belowThreshold.length, + totalValueGRT, + allocations: signedRavs.belowThreshold.map((signedRav) => + dataSlice(signedRav.rav.rav.collectionId, 12).toString(), + ), + }) + } + return signedRavs.eligible + } + + const pendingRAVs = this.getPendingRAVs() + const signedRAVs = this.getSignedRAVsEventual(pendingRAVs) + const eligibleRAVs = signedRAVs + .map(notifyAndMapEligible) + .filter((signedRavs) => signedRavs.length > 0) + eligibleRAVs.pipe(async (ravs) => await this.submitRAVs(ravs)) + } + + private getPendingRAVs(): Eventual { + return sequentialTimerMap( + { + logger: this.logger, + milliseconds: RAV_CHECK_INTERVAL_MS, + }, + async () => { + let ravs = await this.pendingRAVs() + if (ravs.length === 0) { + this.logger.info(`No pending RAVs v2 to process`) + return [] + } + if (ravs.length > 0) { + ravs = await this.filterAndUpdateRavs(ravs) + } + const allocations: Allocation[] = await this.getAllocationsfromAllocationIds(ravs) + this.logger.info(`Retrieved allocations for pending RAVs v2`, { + ravs: ravs.length, + allocations: allocations.length, + }) + return ravs + .map((rav) => { + const signedRav = rav.getSignedRAV() + return { + rav: signedRav, + allocation: allocations.find( + (a) => + a.id === + toAddress(dataSlice(signedRav.rav.collectionId, 12).toString()), + ), + payer: rav.payer, + } + }) + .filter((rav) => rav.allocation !== undefined) as RavWithAllocation[] // this is safe because we filter out undefined allocations + }, + { onError: (err) => this.logger.error(`Failed to query pending RAVs v2`, { err }) }, + ) + } + + private async getAllocationsfromAllocationIds( + ravs: ReceiptAggregateVoucherV2[], + ): Promise { + const allocationIds: string[] = ravs.map((rav) => + dataSlice(rav.collectionId, 12).toString().toLowerCase(), + ) + + let block: { hash: string } | undefined = undefined + let lastId = '' + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const returnedAllocations: any[] = [] + + for (;;) { + const result = await this.networkSubgraph.query( + gql` + query allocations( + $lastId: String! + $pageSize: Int! + $block: Block_height + $allocationIds: [String!]! + ) { + meta: _meta(block: $block) { + block { + number + hash + timestamp + } + } + allocations( + first: $pageSize + block: $block + orderBy: id + orderDirection: asc + where: { id_gt: $lastId, id_in: $allocationIds } + ) { + id + status + subgraphDeployment { + id + stakedTokens + signalledTokens + queryFeesAmount + deniedAt + } + indexer { + id + } + allocatedTokens + createdAtEpoch + createdAtBlockHash + closedAtEpoch + closedAtEpoch + closedAtBlockHash + poi + queryFeeRebates + queryFeesCollected + } + } + `, + { allocationIds, lastId, pageSize: PAGE_SIZE, block }, + ) + if (!result.data) { + throw `There was an error while querying Network Subgraph. Errors: ${result.error}` + } + + returnedAllocations.push(...result.data.allocations) + block = { hash: result.data.meta.block.hash } + if (result.data.allocations.length < PAGE_SIZE) { + break + } + lastId = result.data.allocations.slice(-1)[0].id + } + + if (returnedAllocations.length == 0) { + this.logger.error( + `No allocations returned for ${allocationIds} in network subgraph`, + ) + } + // eslint-disable-next-line @typescript-eslint/no-explicit-any + return returnedAllocations.map((x) => parseGraphQLAllocation(x, this.protocolNetwork)) + } + + private getSignedRAVsEventual( + pendingRAVs: Eventual, + ): Eventual { + return pendingRAVs.tryMap( + async (pendingRAVs) => { + const escrowAccounts = await getEscrowAccounts( + this.networkSubgraph, + this.indexerAddress, + this.contracts.GraphTallyCollector.target.toString(), + ) + return await pReduce( + pendingRAVs, + async (results, rav) => { + const tokensCollected = escrowAccounts.getTokensCollectedForReceiver( + rav.payer, + rav.rav.rav.collectionId, + ) + if ( + BigInt(rav.rav.rav.valueAggregate) - tokensCollected < + this.ravRedemptionThreshold + ) { + results.belowThreshold.push(rav) + } else { + results.eligible.push(rav) + } + return results + }, + { belowThreshold: [], eligible: [] }, + ) + }, + { onError: (err) => this.logger.error(`Failed to reduce to signed RAVs`, { err }) }, + ) + } + + // redeem only if last is true + // Later can add order and limit + private async pendingRAVs(): Promise { + return await this.models.receiptAggregateVouchersV2.findAll({ + where: { last: true, final: false }, + limit: 100, + }) + } + + private async filterAndUpdateRavs( + ravsLastNotFinal: ReceiptAggregateVoucherV2[], + ): Promise { + // look for all transactions for that includes senderaddress[] and allocations[] + const subgraphResponse = await this.findTransactionsForRavs(ravsLastNotFinal) + + // check for redeemed ravs in tx list but not marked as redeemed in our database + this.markRavsInTransactionsAsRedeemed(subgraphResponse, ravsLastNotFinal) + + // Filter unfinalized RAVS fetched from DB, keeping RAVs that have not yet been redeemed on-chain + const nonRedeemedRavs = ravsLastNotFinal + // get all ravs that were marked as redeemed in our database + .filter((rav) => !!rav.redeemedAt) + // get all ravs that wasn't possible to find the transaction + .filter( + (rav) => + !subgraphResponse.transactions.find( + (tx) => + toAddress(rav.payer) === toAddress(tx.payer.id) && + dataSlice(rav.collectionId, 12) === tx.allocationId, + ), + ) + + // we use the subgraph timestamp to make decisions + // block timestamp minus 1 minute (because of blockchain timestamp uncertainty) + const ONE_MINUTE = 60 + const blockTimestampSecs = subgraphResponse._meta.block.timestamp - ONE_MINUTE + + // Mark RAVs as unredeemed in DB if the TAP subgraph couldn't find the redeem Tx. + // To handle a chain reorg that "unredeemed" the RAVs. + if (nonRedeemedRavs.length > 0) { + await this.revertRavsRedeemed(nonRedeemedRavs, blockTimestampSecs) + } + + // For all RAVs that passed finality time, we mark it as final + await this.markRavsAsFinal(blockTimestampSecs) + + return await this.models.receiptAggregateVouchersV2.findAll({ + where: { redeemedAt: null, final: false, last: true }, + }) + } + + public async markRavsInTransactionsAsRedeemed( + subgraphResponse: SubgraphResponse, + ravsLastNotFinal: ReceiptAggregateVoucherV2[], + ) { + // get a list of transactions for ravs marked as not redeemed in our database + const redeemedRavsNotOnOurDatabase = subgraphResponse.transactions + // get only the transactions that exists, this prevents errors marking as redeemed + // transactions for different senders with the same allocation id + .filter((tx) => { + // check if exists in the ravsLastNotFinal list + return !!ravsLastNotFinal.find( + (rav) => + // rav has the same sender address as tx + toAddress(rav.payer) === toAddress(tx.payer.id) && + // rav has the same allocation id as tx + dataSlice(rav.collectionId, 12) === tx.allocationId && + // rav was marked as not redeemed in the db + !rav.redeemedAt, + ) + }) + + // for each transaction that is not redeemed on our database + // but was redeemed on the blockchain, update it to redeemed + if (redeemedRavsNotOnOurDatabase.length > 0) { + for (const rav of redeemedRavsNotOnOurDatabase) { + await this.markRavAsRedeemed( + zeroPadValue(rav.allocationId, 32), + rav.payer.id, + rav.timestamp, + ) + } + } + } + + public async findTransactionsForRavs( + ravs: ReceiptAggregateVoucherV2[], + ): Promise { + let meta: GraphTallyMeta | undefined = undefined + let lastId = '' + const transactions: GraphTallyTransaction[] = [] + + const unfinalizedRavsAllocationIds = [ + ...new Set( + ravs.map((value) => toAddress(value.collectionId.slice(12)).toLowerCase()), + ), + ] + + const payerAddresses = [ + ...new Set(ravs.map((value) => toAddress(value.payer).toLowerCase())), + ] + + for (;;) { + let block: { hash: string } | undefined = undefined + if (meta?.block?.hash) { + block = { + hash: meta?.block?.hash, + } + } + + const result: QueryResult = + await this.networkSubgraph.query( + gql` + query transactions( + $lastId: String! + $pageSize: Int! + $block: Block_height + $unfinalizedRavsAllocationIds: [String!]! + $payerAddresses: [String!]! + ) { + transactions( + first: $pageSize + block: $block + orderBy: id + orderDirection: asc + where: { + id_gt: $lastId + type: "redeem" + allocationId_in: $unfinalizedRavsAllocationIds + payer_: { id_in: $payerAddresses } + } + ) { + id + allocationId + timestamp + payer { + id + } + } + _meta { + block { + hash + timestamp + } + } + } + `, + { + lastId, + pageSize: PAGE_SIZE, + block, + unfinalizedRavsAllocationIds, + payerAddresses, + }, + ) + + if (!result.data) { + throw `There was an error while querying Network Subgraph. Errors: ${result.error}` + } + meta = result.data._meta + transactions.push(...result.data.transactions) + if (result.data.transactions.length < PAGE_SIZE) { + break + } + lastId = result.data.transactions.slice(-1)[0].id + } + + return { + transactions, + _meta: meta!, + } + } + + // for every allocation_id of this list that contains the redeemedAt less than the current + // subgraph timestamp + private async revertRavsRedeemed( + ravsNotRedeemed: { collectionId: string; payer: string }[], + blockTimestampSecs: number, + ) { + if (ravsNotRedeemed.length == 0) { + return + } + + // WE use sql directly due to a bug in sequelize update: + // https://github.com/sequelize/sequelize/issues/7664 (bug been open for 7 years no fix yet or ever) + const query = ` + UPDATE tap_horizon_ravs + SET redeemed_at = NULL + WHERE (collection_id::char(64), payer::char(40)) IN (VALUES ${ravsNotRedeemed + .map( + (rav) => + `('${rav.collectionId + .toString() + .toLowerCase() + .replace('0x', '')}'::char(64), '${rav.payer + .toString() + .toLowerCase() + .replace('0x', '')}'::char(40))`, + ) + .join(', ')}) + AND redeemed_at < to_timestamp(${blockTimestampSecs}) + ` + + await this.models.receiptAggregateVouchersV2.sequelize?.query(query) + + this.logger.warn( + `Reverted Redeemed RAVs v2: ${ravsNotRedeemed + .map((rav) => `(${rav.payer},${rav.collectionId})`) + .join(', ')}`, + ) + } + + // we use blockTimestamp instead of NOW() because we must be older than + // the subgraph timestamp + private async markRavsAsFinal(blockTimestampSecs: number) { + const query = ` + UPDATE tap_horizon_ravs + SET final = TRUE + WHERE last = TRUE + AND final = FALSE + AND redeemed_at IS NOT NULL + AND redeemed_at < to_timestamp(${blockTimestampSecs - this.finalityTime}) + ` + + await this.models.receiptAggregateVouchersV2.sequelize?.query(query) + } + + private async submitRAVs(signedRavs: RavWithAllocation[]): Promise { + const logger = this.logger.child({ + function: 'submitRAVsV2', + ravsToSubmit: signedRavs.length, + }) + + logger.info(`Submit last RAVs v2 on chain individually`, { + signedRavs, + }) + + const escrowAccounts = await getEscrowAccounts( + this.networkSubgraph, + this.indexerAddress, + this.contracts.GraphTallyCollector.target.toString(), + ) + + // Redeem RAV one-by-one as no plual version available + const tokensCollectedPerAllocation: { + allocationId: string + tokensCollected: bigint + }[] = [] + + for (const { rav: signedRav, allocation, payer } of signedRavs) { + const { rav } = signedRav + + // verify escrow balances + const ravValue = BigInt(rav.valueAggregate.toString()) + const tokensAlreadyCollected = escrowAccounts.getTokensCollectedForReceiver( + payer, + rav.collectionId, + ) + const payerBalance = escrowAccounts.getBalanceForPayer(payer) + + // In horizon the RAV value is monotonically increasing. To calculate the actual outstanding amount we need to subtract the tokens already collected. + const tokensToCollect = ravValue - tokensAlreadyCollected + if (payerBalance < tokensToCollect) { + this.logger.warn( + 'RAV v2 was not sent to the blockchain \ + because its value aggregate is lower than escrow balance.', + { + rav, + payer, + payerBalance, + }, + ) + continue + } + + const stopTimer = this.metrics.ravsRedeemDuration.startTimer({ + collection: rav.collectionId, + }) + + try { + // subtract from the escrow account + // THIS IS A MUT OPERATION + const actualTokensCollected = await this.redeemRav(logger, signedRav) + if (!actualTokensCollected) { + throw new Error(`Failed to redeem RAV v2: no tokens collected`) + } + tokensCollectedPerAllocation.push({ + allocationId: allocation.id, + tokensCollected: actualTokensCollected, + }) + escrowAccounts.updateBalances(payer, rav.collectionId, actualTokensCollected) + } catch (err) { + this.metrics.ravRedeemsFailed.inc({ collection: rav.collectionId }) + logger.error(`Failed to redeem RAV v2`, { + err: indexerError(IndexerErrorCode.IE055, err), + }) + continue + } + stopTimer() + } + + try { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + await this.models.allocationSummaries.sequelize!.transaction( + async (transaction) => { + for (const { allocationId, tokensCollected } of tokensCollectedPerAllocation) { + const [summary] = await ensureAllocationSummary( + this.models, + toAddress(allocationId.toString()), + transaction, + this.protocolNetwork, + ) + summary.withdrawnFees = ( + BigInt(summary.withdrawnFees) + BigInt(tokensCollected) + ).toString() + await summary.save({ transaction }) + } + }, + ) + + logger.info(`Updated allocation summaries table with withdrawn fees for RAV v2`) + } catch (err) { + logger.warn(`Failed to update allocation summaries for RAV v2`, { + err, + }) + } + + signedRavs.map((signedRav) => + this.metrics.ravRedeemsSuccess.inc({ collection: signedRav.rav.rav.collectionId }), + ) + } + + public async redeemRav( + logger: Logger, + signedRav: SignedRAVv2, + ): Promise { + const { rav, signature } = signedRav + + const encodedData = encodeCollectQueryFeesData(rav, signature.toString(), 0n) + + // Submit the signed RAV on chain + const txReceipt = await this.transactionManager.executeTransaction( + () => + this.contracts.SubgraphService.collect.estimateGas( + rav.serviceProvider, + PaymentTypes.QueryFee, + encodedData, + ), + (gasLimit) => + this.contracts.SubgraphService.collect(rav.serviceProvider, 0, encodedData, { + gasLimit, + }), + logger.child({ function: 'collect' }), + ) + + // get tx receipt and post process + if (txReceipt === 'paused' || txReceipt === 'unauthorized') { + this.metrics.ravRedeemsInvalid.inc({ collection: rav.collectionId }) + return + } + + // Get the actual value collected + const contractInterface = this.contracts.GraphTallyCollector.interface + const event = contractInterface.getEvent('PaymentCollected') + + const log = txReceipt.logs.find((log) => log.topics[0] === event.topicHash) + if (!log) throw new Error('PaymentCollected event not found!') + + const decoded = contractInterface.decodeEventLog(event, log.data, log.topics) + if (!decoded.tokens) { + throw new Error( + `Actual value collected not found for collection ${rav.collectionId}`, + ) + } + const actualTokensCollected = BigInt(decoded.tokens) + + this.metrics.ravCollectedFees.set( + { collection: rav.collectionId }, + parseFloat(actualTokensCollected.toString()), + ) + + try { + await this.markRavAsRedeemed(rav.collectionId, rav.payer) + logger.info( + `Updated receipt aggregate vouchers v2 table with redeemed_at for collection ${rav.collectionId} and payer ${rav.payer}`, + ) + } catch (err) { + logger.warn( + `Failed to update receipt aggregate voucher v2 table with redeemed_at for collection ${rav.collectionId} and payer ${rav.payer}`, + { + err, + }, + ) + } + + return actualTokensCollected + } + + private async markRavAsRedeemed( + collectionId: string, + payer: string, + timestamp?: number, + ) { + // WE use sql directly due to a bug in sequelize update: + // https://github.com/sequelize/sequelize/issues/7664 (bug been open for 7 years no fix yet or ever) + const query = ` + UPDATE tap_horizon_ravs + SET redeemed_at = ${timestamp ? `to_timestamp(${timestamp})` : 'NOW()'} + WHERE collection_id = '${collectionId + .toString() + .toLowerCase() + .replace('0x', '')}' + AND payer = '${payer.toString().toLowerCase().replace('0x', '')}' + ` + + await this.models.receiptAggregateVouchersV2.sequelize?.query(query) + } +} + +const registerReceiptMetrics = (metrics: Metrics, networkIdentifier: string) => ({ + ravRedeemsSuccess: new metrics.client.Counter({ + name: `indexer_agent_rav_v2_exchanges_ok_${networkIdentifier}`, + help: 'Successfully redeemed ravs v2', + registers: [metrics.registry], + labelNames: ['collection'], + }), + + ravRedeemsInvalid: new metrics.client.Counter({ + name: `indexer_agent_rav_v2_exchanges_invalid_${networkIdentifier}`, + help: 'Invalid ravs v2 redeems - tx paused or unauthorized', + registers: [metrics.registry], + labelNames: ['collection'], + }), + + ravRedeemsFailed: new metrics.client.Counter({ + name: `indexer_agent_rav_v2_redeems_failed_${networkIdentifier}`, + help: 'Failed redeems for ravs v2', + registers: [metrics.registry], + labelNames: ['collection'], + }), + + ravsRedeemDuration: new metrics.client.Histogram({ + name: `indexer_agent_rav_v2_redeem_duration_${networkIdentifier}`, + help: 'Duration of redeeming ravs v2', + registers: [metrics.registry], + labelNames: ['collection'], + }), + + ravCollectedFees: new metrics.client.Gauge({ + name: `indexer_agent_rav_v2_collected_fees_${networkIdentifier}`, + help: 'Amount of query fees collected for a rav v2', + registers: [metrics.registry], + labelNames: ['collection'], + }), +}) diff --git a/packages/indexer-common/src/allocations/horizon-escrow-accounts.ts b/packages/indexer-common/src/allocations/horizon-escrow-accounts.ts new file mode 100644 index 000000000..4a7216612 --- /dev/null +++ b/packages/indexer-common/src/allocations/horizon-escrow-accounts.ts @@ -0,0 +1,113 @@ +import { SubgraphClient } from '../subgraph-client' +import gql from 'graphql-tag' + +export type PaymentsEscrowAccountResponse = { + paymentsEscrowAccounts: { + balance: string + payer: { + id: string + } + }[] + // Not a typo just how graph-client pluralizes the field name + graphTallyTokensCollecteds: { + tokens: string + collectionId: string + payer: { + id: string + } + }[] +} + +export class PaymentsEscrowAccounts { + private payersBalances: Map + private receiversTokensCollected: Map + + constructor( + payersBalances: Map, + receiversTokensCollected: Map, + ) { + this.payersBalances = payersBalances + this.receiversTokensCollected = receiversTokensCollected + } + + getBalanceForPayer(payer: string): bigint { + const balance = this.payersBalances.get(payer) + if (balance === undefined) { + throw new Error(`No balance found for payer: ${payer}`) + } + return balance + } + + getTokensCollectedForReceiver(payer: string, collectionId: string): bigint { + const balance = this.receiversTokensCollected.get(`${payer}-${collectionId}`) + if (balance === undefined) { + throw new Error( + `No tokens collected found for payer: ${payer} and collectionId: ${collectionId}`, + ) + } + return balance + } + + updateBalances(payer: string, collectionId: string, value: bigint) { + // payer balance + const balance = this.getBalanceForPayer(payer) + if (balance < value) { + throw new Error(`Negative balances are not allowed`) + } + const newBalance = balance - value + this.payersBalances.set(payer, newBalance) + + // receiver tokens collected + const tokensCollected = this.getTokensCollectedForReceiver(payer, collectionId) + this.receiversTokensCollected.set(`${payer}-${collectionId}`, tokensCollected + value) + } + + static fromResponse(response: PaymentsEscrowAccountResponse): PaymentsEscrowAccounts { + const payersBalances = new Map() + const tokensCollected = new Map() + + response.paymentsEscrowAccounts.forEach((account) => { + payersBalances.set(account.payer.id, BigInt(account.balance)) + }) + + response.graphTallyTokensCollecteds.forEach((token) => { + tokensCollected.set(`${token.payer.id}-${token.collectionId}`, BigInt(token.tokens)) + }) + + return new PaymentsEscrowAccounts(payersBalances, tokensCollected) + } +} + +export const getEscrowAccounts = async ( + subgraph: SubgraphClient, + indexer: string, + collectorAddress: string, +): Promise => { + const result = await subgraph.query( + gql` + query PaymentsEscrowAccountQuery($indexer: ID!, $collector: String!) { + paymentsEscrowAccounts( + where: { receiver_: { id: $indexer }, collector: $collector } + ) { + balance + payer { + id + } + } + graphTallyTokensCollecteds(where: { receiver_: { id: $indexer } }) { + tokens + collectionId + payer { + id + } + } + } + `, + { indexer, collector: collectorAddress }, + ) + if (!result.data) { + throw `There was an error while querying Network Subgraph. Errors: ${result.error}` + } + + return PaymentsEscrowAccounts.fromResponse(result.data) +} diff --git a/packages/indexer-common/src/allocations/index.ts b/packages/indexer-common/src/allocations/index.ts index 79e60e617..8db9cdaf1 100644 --- a/packages/indexer-common/src/allocations/index.ts +++ b/packages/indexer-common/src/allocations/index.ts @@ -1,6 +1,5 @@ export * from './escrow-accounts' export * from './keys' -export * from './query-fees' export * from './tap-collector' export * from './monitor' export * from './types' diff --git a/packages/indexer-common/src/allocations/keys.ts b/packages/indexer-common/src/allocations/keys.ts index 0f7aaaddf..da11921c8 100644 --- a/packages/indexer-common/src/allocations/keys.ts +++ b/packages/indexer-common/src/allocations/keys.ts @@ -1,14 +1,14 @@ -import { Wallet, utils, Signer } from 'ethers' +import { Wallet, Signer, HDNodeWallet, solidityPackedKeccak256, getBytes } from 'ethers' import { Address, SubgraphDeploymentID, toAddress } from '@graphprotocol/common-ts' import { Allocation } from './types' const deriveKeyPair = ( - hdNode: utils.HDNode, + hdNode: HDNodeWallet, epoch: number, deployment: SubgraphDeploymentID, index: number, ): { publicKey: string; privateKey: string; address: Address } => { - const path = 'm/' + [epoch, ...Buffer.from(deployment.ipfsHash), index].join('/') + const path = [epoch, ...Buffer.from(deployment.ipfsHash), index].join('/') const derivedKey = hdNode.derivePath(path) return { publicKey: derivedKey.publicKey, @@ -19,10 +19,10 @@ const deriveKeyPair = ( // Returns the private key of allocation signer export const allocationSignerPrivateKey = ( - wallet: Wallet, + wallet: HDNodeWallet, allocation: Allocation, ): string => { - const hdNode = utils.HDNode.fromMnemonic(wallet.mnemonic.phrase) + const hdNode = HDNodeWallet.fromPhrase(wallet.mnemonic!.phrase) // The allocation was either created at the epoch it intended to or one // epoch later. So try both both. @@ -43,7 +43,10 @@ export const allocationSignerPrivateKey = ( } // Returns allocation signer wallet -export const allocationSigner = (wallet: Wallet, allocation: Allocation): Signer => { +export const allocationSigner = ( + wallet: HDNodeWallet, + allocation: Allocation, +): Signer => { return new Wallet(allocationSignerPrivateKey(wallet, allocation)) } @@ -66,7 +69,7 @@ export const uniqueAllocationID = ( existingIDs: Address[], ): { allocationSigner: Signer; allocationId: Address } => { for (let i = 0; i < 100; i++) { - const hdNode = utils.HDNode.fromMnemonic(indexerMnemonic) + const hdNode = HDNodeWallet.fromPhrase(indexerMnemonic) const keyPair = deriveKeyPair(hdNode, epoch, deployment, i) if (!existingIDs.includes(keyPair.address)) { return { @@ -79,19 +82,47 @@ export const uniqueAllocationID = ( throw new Error(`Exhausted limit of 100 parallel allocations`) } -export const allocationIdProof = ( +export const legacyAllocationIdProof = ( signer: Signer, indexerAddress: string, allocationId: string, ): Promise => { - const messageHash = utils.solidityKeccak256( + const messageHash = solidityPackedKeccak256( ['address', 'address'], [indexerAddress, allocationId], ) - const messageHashBytes = utils.arrayify(messageHash) + const messageHashBytes = getBytes(messageHash) return signer.signMessage(messageHashBytes) } +export const EIP712_ALLOCATION_ID_PROOF_TYPES = { + AllocationIdProof: [ + { name: 'indexer', type: 'address' }, + { name: 'allocationId', type: 'address' }, + ], +} + +// For new allocations in the subgraph service +export const horizonAllocationIdProof = ( + signer: Signer, + chainId: number, + indexerAddress: Address, + allocationId: Address, + subgraphServiceAddress: string, +): Promise => { + const domain = { + name: 'SubgraphService', + version: '1.0', + chainId: chainId, + verifyingContract: subgraphServiceAddress, + } + + return signer.signTypedData(domain, EIP712_ALLOCATION_ID_PROOF_TYPES, { + indexer: indexerAddress, + allocationId: allocationId, + }) +} + export const tapAllocationIdProof = ( signer: Signer, chainId: number, @@ -99,10 +130,10 @@ export const tapAllocationIdProof = ( allocationId: Address, escrowContract: Address, ): Promise => { - const messageHash = utils.solidityKeccak256( + const messageHash = solidityPackedKeccak256( ['uint256', 'address', 'address', 'address'], [chainId, sender, allocationId, escrowContract], ) - const messageHashBytes = utils.arrayify(messageHash) + const messageHashBytes = getBytes(messageHash) return signer.signMessage(messageHashBytes) } diff --git a/packages/indexer-common/src/allocations/query-fees.test.ts b/packages/indexer-common/src/allocations/query-fees.test.ts deleted file mode 100644 index d42342ea4..000000000 --- a/packages/indexer-common/src/allocations/query-fees.test.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { PartialVoucher, encodePartialVouchers } from './query-fees' - -const TEST_DATA: Array = [ - { - allocation: '0x6aea8894b5ab5a36cdc2d8be9290046801dd5fed', - fees: '1208491688206053754', - receipt_id_max: '0x1321676bb44e606cda1779a8d92af9', - receipt_id_min: '0x01460d518a7b0b278dcd2bf882c11a', - signature: - '0x81140e47bc06819e133735bbd622213d50029d958115e4f905f18fcede2dce0f027669b2a5a6b0303d1692d7f2f01db65236f632f4c02450b102275c2cb816e11c', - }, - { - allocation: '0x6aea8894b5ab5a36cdc2d8be9290046801dd5fed', - fees: '1215330506986176264', - receipt_id_max: '0x1ea67d3d01eb7d6b25e33332e4f5fd', - receipt_id_min: '0x13ce97080acc5acf664404fdb9038f', - signature: - '0x62374ca18ad2713d149e1e90c3771d7fc4e5c643f7f063bacd497b7be2089c72404026ea675e189017c072850811422514a9781c663414f42689f697dc262ad21c', - }, - { - allocation: '0x6aea8894b5ab5a36cdc2d8be9290046801dd5fed', - fees: '1215454440881710511', - receipt_id_max: '0x2e8f582977cbacb24b4fc0d0d52436', - receipt_id_min: '0x217ae93ba26b959edfa33eeb08c0ba', - signature: - '0x657ddb7e0b09c8b0a5938df2d29d5d6d9412c5f153b4a409ca05cb6c62be1cf30016394462eaf2d1b86049f3ad71c0c2162bc97965a98a19a3bbf372106b82c01c', - }, -] - -const TEST_DATA_MULTIPLE_ALLOCATIONS_PARTIAL_VOUCHERS: Array = [ - { - allocation: '0x7bea8894b5ab5a36cdc2d8be9290046801dd5fed', - fees: '1208491688206053754', - receipt_id_max: '0x1321676bb44e606cda1779a8d92af9', - receipt_id_min: '0x01460d518a7b0b278dcd2bf882c11a', - signature: - '0x81140e47bc06819e133735bbd622213d50029d958115e4f905f18fcede2dce0f027669b2a5a6b0303d1692d7f2f01db65236f632f4c02450b102275c2cb816e11c', - }, - { - allocation: '0x6aea8894b5ab5a36cdc2d8be9290046801dd5fed', - fees: '1215330506986176264', - receipt_id_max: '0x1ea67d3d01eb7d6b25e33332e4f5fd', - receipt_id_min: '0x13ce97080acc5acf664404fdb9038f', - signature: - '0x62374ca18ad2713d149e1e90c3771d7fc4e5c643f7f063bacd497b7be2089c72404026ea675e189017c072850811422514a9781c663414f42689f697dc262ad21c', - }, - { - allocation: '0x6aea8894b5ab5a36cdc2d8be9290046801dd5fed', - fees: '1215454440881710511', - receipt_id_max: '0x2e8f582977cbacb24b4fc0d0d52436', - receipt_id_min: '0x217ae93ba26b959edfa33eeb08c0ba', - signature: - '0x657ddb7e0b09c8b0a5938df2d29d5d6d9412c5f153b4a409ca05cb6c62be1cf30016394462eaf2d1b86049f3ad71c0c2162bc97965a98a19a3bbf372106b82c01c', - }, -] - -describe('Encode partial vouchers', () => { - test('encode a single partial voucher', () => { - const partialVoucherData = TEST_DATA.slice(0, 1) - expect(encodePartialVouchers(partialVoucherData)).toEqual({ - allocation: partialVoucherData[0].allocation, - partialVouchers: partialVoucherData, - }) - }) - - test('encode multiple partial vouchers', () => { - expect(encodePartialVouchers(TEST_DATA)).toEqual({ - allocation: TEST_DATA[0].allocation, - partialVouchers: TEST_DATA, - }) - }) - - test('fail to encode vouchers because they are from multiple allocations', () => { - const partialVoucherData = TEST_DATA_MULTIPLE_ALLOCATIONS_PARTIAL_VOUCHERS - expect(() => encodePartialVouchers(partialVoucherData)).toThrowError( - `Partial vouchers set must be for a single allocation, '2' unique allocations represented`, - ) - }) -}) diff --git a/packages/indexer-common/src/allocations/query-fees.ts b/packages/indexer-common/src/allocations/query-fees.ts deleted file mode 100644 index a6565620a..000000000 --- a/packages/indexer-common/src/allocations/query-fees.ts +++ /dev/null @@ -1,812 +0,0 @@ -import { Counter, Gauge, Histogram } from 'prom-client' -import axios from 'axios' -import { - Logger, - BytesWriter, - toAddress, - formatGRT, - Address, - Metrics, - Eventual, -} from '@graphprotocol/common-ts' -import { - Allocation, - AllocationReceipt, - indexerError, - IndexerErrorCode, - QueryFeeModels, - Voucher, - ensureAllocationSummary, - TransactionManager, - specification as spec, - sequentialTimerMap, - SubgraphClient, -} from '..' -import { DHeap } from '@thi.ng/heaps' -import { BigNumber, BigNumberish, Contract } from 'ethers' -import { Op } from 'sequelize' -import pReduce from 'p-reduce' - -// Receipts are collected with a delay of 20 minutes after -// the corresponding allocation was closed -const RECEIPT_COLLECT_DELAY = 1200_000 - -interface AllocationReceiptsBatch { - receipts: AllocationReceipt[] - timeout: number -} - -export interface PartialVoucher { - allocation: string // (0x-prefixed hex) - fees: string // (0x-prefixed hex) - signature: string // (0x-prefixed hex) - receipt_id_min: string // (0x-prefixed hex) - receipt_id_max: string // (0x-prefixed hex) -} - -interface ReceiptMetrics { - receiptsToCollect: Gauge - failedReceipts: Counter - partialVouchersToExchange: Gauge - receiptsCollectDuration: Histogram - vouchers: Counter - successVoucherRedeems: Counter - invalidVoucherRedeems: Counter - failedVoucherRedeems: Counter - vouchersRedeemDuration: Histogram - vouchersBatchRedeemSize: Gauge - voucherCollectedFees: Gauge -} - -export interface AllocationPartialVouchers { - allocation: string - partialVouchers: PartialVoucher[] -} - -export interface AllocationReceiptCollectorOptions { - logger: Logger - metrics: Metrics - transactionManager: TransactionManager - allocationExchange: Contract - allocations: Eventual - models: QueryFeeModels - networkSpecification: spec.NetworkSpecification - networkSubgraph: SubgraphClient -} - -export interface ReceiptCollector { - rememberAllocations(actionID: number, allocationIDs: Address[]): Promise - collectReceipts(actionID: number, allocation: Allocation): Promise -} - -export class AllocationReceiptCollector implements ReceiptCollector { - declare logger: Logger - declare metrics: ReceiptMetrics - declare models: QueryFeeModels - declare transactionManager: TransactionManager - declare allocationExchange: Contract - declare allocations: Eventual - declare collectEndpoint: URL - declare partialVoucherEndpoint: URL - declare voucherEndpoint: URL - declare receiptsToCollect: DHeap - declare voucherRedemptionThreshold: BigNumber - declare voucherRedemptionBatchThreshold: BigNumber - declare voucherRedemptionMaxBatchSize: number - declare protocolNetwork: string - declare networkSubgraph: SubgraphClient - - // eslint-disable-next-line @typescript-eslint/no-empty-function -- Private constructor to prevent direct instantiation - private constructor() {} - - public static async create({ - logger, - metrics, - transactionManager, - models, - allocationExchange, - allocations, - networkSpecification, - networkSubgraph, - }: AllocationReceiptCollectorOptions): Promise { - const collector = new AllocationReceiptCollector() - collector.logger = logger.child({ component: 'AllocationReceiptCollector' }) - collector.metrics = registerReceiptMetrics( - metrics, - networkSpecification.networkIdentifier, - ) - collector.transactionManager = transactionManager - collector.models = models - collector.allocationExchange = allocationExchange - collector.allocations = allocations - collector.protocolNetwork = networkSpecification.networkIdentifier - collector.networkSubgraph = networkSubgraph - - // Process Gateway routes - const gatewayUrls = processGatewayRoutes(networkSpecification.gateway.url) - collector.collectEndpoint = gatewayUrls.collectReceipts - collector.voucherEndpoint = gatewayUrls.voucher - collector.partialVoucherEndpoint = gatewayUrls.partialVoucher - - const { - voucherRedemptionThreshold, - voucherRedemptionBatchThreshold, - voucherRedemptionMaxBatchSize, - } = networkSpecification.indexerOptions - collector.voucherRedemptionThreshold = voucherRedemptionThreshold - collector.voucherRedemptionBatchThreshold = voucherRedemptionBatchThreshold - collector.voucherRedemptionMaxBatchSize = voucherRedemptionMaxBatchSize - - // Start the AllocationReceiptCollector - // TODO: Consider calling methods conditionally based on a boolean - // flag during startup. - collector.startReceiptCollecting() - collector.startVoucherProcessing() - await collector.queuePendingReceiptsFromDatabase() - return collector - } - - async rememberAllocations( - actionID: number, - allocationIDs: Address[], - ): Promise { - const logger = this.logger.child({ - action: actionID, - allocations: allocationIDs, - }) - - try { - logger.info('Remember allocations for collecting receipts later') - - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - await this.models.allocationSummaries.sequelize!.transaction( - async (transaction) => { - for (const allocation of allocationIDs) { - const [summary] = await ensureAllocationSummary( - this.models, - allocation, - transaction, - this.protocolNetwork, - ) - await summary.save({ transaction }) - } - }, - ) - return true - } catch (err) { - logger.error(`Failed to remember allocations for collecting receipts later`, { - err: indexerError(IndexerErrorCode.IE056, err), - }) - return false - } - } - - async collectReceipts(actionID: number, allocation: Allocation): Promise { - const logger = this.logger.child({ - action: actionID, - allocation: allocation.id, - deployment: allocation.subgraphDeployment.id.display, - }) - - try { - logger.debug(`Queue allocation receipts for collecting`, { actionID, allocation }) - - const now = new Date() - - const receipts = - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - await this.models.allocationReceipts.sequelize!.transaction( - async (transaction) => { - // Update the allocation summary - await this.models.allocationSummaries.update( - { closedAt: now }, - { - where: { - allocation: allocation.id, - protocolNetwork: this.protocolNetwork, - }, - transaction, - }, - ) - - // Return all receipts for the just-closed allocation - return this.models.allocationReceipts.findAll({ - where: { allocation: allocation.id, protocolNetwork: this.protocolNetwork }, - order: ['id'], - transaction, - }) - }, - ) - - this.metrics.receiptsToCollect.set( - { allocation: receipts[0]?.allocation }, - receipts.length, - ) - if (receipts.length <= 0) { - logger.debug(`No receipts to collect for allocation`, { actionID, allocation }) - return false - } - - const timeout = now.valueOf() + RECEIPT_COLLECT_DELAY - - // Collect the receipts for this allocation in a bit - this.receiptsToCollect.push({ - receipts, - timeout, - }) - logger.info(`Successfully queued allocation receipts for collecting`, { - receipts: receipts.length, - timeout: new Date(timeout).toLocaleString(), - actionID, - allocation, - }) - return true - } catch (err) { - const error = indexerError(IndexerErrorCode.IE053, err) - this.metrics.failedReceipts.inc({ allocation: allocation.id }) - this.logger.error(`Failed to queue allocation receipts for collecting`, { - error, - actionID, - allocation, - }) - throw error - } - } - - private startReceiptCollecting() { - this.receiptsToCollect = new DHeap(null, { - compare: (t1, t2) => t1.timeout - t2.timeout, - }) - - const hasReceiptsReadyForCollecting = () => { - const batch = this.receiptsToCollect.peek() - return batch && batch.timeout <= Date.now() - } - - // Check if there's another batch of receipts to collect every 10s - sequentialTimerMap({ logger: this.logger, milliseconds: 10_000 }, async () => { - while (hasReceiptsReadyForCollecting()) { - // Remove the batch from the processing queue - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const batch = this.receiptsToCollect.pop()! - - // If the array is empty we cannot know what allocation this group - // belongs to. Should this assertion ever fail, then there is a - // programmer error where empty batches are pushed to the - // `receiptsToCollect` queue. - console.assert(batch.receipts.length > 0) - - // Collect the receipts now - await this.obtainReceiptsVoucher(batch.receipts) - } - }) - } - - private startVoucherProcessing() { - sequentialTimerMap({ logger: this.logger, milliseconds: 30_000 }, async () => { - let pendingVouchers: Voucher[] = [] - try { - pendingVouchers = await this.pendingVouchers() // Ordered by value - } catch (err) { - this.logger.warn(`Failed to query pending vouchers`, { err }) - return - } - - const logger = this.logger.child({}) - - const vouchers = await pReduce( - pendingVouchers, - async (results, voucher) => { - if (await this.allocationExchange.allocationsRedeemed(voucher.allocation)) { - try { - await this.models.vouchers.destroy({ - where: { - allocation: voucher.allocation, - protocolNetwork: this.protocolNetwork, - }, - }) - logger.warn( - `Query fee voucher for allocation already redeemed, deleted local voucher copy`, - { allocation: voucher.allocation }, - ) - } catch (err) { - logger.warn(`Failed to delete local vouchers copy, will try again later`, { - err, - allocation: voucher.allocation, - }) - } - return results - } - if (BigNumber.from(voucher.amount).lt(this.voucherRedemptionThreshold)) { - results.belowThreshold.push(voucher) - } else { - results.eligible.push(voucher) - } - return results - }, - { belowThreshold: [], eligible: [] }, - ) - - if (vouchers.belowThreshold.length > 0) { - const totalValueGRT = formatGRT( - vouchers.belowThreshold.reduce( - (total, voucher) => total.add(BigNumber.from(voucher.amount)), - BigNumber.from(0), - ), - ) - logger.info(`Query vouchers below the redemption threshold`, { - hint: 'If you would like to redeem vouchers like this, reduce the voucher redemption threshold', - voucherRedemptionThreshold: formatGRT(this.voucherRedemptionThreshold), - belowThresholdCount: vouchers.belowThreshold.length, - totalValueGRT, - allocations: vouchers.belowThreshold.map((voucher) => voucher.allocation), - }) - } - - // If there are no eligible vouchers then bail - if (vouchers.eligible.length === 0) return - - // Already ordered by value - const voucherBatch = vouchers.eligible.slice(0, this.voucherRedemptionMaxBatchSize), - batchValueGRT = voucherBatch.reduce( - (total, voucher) => total.add(BigNumber.from(voucher.amount)), - BigNumber.from(0), - ) - - if (batchValueGRT.gt(this.voucherRedemptionBatchThreshold)) { - this.metrics.vouchersBatchRedeemSize.set(voucherBatch.length) - logger.info(`Query voucher batch is ready for redemption`, { - batchSize: voucherBatch.length, - voucherRedemptionMaxBatchSize: this.voucherRedemptionMaxBatchSize, - voucherRedemptionBatchThreshold: formatGRT( - this.voucherRedemptionBatchThreshold, - ), - batchValueGRT: formatGRT(batchValueGRT), - }) - await this.submitVouchers(voucherBatch) - } else { - logger.info(`Query voucher batch value too low for redemption`, { - batchSize: voucherBatch.length, - voucherRedemptionMaxBatchSize: this.voucherRedemptionMaxBatchSize, - voucherRedemptionBatchThreshold: formatGRT( - this.voucherRedemptionBatchThreshold, - ), - batchValueGRT: formatGRT(batchValueGRT), - }) - } - }) - } - - private async pendingVouchers(): Promise { - return this.models.vouchers.findAll({ - where: { protocolNetwork: this.protocolNetwork }, - order: [['amount', 'DESC']], // sorted by highest value to maximise the value of the batch - limit: this.voucherRedemptionMaxBatchSize, // limit the number of vouchers to the max batch size - }) - } - - private encodeReceiptBatch(receipts: AllocationReceipt[]): BytesWriter { - // Encode the receipt batch to a buffer - // [allocationId, receipts[]] (in bytes) - const encodedReceipts = new BytesWriter(20 + receipts.length * 112) - encodedReceipts.writeHex(receipts[0].allocation) - for (const receipt of receipts) { - // [fee, id, signature] - const fee = BigNumber.from(receipt.fees).toHexString() - const feePadding = 33 - fee.length / 2 - encodedReceipts.writeZeroes(feePadding) - encodedReceipts.writeHex(fee) - encodedReceipts.writeHex(receipt.id) - encodedReceipts.writeHex(receipt.signature) - } - return encodedReceipts - } - - private async obtainReceiptsVoucher(receipts: AllocationReceipt[]): Promise { - const allocation = receipts[0].allocation - const logger = this.logger.child({ - allocation, - function: 'obtainReceiptsVoucher()', - }) - // Gross underestimated number of receipts the gateway take at once - const receiptsThreshold = 25_000 - let response - try { - logger.info(`Collect receipts for allocation`, { - receipts: receipts.length, - }) - const stopTimer = this.metrics.receiptsCollectDuration.startTimer({ allocation }) - - // All receipts can fit the gateway, make a single-shot collection - if (receipts.length <= receiptsThreshold) { - const encodedReceipts = this.encodeReceiptBatch(receipts) - - // Exchange the receipts for a voucher signed by the counterparty (aka the client) - response = await axios.post( - this.collectEndpoint.toString(), - encodedReceipts.unwrap().buffer, - { headers: { 'Content-Type': 'application/octet-stream' } }, - ) - } else { - logger.info( - `Too many receipts to collect in oneshot, collecting in batches of '${receiptsThreshold} receipts`, - { - receipts: receipts.length, - }, - ) - // Split receipts in batches and collect partial vouchers - const partialVouchers: Array = [] - for (let i = 0; i < receipts.length; i += receiptsThreshold) { - const partialReceipts = receipts.slice( - i, - Math.min(i + receiptsThreshold, receipts.length), - ) - const encodedReceipts = this.encodeReceiptBatch(partialReceipts) - - // Exchange the receipts for a partial voucher signed by the counterparty (aka the client) - response = await axios.post( - this.partialVoucherEndpoint.toString(), - encodedReceipts.unwrap().buffer, - { headers: { 'Content-Type': 'application/octet-stream' } }, - ) - const partialVoucher = response.data as PartialVoucher - partialVouchers.push(partialVoucher) - } - - this.metrics.partialVouchersToExchange.set({ allocation }, partialVouchers.length) - logger.debug(`Partial vouchers to exchange`, { - partialVouchers: partialVouchers.length, - }) - - const encodedPartialVouchers = encodePartialVouchers(partialVouchers) - - // Exchange the partial vouchers for a voucher - response = await axios.post( - this.voucherEndpoint.toString(), - encodedPartialVouchers, - { - headers: { 'Content-Type': 'application/json' }, - }, - ) - } - - logger.trace('Gateway response', { - response, - allocation, - }) - - // Depending of which Gateway endpoint was used, fee information can come in different fields - const fees = response.data.fees ?? response.data.amount - if (!fees || !response.data.allocation || !response.data.signature) { - throw new Error('Failed to parse response from Gateay') - } - - const voucher = { ...response.data, fees } as { - allocation: string - fees: string - signature: string - } - - this.metrics.vouchers.inc({ - allocation, - }) - this.metrics.voucherCollectedFees.set({ allocation }, parseFloat(voucher.fees)) - - // Replace the receipts with the voucher in one db transaction; - // should this fail, we'll try to collect these receipts again - // later - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - await this.models.vouchers.sequelize!.transaction(async (transaction) => { - logger.debug(`Removing collected receipts from the database`, { - receipts: receipts.length, - }) - - // Remove all receipts in the batch from the database - await this.models.allocationReceipts.destroy({ - where: { - id: receipts.map((receipt) => receipt.id), - protocolNetwork: this.protocolNetwork, - }, - transaction, - }) - - logger.debug(`Add voucher received in exchange for receipts to the database`, { - voucher, - }) - - // Update the query fees tracked against the allocation - const [summary] = await ensureAllocationSummary( - this.models, - toAddress(voucher.allocation), - transaction, - this.protocolNetwork, - ) - summary.collectedFees = BigNumber.from(summary.collectedFees) - .add(voucher.fees) - .toString() - await summary.save({ transaction }) - - // Add the voucher to the database - await this.models.vouchers.findOrCreate({ - where: { - allocation: toAddress(voucher.allocation), - protocolNetwork: this.protocolNetwork, - }, - defaults: { - allocation: toAddress(voucher.allocation), - amount: voucher.fees, - signature: voucher.signature, - protocolNetwork: this.protocolNetwork, - }, - transaction, - }) - }) - stopTimer() - } catch (err) { - logger.error( - `Failed to collect receipts in exchange for an on-chain query fee voucher`, - { err: indexerError(IndexerErrorCode.IE054, err) }, - ) - } - } - - private async submitVouchers(vouchers: Voucher[]): Promise { - const logger = this.logger.child({ - function: 'submitVouchers()', - voucherBatchSize: vouchers.length, - }) - - logger.info(`Redeem query voucher batch on chain`, { - vouchers, - }) - const stopTimer = this.metrics.vouchersRedeemDuration.startTimer({ - allocation: vouchers[0].allocation, - }) - - const hexPrefix = (bytes: string): string => - bytes.startsWith('0x') ? bytes : `0x${bytes}` - - const onchainVouchers = vouchers.map((voucher) => { - return { - allocationID: hexPrefix(voucher.allocation), - amount: voucher.amount, - signature: hexPrefix(voucher.signature), - } - }) - - try { - // Submit the voucher on chain - const txReceipt = await this.transactionManager.executeTransaction( - () => this.allocationExchange.estimateGas.redeemMany(onchainVouchers), - async (gasLimit: BigNumberish) => - this.allocationExchange.redeemMany(onchainVouchers, { - gasLimit, - }), - logger.child({ action: 'redeemMany' }), - ) - - if (txReceipt === 'paused' || txReceipt === 'unauthorized') { - this.metrics.invalidVoucherRedeems.inc({ allocation: vouchers[0].allocation }) - return - } - - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - await this.models.allocationSummaries.sequelize!.transaction( - async (transaction) => { - for (const voucher of vouchers) { - const [summary] = await ensureAllocationSummary( - this.models, - toAddress(voucher.allocation), - transaction, - this.protocolNetwork, - ) - summary.withdrawnFees = BigNumber.from(summary.withdrawnFees) - .add(voucher.amount) - .toString() - await summary.save({ transaction }) - } - }, - ) - } catch (err) { - this.metrics.failedVoucherRedeems.inc({ allocation: vouchers[0].allocation }) - logger.error(`Failed to redeem query fee voucher`, { - err: indexerError(IndexerErrorCode.IE055, err), - }) - return - } - stopTimer() - - // Remove the now obsolete voucher from the database - logger.info(`Successfully redeemed query fee voucher, delete local copy`) - try { - await this.models.vouchers.destroy({ - where: { - allocation: vouchers.map((voucher) => voucher.allocation), - protocolNetwork: this.protocolNetwork, - }, - }) - this.metrics.successVoucherRedeems.inc({ allocation: vouchers[0].allocation }) - logger.info(`Successfully deleted local voucher copy`) - } catch (err) { - logger.warn(`Failed to delete local voucher copy, will try again later`, { - err, - }) - } - } - - public async queuePendingReceiptsFromDatabase(): Promise { - // Obtain all closed allocations - const closedAllocations = await this.models.allocationSummaries.findAll({ - where: { closedAt: { [Op.not]: null }, protocolNetwork: this.protocolNetwork }, - }) - - // Create a receipts batch for each of these allocations - const batches = new Map( - closedAllocations.map((summary) => [ - summary.allocation, - { - timeout: summary.closedAt.valueOf() + RECEIPT_COLLECT_DELAY, - receipts: [], - }, - ]), - ) - - // Obtain all receipts for these allocations - const uncollectedReceipts = await this.models.allocationReceipts.findAll({ - where: { - allocation: closedAllocations.map((summary) => summary.allocation), - protocolNetwork: this.protocolNetwork, - }, - order: ['id'], - }) - - // Add receipts into the right batches - for (const receipt of uncollectedReceipts) { - const batch = batches.get(receipt.allocation) - - // We can safely assume that we only fetched receipts matching the - // allocations; just asserting this here to be _really_ sure - console.assert(batch !== undefined) - batch?.receipts.push(receipt) - } - - // Queue all batches of uncollected receipts - for (const batch of batches.values()) { - if (batch.receipts.length > 0) { - this.logger.info( - `Queue allocation receipts for collecting again after a restart`, - { - allocation: batch.receipts[0].allocation, - receipts: batch.receipts.length, - }, - ) - this.receiptsToCollect.push(batch) - } - } - } -} - -export function encodePartialVouchers( - partialVouchers: PartialVoucher[], -): AllocationPartialVouchers { - const uniqueAllocations = new Set(partialVouchers.map((voucher) => voucher.allocation)) - .size - if (uniqueAllocations !== 1) { - throw Error( - `Partial vouchers set must be for a single allocation, '${uniqueAllocations}' unique allocations represented`, - ) - } - - return { - allocation: partialVouchers[0].allocation, - partialVouchers, - } -} - -const registerReceiptMetrics = (metrics: Metrics, networkIdentifier: string) => ({ - receiptsToCollect: new metrics.client.Gauge({ - name: `indexer_agent_receipts_to_collect_${networkIdentifier}`, - help: 'Individual receipts to collect', - registers: [metrics.registry], - labelNames: ['allocation'], - }), - - failedReceipts: new metrics.client.Counter({ - name: `indexer_agent_receipts_failed_${networkIdentifier}`, - help: 'Failed to queue receipts to collect', - registers: [metrics.registry], - labelNames: ['allocation'], - }), - - partialVouchersToExchange: new metrics.client.Gauge({ - name: `indexer_agent_vouchers_to_exchange_${networkIdentifier}`, - help: 'Individual partial vouchers to exchange', - registers: [metrics.registry], - labelNames: ['allocation'], - }), - - receiptsCollectDuration: new metrics.client.Histogram({ - name: `indexer_agent_receipts_exchange_duration_${networkIdentifier}`, - help: 'Duration of processing and exchanging receipts to voucher', - registers: [metrics.registry], - labelNames: ['allocation'], - }), - - vouchers: new metrics.client.Counter({ - name: `indexer_agent_vouchers_${networkIdentifier}`, - help: 'Individual vouchers to redeem', - registers: [metrics.registry], - labelNames: ['allocation'], - }), - - successVoucherRedeems: new metrics.client.Counter({ - name: `indexer_agent_voucher_exchanges_ok_${networkIdentifier}`, - help: 'Successfully redeemed vouchers', - registers: [metrics.registry], - labelNames: ['allocation'], - }), - - invalidVoucherRedeems: new metrics.client.Counter({ - name: `indexer_agent_voucher_exchanges_invalid_${networkIdentifier}`, - help: 'Invalid vouchers redeems - tx paused or unauthorized', - registers: [metrics.registry], - labelNames: ['allocation'], - }), - - failedVoucherRedeems: new metrics.client.Counter({ - name: `indexer_agent_voucher_redeems_failed_${networkIdentifier}`, - help: 'Failed redeems for vouchers', - registers: [metrics.registry], - labelNames: ['allocation'], - }), - - vouchersRedeemDuration: new metrics.client.Histogram({ - name: `indexer_agent_vouchers_redeem_duration_${networkIdentifier}`, - help: 'Duration of redeeming vouchers', - registers: [metrics.registry], - labelNames: ['allocation'], - }), - - vouchersBatchRedeemSize: new metrics.client.Gauge({ - name: `indexer_agent_vouchers_redeem_${networkIdentifier}`, - help: 'Size of redeeming batched vouchers', - registers: [metrics.registry], - }), - - voucherCollectedFees: new metrics.client.Gauge({ - name: `indexer_agent_voucher_collected_fees_${networkIdentifier}`, - help: 'Amount of query fees collected for a voucher', - registers: [metrics.registry], - labelNames: ['allocation'], - }), -}) - -interface GatewayRoutes { - collectReceipts: URL - voucher: URL - partialVoucher: URL -} - -function processGatewayRoutes(input: string): GatewayRoutes { - const GATEWAY_ROUTES = { - collectReceipts: 'collect-receipts', - voucher: 'voucher', - partialVoucher: 'partial-voucher', - } - - // Strip existing information except for protocol and host - const inputURL = new URL(input) - const base = `${inputURL.protocol}//${inputURL.host}` - - function route(pathname: string): URL { - const url = new URL(base) - url.pathname = pathname - return url - } - - return { - collectReceipts: route(GATEWAY_ROUTES.collectReceipts), - voucher: route(GATEWAY_ROUTES.voucher), - partialVoucher: route(GATEWAY_ROUTES.partialVoucher), - } -} diff --git a/packages/indexer-common/src/allocations/tap-collector.ts b/packages/indexer-common/src/allocations/tap-collector.ts index 9431fff84..f7ab896a9 100644 --- a/packages/indexer-common/src/allocations/tap-collector.ts +++ b/packages/indexer-common/src/allocations/tap-collector.ts @@ -23,7 +23,6 @@ import { parseGraphQLAllocation, sequentialTimerMap, } from '..' -import { BigNumber } from 'ethers' import pReduce from 'p-reduce' import { SubgraphClient, QueryResult } from '../subgraph-client' import gql from 'graphql-tag' @@ -104,7 +103,7 @@ export class TapCollector { declare transactionManager: TransactionManager declare tapContracts: TapContracts declare allocations: Eventual - declare ravRedemptionThreshold: BigNumber + declare ravRedemptionThreshold: bigint declare protocolNetwork: string declare tapSubgraph: SubgraphClient declare networkSubgraph: SubgraphClient @@ -156,9 +155,8 @@ export class TapCollector { const logger = this.logger.child({ function: 'startRAVProcessing()' }) const totalValueGRT = formatGRT( signedRavs.belowThreshold.reduce( - (total, signedRav) => - total.add(BigNumber.from(signedRav.rav.rav.valueAggregate)), - BigNumber.from(0), + (total, signedRav) => total + BigInt(signedRav.rav.rav.valueAggregate), + 0n, ), ) logger.info(`Query RAVs below the redemption threshold`, { @@ -208,7 +206,7 @@ export class TapCollector { return { rav: signedRav, allocation: allocations.find( - (a) => a.id === toAddress(signedRav.rav.allocationId), + (a) => a.id === toAddress(signedRav.rav.allocationId.toString()), ), sender: rav.senderAddress, } @@ -223,7 +221,7 @@ export class TapCollector { ravs: ReceiptAggregateVoucher[], ): Promise { const allocationIds: string[] = ravs.map((rav) => - rav.getSignedRAV().rav.allocationId.toLowerCase(), + rav.getSignedRAV().rav.allocationId.toString().toLowerCase(), ) let block: { hash: string } | undefined = undefined @@ -309,9 +307,7 @@ export class TapCollector { return await pReduce( pendingRAVs, async (results, rav) => { - if ( - BigNumber.from(rav.rav.rav.valueAggregate).lt(this.ravRedemptionThreshold) - ) { + if (BigInt(rav.rav.rav.valueAggregate) < this.ravRedemptionThreshold) { results.belowThreshold.push(rav) } else { results.eligible.push(rav) @@ -582,7 +578,7 @@ export class TapCollector { } const stopTimer = this.metrics.ravsRedeemDuration.startTimer({ - allocation: rav.allocationId, + allocation: rav.allocationId.toString(), }) try { await this.redeemRav(logger, allocation, sender, signedRav) @@ -590,7 +586,7 @@ export class TapCollector { // THIS IS A MUT OPERATION escrowAccounts.subtractSenderBalance(sender, ravValue) } catch (err) { - this.metrics.ravRedeemsFailed.inc({ allocation: rav.allocationId }) + this.metrics.ravRedeemsFailed.inc({ allocation: rav.allocationId.toString() }) logger.error(`Failed to redeem RAV`, { err: indexerError(IndexerErrorCode.IE055, err), }) @@ -607,13 +603,13 @@ export class TapCollector { const { rav } = signedRav const [summary] = await ensureAllocationSummary( this.models, - toAddress(rav.allocationId), + toAddress(rav.allocationId.toString()), transaction, this.protocolNetwork, ) - summary.withdrawnFees = BigNumber.from(summary.withdrawnFees) - .add(rav.valueAggregate) - .toString() + summary.withdrawnFees = ( + BigInt(summary.withdrawnFees) + BigInt(rav.valueAggregate) + ).toString() await summary.save({ transaction }) } }, @@ -645,8 +641,8 @@ export class TapCollector { allocationSigner(this.transactionManager.wallet, allocation), parseInt(this.protocolNetwork.split(':')[1]), sender, - toAddress(rav.allocationId), - toAddress(escrow.escrow.address), + toAddress(rav.allocationId.toString()), + toAddress(escrow.escrow.target.toString()), ) this.logger.debug(`Computed allocationIdProof`, { allocationId: rav.allocationId, @@ -654,7 +650,7 @@ export class TapCollector { }) // Submit the signed RAV on chain const txReceipt = await this.transactionManager.executeTransaction( - () => escrow.escrow.estimateGas.redeem(signedRav, proof), + () => escrow.escrow.redeem.estimateGas(signedRav, proof), (gasLimit) => escrow.escrow.redeem(signedRav, proof, { gasLimit, @@ -664,17 +660,17 @@ export class TapCollector { // get tx receipt and post process if (txReceipt === 'paused' || txReceipt === 'unauthorized') { - this.metrics.ravRedeemsInvalid.inc({ allocation: rav.allocationId }) + this.metrics.ravRedeemsInvalid.inc({ allocation: rav.allocationId.toString() }) return } this.metrics.ravCollectedFees.set( - { allocation: rav.allocationId }, + { allocation: rav.allocationId.toString() }, parseFloat(rav.valueAggregate.toString()), ) try { - await this.markRavAsRedeemed(toAddress(rav.allocationId), sender) + await this.markRavAsRedeemed(toAddress(rav.allocationId.toString()), sender) logger.info( `Updated receipt aggregate vouchers table with redeemed_at for allocation ${rav.allocationId} and sender ${sender}`, ) diff --git a/packages/indexer-common/src/allocations/types.ts b/packages/indexer-common/src/allocations/types.ts index b31c6c71f..63afd6e0a 100644 --- a/packages/indexer-common/src/allocations/types.ts +++ b/packages/indexer-common/src/allocations/types.ts @@ -1,4 +1,3 @@ -import { BigNumber } from 'ethers' import { SubgraphClient, SubgraphDeployment } from '@graphprotocol/indexer-common' import { Logger, Address } from '@graphprotocol/common-ts' @@ -6,18 +5,32 @@ import { Logger, Address } from '@graphprotocol/common-ts' export interface Allocation { id: Address status: AllocationStatus + isLegacy: boolean subgraphDeployment: SubgraphDeployment indexer: Address - allocatedTokens: BigNumber + allocatedTokens: bigint + createdAt: number createdAtEpoch: number createdAtBlockHash: string + closedAt: number closedAtEpoch: number closedAtEpochStartBlockHash: string | undefined previousEpochStartBlockHash: string | undefined closedAtBlockHash: string poi: string | undefined - queryFeeRebates: BigNumber | undefined - queryFeesCollected: BigNumber | undefined + queryFeeRebates: bigint | undefined + queryFeesCollected: bigint | undefined +} + +export interface Provision { + id: Address + dataService: Address + indexer: Address + tokensProvisioned: bigint + tokensAllocated: bigint + tokensThawing: bigint + maxVerifierCut: bigint + thawingPeriod: bigint } export enum AllocationStatus { diff --git a/packages/indexer-common/src/errors.ts b/packages/indexer-common/src/errors.ts index 34dc610d9..dd4c518d7 100644 --- a/packages/indexer-common/src/errors.ts +++ b/packages/indexer-common/src/errors.ts @@ -88,6 +88,14 @@ export enum IndexerErrorCode { IE075 = 'IE075', IE076 = 'IE076', IE077 = 'IE077', + IE078 = 'IE078', + IE079 = 'IE079', + IE080 = 'IE080', + IE081 = 'IE081', + IE082 = 'IE082', + IE083 = 'IE083', + IE084 = 'IE084', + IE085 = 'IE085', } export const INDEXER_ERROR_MESSAGES: Record = { @@ -169,6 +177,14 @@ export const INDEXER_ERROR_MESSAGES: Record = { IE075: 'Failed to connect to network contracts', IE076: 'Failed to resume subgraph deployment', IE077: 'Failed to allocate: subgraph not healthily syncing', + IE078: 'No provision found', + IE079: 'Failed to add stake to provision: Invalid stake amount provided', + IE080: 'Failed to add stake to provision: stake not added on chain', + IE081: 'Multiple provisions found', + IE082: 'Graph Horizon protocol not detected', + IE083: 'Failed to thaw stake from provision', + IE084: 'Could not resolve POI block number', + IE085: 'Could not resolve public POI', } export type IndexerErrorCause = unknown diff --git a/packages/indexer-common/src/graph-node.ts b/packages/indexer-common/src/graph-node.ts index f75d87b5e..21e902918 100644 --- a/packages/indexer-common/src/graph-node.ts +++ b/packages/indexer-common/src/graph-node.ts @@ -1026,6 +1026,22 @@ export class GraphNode { } } + public async entityCount(deployments: SubgraphDeploymentID[]): Promise { + // Query the entity count for each deployment using the indexingStatuses query + const query = ` + query entityCounts($deployments: [String!]!) { + indexingStatuses(subgraphs: $deployments) { + entityCount + } + } + ` + const result = await this.status + .query(query, { deployments: deployments.map((id) => id.ipfsHash) }) + .toPromise() + + return result.data.indexingStatuses.map((status) => status.entityCount) as number[] + } + public async proofOfIndexing( deployment: SubgraphDeploymentID, block: BlockPointer, diff --git a/packages/indexer-common/src/index.ts b/packages/indexer-common/src/index.ts index ab3eedd97..a74020745 100644 --- a/packages/indexer-common/src/index.ts +++ b/packages/indexer-common/src/index.ts @@ -3,6 +3,7 @@ export * from './allocations' export * from './async-cache' export * from './errors' export * from './indexer-management' +export * from './indexing-fees' export * from './graph-node' export * from './operator' export * from './network' @@ -17,3 +18,4 @@ export * from './parsers' export * as specification from './network-specification' export * from './multi-networks' export * from './sequential-timer' +export * from './indexing-fees' diff --git a/packages/indexer-common/src/indexer-management/__tests__/allocations.test.ts b/packages/indexer-common/src/indexer-management/__tests__/allocations.test.ts index eafd14665..ab80e44cc 100644 --- a/packages/indexer-common/src/indexer-management/__tests__/allocations.test.ts +++ b/packages/indexer-common/src/indexer-management/__tests__/allocations.test.ts @@ -62,6 +62,7 @@ const setup = async () => { const network = await Network.create( logger, testNetworkSpecification, + managementModels, queryFeeModels, graphNode, metrics, @@ -141,23 +142,23 @@ describe.skip('Allocation Manager', () => { // Allocate test action expect(allocate.action.type).toBe(ActionType.ALLOCATE) expect(allocate.allocates).toStrictEqual(parseGRT('10000')) - expect(allocate.rewards.isZero()).toBeTruthy() - expect(allocate.unallocates.isZero()).toBeTruthy() + expect(allocate.rewards).toBe(0n) + expect(allocate.unallocates).toBe(0n) expect(allocate.balance).toStrictEqual(parseGRT('10000')) // Unallocate test action expect(unallocate.action.type).toBe(ActionType.UNALLOCATE) - expect(unallocate.allocates.isZero()).toBeTruthy() - expect(unallocate.rewards.isZero()).toBeFalsy() + expect(unallocate.allocates).toBe(0n) + expect(unallocate.rewards).toBe(0n) expect(unallocate.unallocates).toStrictEqual(parseGRT('10000')) expect(unallocate.balance).toStrictEqual( - unallocate.allocates.sub(unallocate.unallocates).sub(unallocate.rewards), + unallocate.allocates - unallocate.unallocates - unallocate.rewards, ) // This Reallocate test Action intentionally uses a null or zeroed POI, so it should not accrue rewards. expect(reallocate.action.type).toBe(ActionType.REALLOCATE) expect(reallocate.allocates).toStrictEqual(parseGRT('10000')) - expect(reallocate.rewards.isZero()).toBeTruthy() + expect(reallocate.rewards).toBe(0n) expect(reallocate.unallocates).toStrictEqual(parseGRT('10000')) expect(reallocate.balance).toStrictEqual(parseGRT('0')) }) diff --git a/packages/indexer-common/src/indexer-management/__tests__/helpers.test.ts b/packages/indexer-common/src/indexer-management/__tests__/helpers.test.ts index 58f21dd43..62a9535a7 100644 --- a/packages/indexer-common/src/indexer-management/__tests__/helpers.test.ts +++ b/packages/indexer-common/src/indexer-management/__tests__/helpers.test.ts @@ -1,9 +1,7 @@ import { - connectContracts, connectDatabase, createLogger, Logger, - NetworkContracts, SubgraphDeploymentID, toAddress, } from '@graphprotocol/common-ts' @@ -34,7 +32,11 @@ import { getTestProvider, } from '@graphprotocol/indexer-common' import { mockLogger, mockProvider } from '../../__tests__/subgraph.test' -import { BigNumber, ethers, utils } from 'ethers' +import { hexlify, Provider } from 'ethers' +import { + connectGraphHorizon, + connectSubgraphService, +} from '@graphprotocol/toolshed/deployments' // Make global Jest variable available // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -44,8 +46,7 @@ declare const __LOG_LEVEL__: any let sequelize: Sequelize let models: IndexerManagementModels -let ethereum: ethers.providers.BaseProvider -let contracts: NetworkContracts +let ethereum: Provider let graphNode: GraphNode let networkSubgraph: SubgraphClient let epochSubgraph: SubgraphClient @@ -71,7 +72,12 @@ const setupMonitor = async () => { level: __LOG_LEVEL__ ?? 'error', }) ethereum = getTestProvider('sepolia') - contracts = await connectContracts(ethereum, 5, undefined) + const horizonContracts = connectGraphHorizon(5, ethereum) + const subgraphServiceContracts = connectSubgraphService(5, ethereum) + const contracts = { + ...horizonContracts, + ...subgraphServiceContracts, + } const subgraphFreshnessChecker = new SubgraphFreshnessChecker( 'Test Subgraph', @@ -130,16 +136,16 @@ export const createMockAllocation = (): Allocation => { const mockDeployment = { id: new SubgraphDeploymentID('QmcpeU4pZxzKB9TJ6fzH6PyZi9h8PJ6pG1c4izb9VAakJq'), deniedAt: 0, - stakedTokens: BigNumber.from(50000), - signalledTokens: BigNumber.from(100000), - queryFeesAmount: BigNumber.from(0), + stakedTokens: 50000n, + signalledTokens: 100000n, + queryFeesAmount: 0n, } as SubgraphDeployment const mockAllocation = { id: toAddress('0xbAd8935f75903A1eF5ea62199d98Fd7c3c1ab20C'), status: AllocationStatus.CLOSED, subgraphDeployment: mockDeployment, indexer: toAddress('0xc61127cdfb5380df4214b0200b9a07c7c49d34f9'), - allocatedTokens: BigNumber.from(1000), + allocatedTokens: 1000n, createdAtEpoch: 3, createdAtBlockHash: '0x675e9411241c431570d07b920321b2ff6aed2359aa8e26109905d34bffd8932a', @@ -240,6 +246,7 @@ describe('Actions', () => { priority: 0, // When writing directly to the database, `protocolNetwork` must be in the CAIP2-ID format. protocolNetwork: 'eip155:421614', + isLegacy: true, } await models.Action.upsert(action) @@ -277,6 +284,14 @@ describe('Actions', () => { updatedAt: { [Op.lte]: literal("NOW() - INTERVAL '1d'") }, }), ).resolves.toHaveLength(0) + + await expect( + ActionManager.fetchActions(models, null, { + status: ActionStatus.FAILED, + type: ActionType.ALLOCATE, + isLegacy: true, + }), + ).resolves.toHaveLength(1) }) }) describe('Types', () => { @@ -326,8 +341,11 @@ describe.skip('Monitor: local', () => { await expect(networkMonitor.currentEpochNumber()).resolves.toBeGreaterThan(1500) }) - test('Fetch maxAllocationEpoch', async () => { - await expect(networkMonitor.maxAllocationEpoch()).resolves.toBeGreaterThan(1) + test('Fetch maxAllocationDuration', async () => { + await expect(networkMonitor.maxAllocationDuration()).resolves.toMatchObject({ + legacy: expect.any(Number), + horizon: expect.any(Number), + }) }) test('Fetch network chain current epoch', async () => { @@ -339,7 +357,13 @@ describe.skip('Monitor: local', () => { test('Resolve POI using force=true', async () => { await expect( - networkMonitor.resolvePOI(mockAllocation, utils.hexlify(Array(32).fill(0)), true), + networkMonitor.resolvePOI( + mockAllocation, + hexlify(new Uint8Array(32).fill(0)), + undefined, + undefined, + true, + ), ).resolves.toEqual( '0x0000000000000000000000000000000000000000000000000000000000000000', ) @@ -347,7 +371,7 @@ describe.skip('Monitor: local', () => { test('Fail to resolve POI', async () => { await expect( - networkMonitor.resolvePOI(mockAllocation, undefined, false), + networkMonitor.resolvePOI(mockAllocation, undefined, undefined, undefined, false), ).rejects.toEqual(indexerError(IndexerErrorCode.IE018, `Could not resolve POI`)) }) }) diff --git a/packages/indexer-common/src/indexer-management/__tests__/horizon-ready.test.ts b/packages/indexer-common/src/indexer-management/__tests__/horizon-ready.test.ts new file mode 100644 index 000000000..fbffa06c2 --- /dev/null +++ b/packages/indexer-common/src/indexer-management/__tests__/horizon-ready.test.ts @@ -0,0 +1,150 @@ +import { createLogger, Logger } from '@graphprotocol/common-ts' +import { NetworkMonitor } from '../monitor' +import { getTestProvider } from '../../utils' +import { resolveChainId } from '../../indexer-management' +import { GraphNode } from '../../graph-node' +import { SubgraphClient } from '../../subgraph-client' +import { SubgraphFreshnessChecker } from '../../subgraphs' +import { mockLogger, mockProvider } from '../../__tests__/subgraph.test' +import { specification as spec } from '../../index' +import { + connectGraphHorizon, + connectSubgraphService, +} from '@graphprotocol/toolshed/deployments' +import { Provider } from 'ethers' + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +declare const __LOG_LEVEL__: any + +describe('Horizon readiness', () => { + let logger: Logger + let ethereum: Provider + let graphNode: GraphNode + let networkSubgraph: SubgraphClient + let epochSubgraph: SubgraphClient + let networkMonitor: NetworkMonitor + // eslint-disable-next-line @typescript-eslint/no-explicit-any + let mockHorizonStaking: any + // eslint-disable-next-line @typescript-eslint/no-explicit-any + let contracts: any + + const setupMonitor = async () => { + logger = createLogger({ + name: 'Horizon readiness tests', + async: false, + level: __LOG_LEVEL__ ?? 'error', + }) + ethereum = getTestProvider('sepolia') + + mockHorizonStaking = { + getMaxThawingPeriod: jest.fn(), + connect: jest.fn(), + waitForDeployment: jest.fn(), + interface: {}, + queryFilter: jest.fn(), + } + + const horizonContracts = { + ...connectGraphHorizon(5, ethereum), + HorizonStaking: mockHorizonStaking, + } + contracts = { + ...horizonContracts, + ...connectSubgraphService(5, ethereum), + } + + const subgraphFreshnessChecker = new SubgraphFreshnessChecker( + 'Test Subgraph', + mockProvider, + 10, + 10, + mockLogger, + 1, + ) + + networkSubgraph = await SubgraphClient.create({ + name: 'NetworkSubgraph', + logger, + endpoint: 'http://test-endpoint.xyz', + deployment: undefined, + subgraphFreshnessChecker, + }) + + epochSubgraph = await SubgraphClient.create({ + name: 'EpochSubgraph', + logger, + endpoint: 'http://test-endpoint.xyz', + subgraphFreshnessChecker, + }) + + graphNode = new GraphNode( + logger, + 'http://test-admin-endpoint.xyz', + 'https://test-query-endpoint.xyz', + 'http://test-status-endpoint.xyz', + 'https://test-ipfs-endpoint.xyz', + ) + + const indexerOptions = spec.IndexerOptions.parse({ + address: '0xc61127cdfb5380df4214b0200b9a07c7c49d34f9', + mnemonic: + 'word ivory whale diesel slab pelican voyage oxygen chat find tobacco sport', + url: 'http://test-url.xyz', + }) + + networkMonitor = new NetworkMonitor( + resolveChainId('sepolia'), + contracts, + indexerOptions, + logger, + graphNode, + networkSubgraph, + ethereum, + epochSubgraph, + ) + } + + beforeEach(setupMonitor) + + describe('monitorIsHorizon', () => { + beforeEach(() => { + mockHorizonStaking.getMaxThawingPeriod.mockResolvedValue(0) + }) + + test('should return false when getMaxThawingPeriod returns 0', async () => { + const isHorizon = await networkMonitor.monitorIsHorizon(logger, { + ...contracts, + HorizonStaking: mockHorizonStaking, + }) + const value = await isHorizon.value() + expect(value).toBe(false) + }) + + test('should return true when getMaxThawingPeriod returns > 0', async () => { + mockHorizonStaking.getMaxThawingPeriod.mockResolvedValue(1000) + + const isHorizon = await networkMonitor.monitorIsHorizon(logger, { + ...contracts, + HorizonStaking: mockHorizonStaking, + }) + + const value = await isHorizon.value() + console.log('Final value:', value) + expect(value).toBe(true) + }) + + test('should handle errors and maintain previous state', async () => { + mockHorizonStaking.getMaxThawingPeriod.mockRejectedValue( + new Error('Contract error'), + ) + + const isHorizon = await networkMonitor.monitorIsHorizon(logger, { + ...contracts, + HorizonStaking: mockHorizonStaking, + }) + + const value = await isHorizon.value() + expect(value).toBe(false) + }) + }) +}) diff --git a/packages/indexer-common/src/indexer-management/__tests__/util.ts b/packages/indexer-common/src/indexer-management/__tests__/util.ts index 7a4204553..66521ee6e 100644 --- a/packages/indexer-common/src/indexer-management/__tests__/util.ts +++ b/packages/indexer-common/src/indexer-management/__tests__/util.ts @@ -58,6 +58,7 @@ export const createTestManagementClient = async ( const network = await Network.create( logger, networkSpecification, + managementModels, queryFeeModels, graphNode, metrics, diff --git a/packages/indexer-common/src/indexer-management/actions.ts b/packages/indexer-common/src/indexer-management/actions.ts index a0d89018d..47f8c832f 100644 --- a/packages/indexer-common/src/indexer-management/actions.ts +++ b/packages/indexer-common/src/indexer-management/actions.ts @@ -92,11 +92,16 @@ export class ActionManager { ).filter((a) => approvedDeploymentIDs.includes(a.subgraphDeployment.id.ipfsHash)) let affectedAllocationExpiring = false if (affectedAllocations.length) { - const currentEpoch = await network.networkMonitor.currentEpochNumber() - const maxAllocationEpoch = await network.networkMonitor.maxAllocationEpoch() + const maxAllocationDuration = await network.networkMonitor.maxAllocationDuration() + // affectedAllocations are ordered by creation time so use index 0 for oldest allocation to check expiration + const currentEpoch = await network.networkMonitor.currentEpochNumber() affectedAllocationExpiring = - currentEpoch >= affectedAllocations[0].createdAtEpoch + maxAllocationEpoch + currentEpoch >= + affectedAllocations[0].createdAtEpoch + + (affectedAllocations[0].isLegacy + ? maxAllocationDuration.legacy + : maxAllocationDuration.horizon) } logger.debug( @@ -107,6 +112,7 @@ export class ActionManager { oldestAffectedAllocationCreatedAtEpoch: affectedAllocations[0]?.createdAtEpoch ?? 'no action in the batch affects existing allocations', + oldestAffectedAllocationIsLegacy: affectedAllocations[0]?.isLegacy, affectedAllocationExpiring, }, ) @@ -328,7 +334,7 @@ export class ActionManager { }) if (pendingActions.length > 0) { logger.warn( - `${pendingActions} Actions found in PENDING state when execution began. Was there a crash?` + + `${pendingActions.length} Actions found in PENDING state when execution began. Was there a crash? ` + `These indicate that execution was interrupted while calling contracts, and will need to be cleared manually.`, ) } @@ -364,7 +370,7 @@ export class ActionManager { const allocationManager = this.allocationManagers[network.specification.networkIdentifier] - let results + let results: AllocationResult[] try { // TODO: we should lift the batch execution (graph-node, then contracts) up to here so we can // mark the actions appropriately diff --git a/packages/indexer-common/src/indexer-management/allocations.ts b/packages/indexer-common/src/indexer-management/allocations.ts index fcc614f07..210e2cefc 100644 --- a/packages/indexer-common/src/indexer-management/allocations.ts +++ b/packages/indexer-common/src/indexer-management/allocations.ts @@ -10,11 +10,12 @@ import { ActionFailure, ActionType, Allocation, - allocationIdProof, + legacyAllocationIdProof, AllocationResult, AllocationStatus, CloseAllocationResult, CreateAllocationResult, + DipsManager, fetchIndexingRules, GraphNode, indexerError, @@ -32,23 +33,36 @@ import { SubgraphStatus, uniqueAllocationID, upsertIndexingRule, + horizonAllocationIdProof, + POIData, + ExecuteTransactionResult, } from '@graphprotocol/indexer-common' +import { + encodeStartServiceData, + encodeStopServiceData, + PaymentTypes, +} from '@graphprotocol/toolshed' +import { + encodeCollectIndexingRewardsData, + encodePOIMetadata, +} from '@graphprotocol/toolshed' import { - BigNumber, BigNumberish, - ContractReceipt, - PopulatedTransaction, - utils, + BytesLike, + ContractTransaction, + hexlify, + TransactionReceipt, + TransactionRequest, + ZeroAddress, } from 'ethers' -import { BytesLike } from '@ethersproject/bytes' import pMap from 'p-map' export interface TransactionPreparationContext { activeAllocations: Allocation[] recentlyClosedAllocations: Allocation[] - currentEpoch: BigNumber + currentEpoch: bigint indexingStatuses: IndexingStatus[] } @@ -63,47 +77,62 @@ export interface AllocateTransactionParams { export interface UnallocateTransactionParams { allocationID: string - poi: BytesLike + poi: POIData + isLegacy: boolean + indexer: string + actionID: number + protocolNetwork: string } export interface ReallocateTransactionParams { closingAllocationID: string - poi: BytesLike + poi: POIData indexer: string subgraphDeploymentID: BytesLike tokens: BigNumberish newAllocationID: string metadata: BytesLike proof: BytesLike + closingAllocationIsLegacy: boolean + actionID: number + protocolNetwork: string } // An Action with resolved Allocation and Unallocation values export interface ActionStakeUsageSummary { action: Action - allocates: BigNumber - unallocates: BigNumber - rewards: BigNumber - balance: BigNumber + allocates: bigint + unallocates: bigint + rewards: bigint + balance: bigint } export type PopulateTransactionResult = - | PopulatedTransaction - | PopulatedTransaction[] + | ActionTransactionRequest + | ActionTransactionRequest[] | ActionFailure +export type ActionTransactionRequest = TransactionRequest & { + actionID: number + protocolNetwork: string +} + export type TransactionResult = - | ContractReceipt - | 'paused' - | 'unauthorized' + | (TransactionReceipt | 'paused' | 'unauthorized')[] | ActionFailure[] export class AllocationManager { + declare dipsManager: DipsManager | null constructor( private logger: Logger, private models: IndexerManagementModels, private graphNode: GraphNode, private network: Network, - ) {} + ) { + if (this.network.specification.indexerOptions.dipperEndpoint) { + this.dipsManager = new DipsManager(this.logger, this.models, this.network, this) + } + } async executeBatch( actions: Action[], @@ -112,17 +141,14 @@ export class AllocationManager { const logger = this.logger.child({ function: 'executeBatch' }) logger.trace('Executing action batch', { actions }) const result = await this.executeTransactions(actions, onFinishedDeploying) - if (Array.isArray(result)) { - logger.trace('Execute batch transaction failed', { actionBatchResult: result }) - return result as ActionFailure[] - } return await this.confirmTransactions(result, actions) } private async executeTransactions( actions: Action[], onFinishedDeploying: (actions: Action[]) => Promise, - ): Promise { + ): Promise { + const actionResults: ExecuteTransactionResult[] = [] const logger = this.logger.child({ function: 'executeTransactions' }) logger.trace('Begin executing transactions', { actions }) if (actions.length < 1) { @@ -135,58 +161,241 @@ export class AllocationManager { await this.deployBeforeAllocating(logger, validatedActions) await onFinishedDeploying(validatedActions) - const populateTransactionsResults = await this.prepareTransactions(validatedActions) - - const failedTransactionPreparations = populateTransactionsResults - .filter((result) => isActionFailure(result)) - .map((result) => result as ActionFailure) + // Populated transaction result for each action + const populatedActionTransactionsResults = + await this.prepareTransactions(validatedActions) + logger.trace('populatedActionTransactionsResults', { + populatedActionTransactionsResults, + }) - if (failedTransactionPreparations.length > 0) { - logger.trace('Failed to prepare transactions', { failedTransactionPreparations }) - return failedTransactionPreparations + // Flat list of valid prepared transactions + const preparedTransactions: ActionTransactionRequest[] = [] + + for (const populatedActionTransactionResult of populatedActionTransactionsResults) { + if (isActionFailure(populatedActionTransactionResult)) { + logger.debug('Failed to prepare action', { populatedActionTransactionResult }) + actionResults.push({ + actionID: populatedActionTransactionResult.actionID, + success: false, + result: populatedActionTransactionResult, + }) + } else { + if (Array.isArray(populatedActionTransactionResult)) { + preparedTransactions.push(...populatedActionTransactionResult) + } else { + preparedTransactions.push(populatedActionTransactionResult) + } + } } logger.trace('Prepared transactions ', { - preparedTransactions: populateTransactionsResults, + preparedTransactions: preparedTransactions, }) - const callData = populateTransactionsResults - .flat() - .map((tx) => tx as PopulatedTransaction) - .filter((tx: PopulatedTransaction) => !!tx.data) - .map((tx) => tx.data as string) - logger.trace('Prepared transaction calldata', { callData }) - - return await this.network.transactionManager.executeTransaction( - async () => this.network.contracts.staking.estimateGas.multicall(callData), - async (gasLimit) => - this.network.contracts.staking.multicall(callData, { gasLimit }), - this.logger.child({ - actions: `${JSON.stringify(validatedActions.map((action) => action.id))}`, - function: 'staking.multicall', - }), + // We need to process both staking contract and subgraph service transactions separately + // as they cannot be multicalled + // Realistically, the only scenario where a batch would have both is shortly after the horizon upgrade + const stakingTransactions = preparedTransactions.filter( + (tx: TransactionRequest) => tx.to === this.network.contracts.HorizonStaking.target, + ) + const subgraphServiceTransactions = preparedTransactions.filter( + (tx: TransactionRequest) => tx.to === this.network.contracts.SubgraphService.target, ) + + // -- STAKING CONTRACT -- + const callDataStakingContract = stakingTransactions + .filter((tx: TransactionRequest) => !!tx.data) + .map((tx) => tx.data as string) + + logger.debug('Found staking contract transactions', { + count: callDataStakingContract.length, + }) + logger.trace('Prepared staking contract transaction calldata', { + callDataStakingContract, + }) + + if (callDataStakingContract.length > 0) { + try { + const stakingTransactionResult = + await this.network.transactionManager.executeTransaction( + async () => + this.network.contracts.HorizonStaking.multicall.estimateGas( + callDataStakingContract, + ), + async (gasLimit) => + this.network.contracts.HorizonStaking.multicall(callDataStakingContract, { + gasLimit, + }), + this.logger.child({ + actions: `${JSON.stringify(validatedActions.map((action) => action.id))}`, + function: 'staking.multicall', + }), + ) + + // Mark all actions with staking contract transactions as successful + for (const transaction of stakingTransactions) { + actionResults.push({ + actionID: transaction.actionID, + success: true, + result: stakingTransactionResult, + }) + } + } catch (error) { + logger.error('Failed to execute staking contract transaction', { error }) + + // Mark all actions with staking contract transactions as failed + for (const transaction of stakingTransactions) { + actionResults.push({ + actionID: transaction.actionID, + success: false, + result: { + actionID: transaction.actionID, + failureReason: `Failed to execute staking contract transaction: ${error.message}`, + protocolNetwork: transaction.protocolNetwork, + }, + }) + } + } + } + + // -- SUBGRAPH SERVICE -- + const callDataSubgraphService = subgraphServiceTransactions + // Reallocate of a legacy allocation during the transition period can result in + // a staking and subgraph service transaction in the same batch. If the staking tx failed we + // should not execute the subgraph service tx. + .filter((tx: ActionTransactionRequest) => { + const actionStakingTransaction = actionResults.find( + (result) => result.actionID === tx.actionID, + ) + return ( + actionStakingTransaction === undefined || + actionStakingTransaction.success === true + ) + }) + .filter((tx: TransactionRequest) => !!tx.data) + .map((tx) => tx.data as string) + logger.debug('Found subgraph service transactions', { + count: callDataSubgraphService.length, + }) + logger.trace('Prepared subgraph service transaction calldata', { + callDataSubgraphService, + }) + + if (callDataSubgraphService.length > 0) { + try { + const subgraphServiceTransactionResult = + await this.network.transactionManager.executeTransaction( + async () => + this.network.contracts.SubgraphService.multicall.estimateGas( + callDataSubgraphService, + ), + async (gasLimit) => + this.network.contracts.SubgraphService.multicall(callDataSubgraphService, { + gasLimit, + }), + this.logger.child({ + actions: `${JSON.stringify(validatedActions.map((action) => action.id))}`, + function: 'subgraphService.multicall', + }), + ) + + // Mark all actions with subgraph service transactions as successful + for (const transaction of subgraphServiceTransactions) { + actionResults.push({ + actionID: transaction.actionID, + success: true, + result: subgraphServiceTransactionResult, + }) + } + } catch (error) { + logger.error('Failed to execute subgraph service transaction', { error }) + + // Mark all actions with subgraph service transactions as failed + for (const transaction of subgraphServiceTransactions) { + actionResults.push({ + actionID: transaction.actionID, + success: false, + result: { + actionID: transaction.actionID, + failureReason: `Failed to execute subgraph service transaction: ${error.message}`, + protocolNetwork: transaction.protocolNetwork, + }, + }) + } + } + } + + // sanity check that all actions have a result + if (actionResults.length !== actions.length) { + logger.error('Inconsistent number of action results', { + actionResults: actionResults.length, + actions: actions.length, + }) + } + + return actionResults } async confirmTransactions( - receipt: ContractReceipt | 'paused' | 'unauthorized', + transactionResults: ExecuteTransactionResult[], actions: Action[], ): Promise { const logger = this.logger.child({ function: 'confirmTransactions', - receipt, - actions, + transactionResults, }) - logger.trace('Confirming transaction') + logger.trace('Confirming transactions') + return pMap( - actions, - async (action: Action) => { + transactionResults, + async (transactionResult: ExecuteTransactionResult) => { + const action = actions.find((action) => action.id === transactionResult.actionID) + if (action === undefined) { + this.logger.error('No action found for transaction result', { + transactionResult, + }) + throw new Error('No action found for transaction result') + } + + if (isActionFailure(transactionResult.result)) { + logger.debug('Execute batch transaction failed', { + actionBatchResult: transactionResult, + reason: transactionResult.result.failureReason, + }) + return transactionResult.result + } + + if ( + transactionResult.result === 'paused' || + transactionResult.result === 'unauthorized' + ) { + logger.debug('Execute batch transaction failed', { + actionBatchResult: transactionResult, + reason: transactionResult.result, + }) + return { + actionID: transactionResult.actionID, + transactionID: undefined, + failureReason: transactionResult.result, + protocolNetwork: action.protocolNetwork, + } + } + + const receipt = transactionResult.result + try { + if (receipt === undefined) { + this.logger.error('No receipt found for action', { + action: transactionResult.actionID, + }) + throw new Error('No receipt found for action') + } + return await this.confirmActionExecution(receipt, action) } catch (error) { let transaction: string | undefined = undefined if (typeof receipt == 'object') { - transaction = receipt.transactionHash ?? undefined + transaction = receipt.hash ?? undefined } this.logger.error('Failed to confirm batch transaction', { error, @@ -207,7 +416,7 @@ export class AllocationManager { } async confirmActionExecution( - receipt: ContractReceipt | 'paused' | 'unauthorized', + receipt: TransactionReceipt | 'paused' | 'unauthorized', action: Action, ): Promise { // Ensure we are handling an action for the same configured network @@ -247,14 +456,14 @@ export class AllocationManager { } async prepareTransactions(actions: Action[]): Promise { - const currentEpoch = await this.network.contracts.epochManager.currentEpoch() + const currentEpoch = await this.network.contracts.EpochManager.currentEpoch() const context: TransactionPreparationContext = { activeAllocations: await this.network.networkMonitor.allocations( AllocationStatus.ACTIVE, ), recentlyClosedAllocations: await this.network.networkMonitor.recentlyClosedAllocations( - currentEpoch.toNumber(), + Number(currentEpoch), 2, ), currentEpoch, @@ -289,6 +498,8 @@ export class AllocationManager { new SubgraphDeploymentID(action.deploymentID!), // eslint-disable-next-line @typescript-eslint/no-non-null-assertion parseGRT(action.amount!), + action.id, + action.protocolNetwork, ) case ActionType.UNALLOCATE: return await this.prepareUnallocate( @@ -298,6 +509,10 @@ export class AllocationManager { action.allocationID!, action.poi === null ? undefined : action.poi, action.force === null ? false : action.force, + action.poiBlockNumber === null ? undefined : action.poiBlockNumber, + action.publicPOI === null ? undefined : action.publicPOI, + action.id, + action.protocolNetwork, ) case ActionType.REALLOCATE: return await this.prepareReallocate( @@ -309,6 +524,10 @@ export class AllocationManager { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion parseGRT(action.amount!), action.force === null ? false : action.force, + action.poiBlockNumber === null ? undefined : action.poiBlockNumber, + action.publicPOI === null ? undefined : action.publicPOI, + action.id, + action.protocolNetwork, ) } } catch (error) { @@ -354,7 +573,7 @@ export class AllocationManager { logger: Logger, context: TransactionPreparationContext, deployment: SubgraphDeploymentID, - amount: BigNumber, + amount: bigint, ): Promise { logger.info('Preparing to allocate', { deployment: deployment.ipfsHash, @@ -376,7 +595,7 @@ export class AllocationManager { ) } - if (amount.lt('0')) { + if (amount < 0n) { logger.warn('Cannot allocate a negative amount of GRT', { amount: amount.toString(), }) @@ -405,25 +624,42 @@ export class AllocationManager { ...context.activeAllocations, ] const { allocationSigner, allocationId } = uniqueAllocationID( - this.network.transactionManager.wallet.mnemonic.phrase, - context.currentEpoch.toNumber(), + this.network.transactionManager.wallet.mnemonic!.phrase, + Number(context.currentEpoch), deployment, activeAndRecentlyClosedAllocations.map((allocation) => allocation.id), ) + logger.debug('New unique Allocation ID generated', { + newAllocationID: allocationId, + newAllocationSigner: allocationSigner, + }) + // Double-check whether the allocationID already exists on chain, to // avoid unnecessary transactions. - // Note: We're checking the allocation state here, which is defined as - // - // enum AllocationState { Null, Active, Closed, Finalized, Claimed } - // - // in the contracts. - const state = await this.network.contracts.staking.getAllocationState(allocationId) - if (state !== 0) { + let allocationExistsSubgraphService = false + let allocationExistsStaking = false + const isHorizon = await this.network.isHorizon.value() + if (isHorizon) { + const allocation = + await this.network.contracts.SubgraphService.getAllocation(allocationId) + const legacyAllocation = + await this.network.contracts.SubgraphService.getLegacyAllocation(allocationId) + allocationExistsSubgraphService = allocation.createdAt !== 0n + allocationExistsStaking = legacyAllocation.indexer !== ZeroAddress + } else { + const state = + await this.network.contracts.LegacyStaking.getAllocationState(allocationId) + allocationExistsStaking = state !== 0n + } + + if (allocationExistsSubgraphService || allocationExistsStaking) { logger.debug(`Skipping allocation as it already exists onchain`, { indexer: this.network.specification.indexerOptions.address, allocation: allocationId, - state, + isHorizon, + allocationExistsSubgraphService, + allocationExistsStaking, }) throw indexerError( IndexerErrorCode.IE066, @@ -437,14 +673,23 @@ export class AllocationManager { indexerAddress: this.network.specification.indexerOptions.address, }) - const proof = await allocationIdProof( - allocationSigner, - this.network.specification.indexerOptions.address, - allocationId, - ) + const proof = isHorizon + ? await horizonAllocationIdProof( + allocationSigner, + Number(this.network.specification.networkIdentifier.split(':')[1]), + this.network.specification.indexerOptions.address, + allocationId, + this.network.contracts.SubgraphService.target.toString(), + ) + : await legacyAllocationIdProof( + allocationSigner, + this.network.specification.indexerOptions.address, + allocationId, + ) logger.debug('Successfully generated allocation ID proof', { allocationIDProof: proof, + isLegacy: !isHorizon, }) return { @@ -452,7 +697,7 @@ export class AllocationManager { subgraphDeploymentID: deployment.bytes32, tokens: amount, allocationID: allocationId, - metadata: utils.hexlify(Array(32).fill(0)), + metadata: hexlify(new Uint8Array(32).fill(0)), proof, } } @@ -461,11 +706,15 @@ export class AllocationManager { actionID: number, deployment: string, amount: string, - receipt: ContractReceipt | 'paused' | 'unauthorized', + receipt: TransactionReceipt | 'paused' | 'unauthorized', ): Promise { const logger = this.logger.child({ action: actionID }) const subgraphDeployment = new SubgraphDeploymentID(deployment) - logger.info(`Confirming 'allocateFrom' transaction`) + const isLegacy = + (receipt as TransactionReceipt).to === this.network.contracts.HorizonStaking.target + logger.info(`Confirming allocation creation transaction`, { + isLegacy, + }) if (receipt === 'paused' || receipt === 'unauthorized') { throw indexerError( IndexerErrorCode.IE062, @@ -476,14 +725,23 @@ export class AllocationManager { ) } - const createAllocationEventLogs = this.network.transactionManager.findEvent( - 'AllocationCreated', - this.network.contracts.staking.interface, - 'subgraphDeploymentID', - subgraphDeployment.bytes32, - receipt, - this.logger, - ) + const createAllocationEventLogs = isLegacy + ? this.network.transactionManager.findEvent( + 'AllocationCreated', + this.network.contracts.LegacyStaking.interface, + 'subgraphDeploymentID', + subgraphDeployment.bytes32, + receipt, + this.logger, + ) + : this.network.transactionManager.findEvent( + 'AllocationCreated', + this.network.contracts.SubgraphService.interface, + 'indexer', + this.network.specification.indexerOptions.address, + receipt, + logger, + ) if (!createAllocationEventLogs) { throw indexerError(IndexerErrorCode.IE014, `Allocation was never mined`) @@ -491,17 +749,16 @@ export class AllocationManager { logger.info(`Successfully allocated to subgraph deployment`, { amountGRT: formatGRT(createAllocationEventLogs.tokens), - allocation: createAllocationEventLogs.allocationID, + allocation: isLegacy + ? createAllocationEventLogs.allocationID + : createAllocationEventLogs.allocationId, deployment: createAllocationEventLogs.subgraphDeploymentID, - epoch: createAllocationEventLogs.epoch.toString(), + epoch: isLegacy + ? createAllocationEventLogs.epoch.toString() + : createAllocationEventLogs.currentEpoch.toString(), + isLegacy, }) - // TODO: deprecated - // Remember allocation - await this.network.receiptCollector?.rememberAllocations(actionID, [ - createAllocationEventLogs.allocationID, - ]) - const subgraphDeploymentID = new SubgraphDeploymentID(deployment) // If there is not yet an indexingRule that deems this deployment worth allocating to, make one if (!(await this.matchingRuleExists(logger, subgraphDeploymentID))) { @@ -519,12 +776,22 @@ export class AllocationManager { await upsertIndexingRule(logger, this.models, indexingRule) } + if (this.dipsManager) { + await this.dipsManager.tryUpdateAgreementAllocation( + deployment, + null, + toAddress(createAllocationEventLogs.allocationID), + ) + } + return { actionID, type: 'allocate', - transactionID: receipt.transactionHash, + transactionID: receipt.hash, deployment: deployment, - allocation: createAllocationEventLogs.allocationID, + allocation: isLegacy + ? createAllocationEventLogs.allocationID + : createAllocationEventLogs.allocationId, allocatedTokens: amount, protocolNetwork: this.network.specification.networkIdentifier, } @@ -534,24 +801,50 @@ export class AllocationManager { logger: Logger, context: TransactionPreparationContext, deployment: SubgraphDeploymentID, - amount: BigNumber, - ): Promise { + amount: bigint, + actionID: number, + protocolNetwork: string, + ): Promise { + const isHorizon = await this.network.isHorizon.value() const params = await this.prepareAllocateParams(logger, context, deployment, amount) - logger.debug(`Populating allocateFrom transaction`, { + logger.debug(`Populating allocation creation transaction`, { indexer: params.indexer, subgraphDeployment: params.subgraphDeploymentID, amount: formatGRT(params.tokens), allocation: params.allocationID, proof: params.proof, + isLegacy: !isHorizon, }) - return await this.network.contracts.staking.populateTransaction.allocateFrom( - params.indexer, - params.subgraphDeploymentID, - params.tokens, - params.allocationID, - params.metadata, - params.proof, - ) + + let populatedTransaction: ContractTransaction + if (isHorizon) { + const encodedData = encodeStartServiceData( + params.subgraphDeploymentID.toString(), + BigInt(params.tokens), + params.allocationID, + params.proof.toString(), + ) + populatedTransaction = + await this.network.contracts.SubgraphService.startService.populateTransaction( + params.indexer, + encodedData, + ) + } else { + populatedTransaction = + await this.network.contracts.LegacyStaking.allocateFrom.populateTransaction( + params.indexer, + params.subgraphDeploymentID, + params.tokens, + params.allocationID, + params.metadata, + params.proof, + ) + } + return { + protocolNetwork, + actionID, + ...populatedTransaction, + } } async prepareUnallocateParams( @@ -560,41 +853,67 @@ export class AllocationManager { allocationID: string, poi: string | undefined, force: boolean, + poiBlockNumber: number | undefined, + publicPOI: string | undefined, + actionID: number, + protocolNetwork: string, ): Promise { - logger.info('Preparing to close allocation (unallocate)', { + logger.info('Preparing to unallocate', { allocationID: allocationID, poi: poi || 'none provided', + publicPOI: publicPOI || 'none provided', + poiBlockNumber: poiBlockNumber || 'none provided', }) const allocation = await this.network.networkMonitor.allocation(allocationID) - poi = await this.network.networkMonitor.resolvePOI(allocation, poi, force) + const poiData = await this.network.networkMonitor.resolvePOI( + allocation, + poi, + publicPOI, + poiBlockNumber, + force, + ) // Double-check whether the allocation is still active on chain, to // avoid unnecessary transactions. - // Note: We're checking the allocation state here, which is defined as - // - // enum AllocationState { Null, Active, Closed, Finalized, Claimed } - // - // in the contracts. - const state = await this.network.contracts.staking.getAllocationState(allocation.id) - if (state !== 1) { - throw indexerError(IndexerErrorCode.IE065) + if (allocation.isLegacy) { + const state = await this.network.contracts.HorizonStaking.getAllocationState( + allocation.id, + ) + if (state !== 1n) { + throw indexerError(IndexerErrorCode.IE065) + } + } else { + const allocation = + await this.network.contracts.SubgraphService.getAllocation(allocationID) + if (allocation.closedAt !== 0n) { + throw indexerError(IndexerErrorCode.IE065) + } } return { + protocolNetwork, + actionID, allocationID: allocation.id, - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - poi: poi!, + poi: poiData, + isLegacy: allocation.isLegacy, + indexer: allocation.indexer, } } async confirmUnallocate( actionID: number, allocationID: string, - receipt: ContractReceipt | 'paused' | 'unauthorized', + receipt: TransactionReceipt | 'paused' | 'unauthorized', ): Promise { const logger = this.logger.child({ action: actionID }) - logger.info(`Confirming 'closeAllocation' transaction`) + const isLegacy = + (receipt as TransactionReceipt).to === this.network.contracts.HorizonStaking.target + const isHorizon = await this.network.isHorizon.value() + + logger.info(`Confirming unallocate transaction`, { + isLegacy, + }) if (receipt === 'paused' || receipt === 'unauthorized') { throw indexerError( @@ -603,14 +922,23 @@ export class AllocationManager { ) } - const closeAllocationEventLogs = this.network.transactionManager.findEvent( - 'AllocationClosed', - this.network.contracts.staking.interface, - 'allocationID', - allocationID, - receipt, - this.logger, - ) + const closeAllocationEventLogs = isLegacy + ? this.network.transactionManager.findEvent( + 'AllocationClosed', + this.network.contracts.LegacyStaking.interface, + 'allocationID', + allocationID, + receipt, + this.logger, + ) + : this.network.transactionManager.findEvent( + 'AllocationClosed', + this.network.contracts.SubgraphService.interface, + 'allocationId', + allocationID, + receipt, + this.logger, + ) if (!closeAllocationEventLogs) { throw indexerError( @@ -619,48 +947,53 @@ export class AllocationManager { ) } - const rewardsEventLogs = this.network.transactionManager.findEvent( - 'RewardsAssigned', - this.network.contracts.rewardsManager.interface, - 'allocationID', - allocationID, - receipt, - this.logger, - ) + const rewardsEventLogs = isLegacy + ? this.network.transactionManager.findEvent( + isHorizon ? 'HorizonRewardsAssigned' : 'RewardsAssigned', + this.network.contracts.RewardsManager.interface, + 'allocationID', + allocationID, + receipt, + this.logger, + ) + : this.network.transactionManager.findEvent( + 'IndexingRewardsCollected', + this.network.contracts.SubgraphService.interface, + 'allocationId', + allocationID, + receipt, + this.logger, + ) - const rewardsAssigned = rewardsEventLogs ? rewardsEventLogs.amount : 0 + const rewardsAssigned = rewardsEventLogs + ? isLegacy + ? rewardsEventLogs.amount + : rewardsEventLogs.tokensIndexerRewards + : 0 if (rewardsAssigned == 0) { logger.warn('No rewards were distributed upon closing the allocation') } const subgraphDeploymentID = new SubgraphDeploymentID( - closeAllocationEventLogs.subgraphDeploymentID, + isLegacy + ? closeAllocationEventLogs.subgraphDeploymentID + : closeAllocationEventLogs.subgraphDeploymentId, ) logger.info(`Successfully closed allocation`, { deployment: subgraphDeploymentID.display, - allocation: closeAllocationEventLogs.allocationID, + allocation: allocationID, indexer: closeAllocationEventLogs.indexer, amountGRT: formatGRT(closeAllocationEventLogs.tokens), - poi: closeAllocationEventLogs.poi, - transaction: receipt.transactionHash, + transaction: receipt.hash, indexingRewards: rewardsAssigned, }) logger.info('Identifying receipts worth collecting', { - allocation: closeAllocationEventLogs.allocationID, + allocation: allocationID, }) - let isCollectingQueryFees = false const allocation = await this.network.networkMonitor.allocation(allocationID) - if (this.network.receiptCollector) { - // TODO: deprecated - // Collect query fees for this allocation - isCollectingQueryFees = await this.network.receiptCollector.collectReceipts( - actionID, - allocation, - ) - } // Upsert a rule so the agent keeps the deployment synced but doesn't allocate to it logger.debug( @@ -675,14 +1008,22 @@ export class AllocationManager { await upsertIndexingRule(logger, this.models, neverIndexingRule) + if (this.dipsManager) { + await this.dipsManager.tryCancelAgreement(allocationID) + await this.dipsManager.tryUpdateAgreementAllocation( + allocation.subgraphDeployment.id.toString(), + toAddress(allocationID), + null, + ) + } + return { actionID, type: 'unallocate', - transactionID: receipt.transactionHash, - allocation: closeAllocationEventLogs.allocationID, + transactionID: receipt.hash, + allocation: allocationID, allocatedTokens: formatGRT(closeAllocationEventLogs.tokens), indexingRewards: formatGRT(rewardsAssigned), - receiptsWorthCollecting: isCollectingQueryFees, protocolNetwork: this.network.specification.networkIdentifier, } } @@ -690,15 +1031,63 @@ export class AllocationManager { async populateUnallocateTransaction( logger: Logger, params: UnallocateTransactionParams, - ): Promise { - logger.debug(`Populating closeAllocation transaction`, { + ): Promise { + logger.debug(`Populating unallocate transaction`, { allocationID: params.allocationID, - POI: params.poi, + poiData: params.poi, }) - return await this.network.contracts.staking.populateTransaction.closeAllocation( - params.allocationID, - params.poi, - ) + + if (params.isLegacy) { + const tx = + await this.network.contracts.HorizonStaking.closeAllocation.populateTransaction( + params.allocationID, + params.poi.poi, + ) + return { + protocolNetwork: params.protocolNetwork, + actionID: params.actionID, + ...tx, + } + } else { + // Horizon: Need to multicall collect and stopService + + // collect + const collectIndexingRewardsData = encodeCollectIndexingRewardsData( + params.allocationID, + params.poi.poi, + encodePOIMetadata( + params.poi.blockNumber, + params.poi.publicPOI, + params.poi.indexingStatus, + 0, + 0, + ), + ) + const collectCallData = + this.network.contracts.SubgraphService.interface.encodeFunctionData('collect', [ + params.indexer, + PaymentTypes.IndexingRewards, + collectIndexingRewardsData, + ]) + + // stopService + const stopServiceCallData = + this.network.contracts.SubgraphService.interface.encodeFunctionData( + 'stopService', + [params.indexer, encodeStopServiceData(params.allocationID)], + ) + + const tx = + await this.network.contracts.SubgraphService.multicall.populateTransaction([ + collectCallData, + stopServiceCallData, + ]) + return { + protocolNetwork: params.protocolNetwork, + actionID: params.actionID, + ...tx, + } + } } async prepareUnallocate( @@ -707,13 +1096,21 @@ export class AllocationManager { allocationID: string, poi: string | undefined, force: boolean, - ): Promise { + poiBlockNumber: number | undefined, + publicPOI: string | undefined, + actionID: number, + protocolNetwork: string, + ): Promise { const params = await this.prepareUnallocateParams( logger, context, allocationID, poi, force, + poiBlockNumber, + publicPOI, + actionID, + protocolNetwork, ) return await this.populateUnallocateTransaction(logger, params) } @@ -723,12 +1120,18 @@ export class AllocationManager { context: TransactionPreparationContext, allocationID: string, poi: string | undefined, - amount: BigNumber, + amount: bigint, force: boolean, + poiBlockNumber: number | undefined, + publicPOI: string | undefined, + actionID: number, + protocolNetwork: string, ): Promise { logger.info('Preparing to reallocate', { allocation: allocationID, poi: poi || 'none provided', + publicPOI: publicPOI || 'none provided', + poiBlockNumber: poiBlockNumber || 'none provided', amount: amount.toString(), force, }) @@ -750,31 +1153,47 @@ export class AllocationManager { allocation: allocationID, deployment: allocation.subgraphDeployment.id.ipfsHash, }) - const allocationPOI = await this.network.networkMonitor.resolvePOI( + const poiData = await this.network.networkMonitor.resolvePOI( allocation, poi, + publicPOI, + poiBlockNumber, force, ) logger.debug('POI resolved', { deployment: allocation.subgraphDeployment.id.ipfsHash, userProvidedPOI: poi, - poi: allocationPOI, + userProvidedPublicPOI: publicPOI, + userProvidedBlockNumber: poiBlockNumber, + poi: poiData.poi, + publicPOI: poiData.publicPOI, + blockNumber: poiData.blockNumber, + force, }) // Double-check whether the allocation is still active on chain, to // avoid unnecessary transactions. - // Note: We're checking the allocation state here, which is defined as - // - // enum AllocationState { Null, Active, Closed, Finalized, Claimed } - // - // in the this.contracts. - const state = await this.network.contracts.staking.getAllocationState(allocation.id) - if (state !== 1) { - logger.warn(`Allocation has already been closed`) - throw indexerError(IndexerErrorCode.IE065, `Allocation has already been closed`) + if (allocation.isLegacy) { + const state = await this.network.contracts.HorizonStaking.getAllocationState( + allocation.id, + ) + if (state !== 1n) { + logger.warn(`Allocation has already been closed`) + throw indexerError( + IndexerErrorCode.IE065, + `Legacy allocation has already been closed`, + ) + } + } else { + const allocationData = + await this.network.contracts.SubgraphService.getAllocation(allocationID) + if (allocationData.closedAt !== 0n) { + logger.warn(`Allocation has already been closed`) + throw indexerError(IndexerErrorCode.IE065, `Allocation has already been closed`) + } } - if (amount.lt('0')) { + if (amount < 0n) { logger.warn('Cannot reallocate a negative amount of GRT', { amount: amount.toString(), }) @@ -785,11 +1204,15 @@ export class AllocationManager { } logger.debug('Generating a new unique Allocation ID') + const activeAndRecentlyClosedAllocations: Allocation[] = [ + ...context.recentlyClosedAllocations, + ...context.activeAllocations, + ] const { allocationSigner, allocationId: newAllocationId } = uniqueAllocationID( - this.network.transactionManager.wallet.mnemonic.phrase, - context.currentEpoch.toNumber(), + this.network.transactionManager.wallet.mnemonic!.phrase, + Number(context.currentEpoch), allocation.subgraphDeployment.id, - context.activeAllocations.map((allocation) => allocation.id), + activeAndRecentlyClosedAllocations.map((allo) => allo.id), ) logger.debug('New unique Allocation ID generated', { @@ -799,34 +1222,56 @@ export class AllocationManager { // Double-check whether the allocationID already exists on chain, to // avoid unnecessary transactions. - // Note: We're checking the allocation state here, which is defined as - // - // enum AllocationState { Null, Active, Closed, Finalized, Claimed } - // - // in the this.contracts. - const newAllocationState = - await this.network.contracts.staking.getAllocationState(newAllocationId) - if (newAllocationState !== 0) { - logger.warn(`Skipping Allocation as it already exists onchain`, { - indexer: this.network.specification.indexerOptions.address, - allocation: newAllocationId, - newAllocationState, - }) - throw indexerError(IndexerErrorCode.IE066, 'AllocationID already exists') + const isHorizon = await this.network.isHorizon.value() + if (isHorizon) { + const allocationData = + await this.network.contracts.SubgraphService.getAllocation(newAllocationId) + if (allocationData.createdAt !== 0n) { + logger.warn(`Skipping allocation as it already exists onchain`, { + indexer: this.network.specification.indexerOptions.address, + allocation: newAllocationId, + allocationData, + isHorizon, + }) + throw indexerError(IndexerErrorCode.IE066, 'AllocationID already exists') + } + } else { + const newAllocationState = + await this.network.contracts.HorizonStaking.getAllocationState(newAllocationId) + if (newAllocationState !== 0n) { + logger.warn(`Skipping allocation as it already exists onchain (legacy)`, { + indexer: this.network.specification.indexerOptions.address, + allocation: newAllocationId, + newAllocationState, + isHorizon, + }) + throw indexerError(IndexerErrorCode.IE066, 'Legacy AllocationID already exists') + } } logger.debug('Generating new allocation ID proof', { newAllocationSigner: allocationSigner, newAllocationID: newAllocationId, indexerAddress: this.network.specification.indexerOptions.address, + isHorizon, }) - const proof = await allocationIdProof( - allocationSigner, - this.network.specification.indexerOptions.address, - newAllocationId, - ) + const proof = isHorizon + ? await horizonAllocationIdProof( + allocationSigner, + Number(this.network.specification.networkIdentifier.split(':')[1]), + this.network.specification.indexerOptions.address, + newAllocationId, + this.network.contracts.SubgraphService.target.toString(), + ) + : await legacyAllocationIdProof( + allocationSigner, + this.network.specification.indexerOptions.address, + newAllocationId, + ) + logger.debug('Successfully generated allocation ID proof', { allocationIDProof: proof, + isHorizon, }) logger.info(`Prepared close and allocate multicall transaction`, { @@ -836,32 +1281,44 @@ export class AllocationManager { newAllocation: newAllocationId, newAllocationAmount: formatGRT(amount), deployment: allocation.subgraphDeployment.id.toString(), - poi: allocationPOI, + poi: poiData, proof, epoch: context.currentEpoch.toString(), }) return { closingAllocationID: allocation.id, - poi: allocationPOI, + closingAllocationIsLegacy: allocation.isLegacy, + poi: poiData, indexer: this.network.specification.indexerOptions.address, subgraphDeploymentID: allocation.subgraphDeployment.id.bytes32, tokens: amount, newAllocationID: newAllocationId, - metadata: utils.hexlify(Array(32).fill(0)), + metadata: hexlify(new Uint8Array(32).fill(0)), proof, + actionID, + protocolNetwork, } } async confirmReallocate( actionID: number, allocationID: string, - receipt: ContractReceipt | 'paused' | 'unauthorized', + receipt: TransactionReceipt | 'paused' | 'unauthorized', ): Promise { const logger = this.logger.child({ action: actionID }) - logger.info(`Confirming close and allocate 'multicall' transaction`, { + const isHorizon = await this.network.isHorizon.value() + + // This could be a tx to the staking contract or the subgraph service contract + const isStakingContract = + (receipt as TransactionReceipt).to === this.network.contracts.HorizonStaking.target + + logger.info(`Confirming reallocate transaction`, { allocationID, + isHorizon, + isStakingContract, }) + if (receipt === 'paused' || receipt === 'unauthorized') { throw indexerError( IndexerErrorCode.IE062, @@ -869,94 +1326,137 @@ export class AllocationManager { ) } - const closeAllocationEventLogs = this.network.transactionManager.findEvent( - 'AllocationClosed', - this.network.contracts.staking.interface, - 'allocationID', - allocationID, - receipt, - this.logger, - ) + let closeAllocationEventLogs + let createAllocationEventLogs + let subgraphDeploymentID + let rewardsAssigned + + if (isStakingContract) { + // tx to the staking contract can be one of the following: + // - closeAllocation for a legacy allocation + // - allocateFrom for a legacy allocation before horizon + + closeAllocationEventLogs = this.network.transactionManager.findEvent( + 'AllocationClosed', + this.network.contracts.LegacyStaking.interface, + 'allocationID', + allocationID, + receipt, + this.logger, + ) - if (!closeAllocationEventLogs) { - throw indexerError( - IndexerErrorCode.IE015, - `Allocation close transaction was never successfully mined`, + if (!closeAllocationEventLogs) { + throw indexerError( + IndexerErrorCode.IE015, + `Legacy allocation close transaction was never successfully mined`, + ) + } + + if (!isHorizon) { + createAllocationEventLogs = this.network.transactionManager.findEvent( + 'AllocationCreated', + this.network.contracts.LegacyStaking.interface, + 'subgraphDeploymentID', + closeAllocationEventLogs.subgraphDeploymentID, + receipt, + this.logger, + ) + + if (!createAllocationEventLogs) { + throw indexerError( + IndexerErrorCode.IE014, + `Legacy allocation create transaction was never mined`, + ) + } + } + + const rewardsEventLogs = this.network.transactionManager.findEvent( + isHorizon ? 'HorizonRewardsAssigned' : 'RewardsAssigned', + this.network.contracts.RewardsManager.interface, + 'allocationID', + allocationID, + receipt, + this.logger, ) - } - const createAllocationEventLogs = this.network.transactionManager.findEvent( - 'AllocationCreated', - this.network.contracts.staking.interface, - 'subgraphDeploymentID', - closeAllocationEventLogs.subgraphDeploymentID, - receipt, - this.logger, - ) + rewardsAssigned = rewardsEventLogs ? rewardsEventLogs.amount : 0 - if (!createAllocationEventLogs) { - throw indexerError( - IndexerErrorCode.IE014, - `Allocation create transaction was never mined`, + if (rewardsAssigned == 0) { + logger.warn('No rewards were distributed upon closing the legacy allocation') + } + + subgraphDeploymentID = new SubgraphDeploymentID( + closeAllocationEventLogs.subgraphDeploymentID, + ) + } else { + // tx to the subgraph service contract can be one of the following: + // - collect + stopService for a new allocation + // - startService for a new allocation + + closeAllocationEventLogs = this.network.transactionManager.findEvent( + 'AllocationClosed', + this.network.contracts.SubgraphService.interface, + 'allocationId', + allocationID, + receipt, + this.logger, ) - } - const rewardsEventLogs = this.network.transactionManager.findEvent( - 'RewardsAssigned', - this.network.contracts.rewardsManager.interface, - 'allocationID', - allocationID, - receipt, - this.logger, - ) + if (!closeAllocationEventLogs) { + throw indexerError( + IndexerErrorCode.IE015, + `Allocation close transaction was never successfully mined`, + ) + } - const rewardsAssigned = rewardsEventLogs ? rewardsEventLogs.amount : 0 + const rewardsEventLogs = this.network.transactionManager.findEvent( + 'IndexingRewardsCollected', + this.network.contracts.SubgraphService.interface, + 'allocationId', + allocationID, + receipt, + this.logger, + ) - if (rewardsAssigned == 0) { - logger.warn('No rewards were distributed upon closing the allocation') - } + rewardsAssigned = rewardsEventLogs ? rewardsEventLogs.tokensIndexerRewards : 0 - const subgraphDeploymentID = new SubgraphDeploymentID( - closeAllocationEventLogs.subgraphDeploymentID, - ) + if (rewardsAssigned == 0) { + logger.warn('No rewards were distributed upon closing the allocation') + } + + createAllocationEventLogs = this.network.transactionManager.findEvent( + 'AllocationCreated', + this.network.contracts.SubgraphService.interface, + 'indexer', + this.network.specification.indexerOptions.address, + receipt, + logger, + ) + + if (!createAllocationEventLogs) { + throw indexerError(IndexerErrorCode.IE014, `Allocation was never mined`) + } + + subgraphDeploymentID = new SubgraphDeploymentID( + closeAllocationEventLogs.subgraphDeploymentId, + ) + } logger.info(`Successfully reallocated to deployment`, { deployment: subgraphDeploymentID.display, - closedAllocation: closeAllocationEventLogs.allocationID, + closedAllocation: allocationID, closedAllocationStakeGRT: formatGRT(closeAllocationEventLogs.tokens), - closedAllocationPOI: closeAllocationEventLogs.poi, - closedAllocationEpoch: closeAllocationEventLogs.epoch.toString(), indexingRewardsCollected: formatGRT(rewardsAssigned), createdAllocation: createAllocationEventLogs.allocationID, createdAllocationStakeGRT: formatGRT(createAllocationEventLogs.tokens), indexer: createAllocationEventLogs.indexer, - epoch: createAllocationEventLogs.epoch.toString(), - transaction: receipt.transactionHash, + transaction: receipt.hash, }) logger.info('Identifying receipts worth collecting', { allocation: closeAllocationEventLogs.allocationID, }) - let allocation - let isCollectingQueryFees = false - try { - allocation = await this.network.networkMonitor.allocation(allocationID) - // Collect query fees for this allocation - - // TODO: deprecated - if (this.network.receiptCollector) { - isCollectingQueryFees = await this.network.receiptCollector.collectReceipts( - actionID, - allocation, - ) - logger.debug('Finished receipt collection') - } - } catch (err) { - logger.error('Failed to collect receipts', { - err, - }) - throw err - } + const allocation = await this.network.networkMonitor.allocation(allocationID) // If there is not yet an indexingRule that deems this deployment worth allocating to, make one if (!(await this.matchingRuleExists(logger, subgraphDeploymentID))) { @@ -974,13 +1474,20 @@ export class AllocationManager { await upsertIndexingRule(logger, this.models, indexingRule) } + if (this.dipsManager) { + await this.dipsManager.tryUpdateAgreementAllocation( + subgraphDeploymentID.toString(), + toAddress(allocationID), + toAddress(createAllocationEventLogs.allocationID), + ) + } + return { actionID, type: 'reallocate', - transactionID: receipt.transactionHash, + transactionID: receipt.hash, closedAllocation: closeAllocationEventLogs.allocationID, indexingRewardsCollected: formatGRT(rewardsAssigned), - receiptsWorthCollecting: isCollectingQueryFees, createdAllocation: createAllocationEventLogs.allocationID, createdAllocationStake: formatGRT(createAllocationEventLogs.tokens), protocolNetwork: this.network.specification.networkIdentifier, @@ -992,9 +1499,13 @@ export class AllocationManager { context: TransactionPreparationContext, allocationID: string, poi: string | undefined, - amount: BigNumber, + amount: bigint, force: boolean, - ): Promise { + poiBlockNumber: number | undefined, + publicPOI: string | undefined, + actionID: number, + protocolNetwork: string, + ): Promise { const params = await this.prepareReallocateParams( logger, context, @@ -1002,22 +1513,110 @@ export class AllocationManager { poi, amount, force, + poiBlockNumber, + publicPOI, + actionID, + protocolNetwork, ) - return [ - await this.network.contracts.staking.populateTransaction.closeAllocation( + return this.populateReallocateTransaction(logger, params) + } + + async populateReallocateTransaction( + logger: Logger, + params: ReallocateTransactionParams, + ): Promise { + logger.debug('Populating reallocate transaction', { + closingAllocationID: params.closingAllocationID, + poi: params.poi, + indexer: params.indexer, + subgraphDeploymentID: params.subgraphDeploymentID, + tokens: params.tokens, + newAllocationID: params.newAllocationID, + metadata: params.metadata, + proof: params.proof, + }) + + const txs: TransactionRequest[] = [] + + // -- close allocation + if (params.closingAllocationIsLegacy) { + txs.push( + await this.network.contracts.LegacyStaking.closeAllocation.populateTransaction( + params.closingAllocationID, + params.poi.poi, + ), + ) + } else { + // Horizon: Need to multicall collect and stopService + + // collect + const collectIndexingRewardsData = encodeCollectIndexingRewardsData( params.closingAllocationID, - params.poi, - ), - await this.network.contracts.staking.populateTransaction.allocateFrom( - params.indexer, - params.subgraphDeploymentID, - params.tokens, + params.poi.poi, + encodePOIMetadata( + params.poi.blockNumber, + params.poi.publicPOI, + params.poi.indexingStatus, + 0, + 0, + ), + ) + const collectCallData = + this.network.contracts.SubgraphService.interface.encodeFunctionData('collect', [ + params.indexer, + PaymentTypes.IndexingRewards, + collectIndexingRewardsData, + ]) + + // stopService + const stopServiceCallData = + this.network.contracts.SubgraphService.interface.encodeFunctionData( + 'stopService', + [params.indexer, encodeStopServiceData(params.closingAllocationID)], + ) + + txs.push( + await this.network.contracts.SubgraphService.multicall.populateTransaction([ + collectCallData, + stopServiceCallData, + ]), + ) + } + + // -- create new allocation + const isHorizon = await this.network.isHorizon.value() + if (isHorizon) { + const encodedData = encodeStartServiceData( + params.subgraphDeploymentID.toString(), + BigInt(params.tokens), params.newAllocationID, - params.metadata, - params.proof, - ), - ] + params.proof.toString(), + ) + txs.push( + await this.network.contracts.SubgraphService.startService.populateTransaction( + params.indexer, + encodedData, + ), + ) + } else { + txs.push( + await this.network.contracts.LegacyStaking.allocateFrom.populateTransaction( + params.indexer, + params.subgraphDeploymentID, + params.tokens, + params.newAllocationID, + params.metadata, + params.proof, + ), + ) + } + + return txs.map((tx) => ({ + actionID: params.actionID, + protocolNetwork: params.protocolNetwork, + ...tx, + })) } async matchingRuleExists( @@ -1032,26 +1631,22 @@ export class AllocationManager { const subgraphDeployment = await this.network.networkMonitor.subgraphDeployment( subgraphDeploymentID.ipfsHash, ) - if (!subgraphDeployment) { - throw Error( - `SHOULD BE UNREACHABLE: No matching subgraphDeployment (${subgraphDeploymentID.ipfsHash}) found on the network`, - ) - } + return isDeploymentWorthAllocatingTowards(logger, subgraphDeployment, indexingRules) .toAllocate } // Calculates the balance (GRT delta) of a single Action. async stakeUsageSummary(action: Action): Promise { - let unallocates = BigNumber.from(0) - let rewards = BigNumber.from(0) + let unallocates = 0n + let rewards = 0n // Handle allocations let allocates if (action.amount) { allocates = parseGRT(action.amount) } else { - allocates = BigNumber.from(0) + allocates = 0n } // Handle unallocations. @@ -1070,16 +1665,19 @@ export class AllocationManager { const allocation = await this.network.networkMonitor.allocation(action.allocationID) // Accrue rewards, except for zeroed POI - const zeroHexString = utils.hexlify(Array(32).fill(0)) + const zeroHexString = hexlify(new Uint8Array(32).fill(0)) rewards = action.poi === zeroHexString - ? BigNumber.from(0) - : await this.network.contracts.rewardsManager.getRewards(action.allocationID) + ? 0n + : await this.network.contracts.RewardsManager.getRewards( + this.network.contracts.HorizonStaking.target, + action.allocationID, + ) - unallocates = unallocates.add(allocation.allocatedTokens) + unallocates = unallocates + allocation.allocatedTokens } - const balance = allocates.sub(unallocates).sub(rewards) + const balance = allocates - unallocates - rewards return { action, allocates, @@ -1093,20 +1691,27 @@ export class AllocationManager { const logger = this.logger.child({ function: 'validateActionBatch' }) logger.debug(`Validating action batch`, { size: batch.length }) - // Validate stake feasibility - const indexerFreeStake = await this.network.contracts.staking.getIndexerCapacity( - this.network.specification.indexerOptions.address, - ) + // Validate stake feasibility - we need to analyse stake depending on the action type + const indexerFreeStake = await this.network.networkMonitor.freeStake() + const actionsBatchStakeUsageSummaries = await pMap(batch, async (action: Action) => this.stakeUsageSummary(action), ) - const batchDelta: BigNumber = actionsBatchStakeUsageSummaries + const batchDeltaLegacy = actionsBatchStakeUsageSummaries + .filter((summary: ActionStakeUsageSummary) => summary.action.isLegacy) .map((summary: ActionStakeUsageSummary) => summary.balance) - .reduce((a: BigNumber, b: BigNumber) => a.add(b)) - const indexerNewBalance = indexerFreeStake.sub(batchDelta) + .reduce((a: bigint, b: bigint) => a + b, 0n) + const batchDelta = actionsBatchStakeUsageSummaries + .filter((summary: ActionStakeUsageSummary) => !summary.action.isLegacy) + .map((summary: ActionStakeUsageSummary) => summary.balance) + .reduce((a: bigint, b: bigint) => a + b, 0n) + + const indexerNewBalance = indexerFreeStake.horizon - batchDelta + const indexerNewBalanceLegacy = indexerFreeStake.legacy - batchDeltaLegacy logger.trace('Action batch stake usage summary', { indexerFreeStake: indexerFreeStake.toString(), + indexerFreeStakeLegacy: indexerFreeStake.legacy.toString(), actionsBatchStakeUsageSummaries: actionsBatchStakeUsageSummaries.map((summary) => { return { action: summary.action, @@ -1117,16 +1722,20 @@ export class AllocationManager { } }), batchDelta: batchDelta.toString(), + batchDeltaLegacy: batchDeltaLegacy.toString(), indexerNewBalance: indexerNewBalance.toString(), + indexerNewBalanceLegacy: indexerNewBalanceLegacy.toString(), }) - if (indexerNewBalance.isNegative()) { + if (indexerNewBalance < 0n || indexerNewBalanceLegacy < 0n) { { throw indexerError( IndexerErrorCode.IE013, `Unfeasible action batch: Approved action batch GRT balance is ` + - `${formatGRT(batchDelta)} ` + - `but available stake equals ${formatGRT(indexerFreeStake)}.`, + `${formatGRT(batchDelta)} for horizon actions and ` + + `${formatGRT(batchDeltaLegacy)} for legacy actions ` + + `but available horizon stake equals ${formatGRT(indexerFreeStake.horizon)} ` + + `and legacy stake equals ${formatGRT(indexerFreeStake.legacy)}.`, ) } } @@ -1136,7 +1745,7 @@ export class AllocationManager { * first and larger allocations are processed last */ return actionsBatchStakeUsageSummaries .sort((a: ActionStakeUsageSummary, b: ActionStakeUsageSummary) => - a.balance.gt(b.balance) ? 1 : -1, + a.balance > b.balance ? 1 : -1, ) .map((a: ActionStakeUsageSummary) => a.action) } diff --git a/packages/indexer-common/src/indexer-management/client.ts b/packages/indexer-common/src/indexer-management/client.ts index fba61436a..a7c30edd1 100644 --- a/packages/indexer-common/src/indexer-management/client.ts +++ b/packages/indexer-common/src/indexer-management/client.ts @@ -12,9 +12,14 @@ import costModelResolvers from './resolvers/cost-models' import indexingRuleResolvers from './resolvers/indexing-rules' import poiDisputeResolvers from './resolvers/poi-disputes' import statusResolvers from './resolvers/indexer-status' -import { BigNumber } from 'ethers' +import provisionResolvers from './resolvers/provisions' import { GraphNode } from '../graph-node' -import { ActionManager, MultiNetworks, Network } from '@graphprotocol/indexer-common' +import { + ActionManager, + MultiNetworks, + Network, + RulesManager, +} from '@graphprotocol/indexer-common' export interface IndexerManagementResolverContext { models: IndexerManagementModels @@ -22,6 +27,7 @@ export interface IndexerManagementResolverContext { logger: Logger defaults: IndexerManagementDefaults actionManager: ActionManager | undefined + rulesManager: RulesManager | undefined multiNetworks: MultiNetworks | undefined } @@ -38,6 +44,7 @@ const SCHEMA_SDL = gql` never always offchain + dips } enum IdentifierType { @@ -75,6 +82,7 @@ const SCHEMA_SDL = gql` stakedTokens: BigInt! status: AllocationStatus! protocolNetwork: String! + isLegacy: Boolean! } type CreateAllocationResult { @@ -88,14 +96,12 @@ const SCHEMA_SDL = gql` allocation: String! allocatedTokens: String! indexingRewards: String! - receiptsWorthCollecting: Boolean! protocolNetwork: String! } type ReallocateAllocationResult { closedAllocation: String! indexingRewardsCollected: String! - receiptsWorthCollecting: Boolean! createdAllocation: String! createdAllocationStake: String! protocolNetwork: String! @@ -125,6 +131,8 @@ const SCHEMA_SDL = gql` allocationID: String amount: String poi: String + publicPOI: String + poiBlockNumber: Int force: Boolean priority: Int! source: String! @@ -134,6 +142,7 @@ const SCHEMA_SDL = gql` createdAt: BigInt! updatedAt: BigInt protocolNetwork: String! + isLegacy: Boolean! } input ActionInput { @@ -143,19 +152,24 @@ const SCHEMA_SDL = gql` allocationID: String amount: String poi: String + publicPOI: String + poiBlockNumber: Int force: Boolean source: String! reason: String! priority: Int! protocolNetwork: String! + isLegacy: Boolean! } input ActionUpdateInput { id: Int deploymentID: String allocationID: String - amount: Int + amount: String poi: String + publicPOI: String + poiBlockNumber: Int force: Boolean type: ActionType status: ActionStatus @@ -171,6 +185,8 @@ const SCHEMA_SDL = gql` transaction amount poi + publicPOI + poiBlockNumber force source reason @@ -187,6 +203,8 @@ const SCHEMA_SDL = gql` allocationID: String amount: String poi: String + publicPOI: String + poiBlockNumber: Int force: Boolean source: String! reason: String! @@ -195,6 +213,7 @@ const SCHEMA_SDL = gql` failureReason: String priority: Int protocolNetwork: String! + isLegacy: Boolean! } input ActionFilter { @@ -299,6 +318,7 @@ const SCHEMA_SDL = gql` address: String registered: Boolean! location: GeoLocation + isLegacy: Boolean! } type IndexingError { @@ -344,10 +364,12 @@ const SCHEMA_SDL = gql` } type IndexerEndpoint { + name: String! url: String healthy: Boolean! protocolNetwork: String! tests: [IndexerEndpointTest!]! + isLegacy: Boolean! } type IndexerEndpoints { @@ -366,13 +388,65 @@ const SCHEMA_SDL = gql` model: String } + type Provision { + id: String! + dataService: String! + indexer: String! + tokensProvisioned: String! + tokensAllocated: String! + tokensThawing: String! + maxVerifierCut: String! + thawingPeriod: String! + protocolNetwork: String! + idleStake: String! + } + + type AddToProvisionResult { + id: String! + dataService: String! + indexer: String! + tokensProvisioned: String! + protocolNetwork: String! + } + + type ThawFromProvisionResult { + id: String! + dataService: String! + indexer: String! + tokensThawing: String! + thawingPeriod: String! + thawingUntil: String! + protocolNetwork: String! + } + + type ThawRequest { + id: String! + fulfilled: String! + dataService: String! + indexer: String! + shares: String! + thawingUntil: String! + protocolNetwork: String! + currentBlockTimestamp: String! + } + + type RemoveFromProvisionResult { + id: String! + dataService: String! + indexer: String! + tokensProvisioned: String! + tokensThawing: String! + tokensRemoved: String! + protocolNetwork: String! + } + type Query { indexingRule( identifier: IndexingRuleIdentifier! merged: Boolean! = false ): IndexingRule indexingRules(merged: Boolean! = false, protocolNetwork: String): [IndexingRule!]! - indexerRegistration(protocolNetwork: String!): IndexerRegistration! + indexerRegistration(protocolNetwork: String!): [IndexerRegistration]! indexerDeployments: [IndexerDeployment]! indexerAllocations(protocolNetwork: String!): [IndexerAllocation]! indexerEndpoints(protocolNetwork: String): [IndexerEndpoints!]! @@ -397,6 +471,9 @@ const SCHEMA_SDL = gql` orderDirection: OrderDirection first: Int ): [Action]! + + provisions(protocolNetwork: String!): [Provision!]! + thawRequests(protocolNetwork: String!): [ThawRequest!]! } type Mutation { @@ -419,12 +496,16 @@ const SCHEMA_SDL = gql` closeAllocation( allocation: String! poi: String + poiBlockNumber: Int + publicPOI: String force: Boolean protocolNetwork: String! ): CloseAllocationResult! reallocateAllocation( allocation: String! poi: String + poiBlockNumber: Int + publicPOI: String amount: String! force: Boolean protocolNetwork: String! @@ -438,6 +519,10 @@ const SCHEMA_SDL = gql` deleteActions(actionIDs: [String!]!): Int! approveActions(actionIDs: [String!]!): [Action]! executeApprovedActions: [ActionResult!]! + + addToProvision(protocolNetwork: String!, amount: String!): AddToProvisionResult! + thawFromProvision(protocolNetwork: String!, amount: String!): ThawFromProvisionResult! + removeFromProvision(protocolNetwork: String!): RemoveFromProvisionResult! } ` @@ -445,7 +530,7 @@ export interface IndexerManagementDefaults { globalIndexingRule: Omit< IndexingRuleCreationAttributes, 'identifier' | 'allocationAmount' - > & { allocationAmount: BigNumber } + > & { allocationAmount: bigint } } export interface IndexerManagementClientOptions { @@ -454,9 +539,11 @@ export interface IndexerManagementClientOptions { graphNode: GraphNode multiNetworks: MultiNetworks | undefined defaults: IndexerManagementDefaults + actionManager?: ActionManager | undefined } export class IndexerManagementClient extends Client { + declare actionManager: ActionManager | undefined private logger?: Logger private models: IndexerManagementModels @@ -465,6 +552,7 @@ export class IndexerManagementClient extends Client { this.logger = options.logger this.models = options.models + this.actionManager = options.actionManager } } @@ -482,12 +570,17 @@ export const createIndexerManagementClient = async ( ...poiDisputeResolvers, ...allocationResolvers, ...actionResolvers, + ...provisionResolvers, } const actionManager = multiNetworks ? await ActionManager.create(multiNetworks, logger, models, graphNode) : undefined + const rulesManager = multiNetworks + ? await RulesManager.create(multiNetworks, logger, models) + : undefined + const context: IndexerManagementResolverContext = { models, graphNode, @@ -495,6 +588,7 @@ export const createIndexerManagementClient = async ( logger: logger.child({ component: 'IndexerManagementClient' }), multiNetworks, actionManager, + rulesManager, } const exchange = executeExchange({ @@ -503,5 +597,8 @@ export const createIndexerManagementClient = async ( context, }) - return new IndexerManagementClient({ url: 'no-op', exchanges: [exchange] }, options) + return new IndexerManagementClient( + { url: 'no-op', exchanges: [exchange] }, + { ...options, actionManager }, + ) } diff --git a/packages/indexer-common/src/indexer-management/models/action.ts b/packages/indexer-common/src/indexer-management/models/action.ts index f89a644b3..e40f37b99 100644 --- a/packages/indexer-common/src/indexer-management/models/action.ts +++ b/packages/indexer-common/src/indexer-management/models/action.ts @@ -37,6 +37,11 @@ export class Action extends Model< declare protocolNetwork: string + declare isLegacy: boolean + + declare publicPOI: string | null + declare poiBlockNumber: number | null + // eslint-disable-next-line @typescript-eslint/ban-types public toGraphQL(): object { return { ...this.toJSON(), __typename: 'Action' } @@ -152,6 +157,19 @@ export const defineActionModels = (sequelize: Sequelize): ActionModels => { is: caip2IdRegex, }, }, + isLegacy: { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: true, + }, + publicPOI: { + type: DataTypes.STRING, + allowNull: true, + }, + poiBlockNumber: { + type: DataTypes.INTEGER, + allowNull: true, + }, }, { modelName: 'Action', diff --git a/packages/indexer-common/src/indexer-management/models/cost-model.ts b/packages/indexer-common/src/indexer-management/models/cost-model.ts index 5c719dad7..ce255fc78 100644 --- a/packages/indexer-common/src/indexer-management/models/cost-model.ts +++ b/packages/indexer-common/src/indexer-management/models/cost-model.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-empty-interface */ import { Optional, Model, DataTypes, Sequelize } from 'sequelize' -import { utils } from 'ethers' +import { isHexString } from 'ethers' export interface GraphQLCostModel { deployment: string @@ -39,13 +39,13 @@ export class CostModel extends Model implements CostModelAttributes { - public id!: number - public deployment!: string - public model!: string | null + declare id: number + declare deployment: string + declare model: string | null public variables!: CostModelVariables | null - public createdAt!: Date - public updatedAt!: Date + declare createdAt: Date + declare updatedAt: Date // eslint-disable-next-line @typescript-eslint/ban-types public toGraphQL(): object { @@ -80,7 +80,7 @@ export const defineCostModelModels = (sequelize: Sequelize): CostModelModels => } // "0x..." and "global" is ok - if (utils.isHexString(value, 32) || value === COST_MODEL_GLOBAL) { + if (isHexString(value, 32) || value === COST_MODEL_GLOBAL) { return } diff --git a/packages/indexer-common/src/indexer-management/models/index.ts b/packages/indexer-common/src/indexer-management/models/index.ts index 8d5ec55af..26f52cb63 100644 --- a/packages/indexer-common/src/indexer-management/models/index.ts +++ b/packages/indexer-common/src/indexer-management/models/index.ts @@ -4,16 +4,19 @@ import { IndexingRuleModels, defineIndexingRuleModels } from './indexing-rule' import { CostModelModels, defineCostModelModels } from './cost-model' import { POIDisputeModels, definePOIDisputeModels } from './poi-dispute' import { ActionModels, defineActionModels } from './action' +import { defineIndexingFeesModels, IndexingFeesModels } from './indexing-agreement' export * from './cost-model' export * from './indexing-rule' export * from './poi-dispute' export * from './action' +export * from './indexing-agreement' export type IndexerManagementModels = IndexingRuleModels & CostModelModels & POIDisputeModels & - ActionModels + ActionModels & + IndexingFeesModels export const defineIndexerManagementModels = ( sequelize: Sequelize, @@ -24,4 +27,5 @@ export const defineIndexerManagementModels = ( defineIndexingRuleModels(sequelize), definePOIDisputeModels(sequelize), defineActionModels(sequelize), + defineIndexingFeesModels(sequelize), ) diff --git a/packages/indexer-common/src/indexer-management/models/indexing-agreement.ts b/packages/indexer-common/src/indexer-management/models/indexing-agreement.ts new file mode 100644 index 000000000..1fceaee34 --- /dev/null +++ b/packages/indexer-common/src/indexer-management/models/indexing-agreement.ts @@ -0,0 +1,310 @@ +import { toAddress, Address } from '@graphprotocol/common-ts' +import { + DataTypes, + Sequelize, + Model, + CreationOptional, + InferCreationAttributes, + InferAttributes, + ForeignKey, +} from 'sequelize' + +// Indexing Fees AKA "DIPs" + +export class IndexingAgreement extends Model< + InferAttributes, + InferCreationAttributes +> { + declare id: CreationOptional + declare signature: Buffer + declare signed_payload: Buffer + declare protocol_network: string + declare chain_id: string + declare base_price_per_epoch: string + declare price_per_entity: string + declare subgraph_deployment_id: string + declare service: string + declare payee: string + declare payer: string + declare deadline: Date + declare duration_epochs: bigint + declare max_initial_amount: string + declare max_ongoing_amount_per_epoch: string + declare min_epochs_per_collection: bigint + declare max_epochs_per_collection: bigint + declare created_at: Date + declare updated_at: Date + declare cancelled_at: Date | null + declare signed_cancellation_payload: Buffer | null + declare current_allocation_id: string | null + declare last_allocation_id: string | null + declare last_payment_collected_at: Date | null +} + +export type DipsReceiptStatus = 'PENDING' | 'SUBMITTED' | 'FAILED' + +export class DipsReceipt extends Model< + InferAttributes, + InferCreationAttributes +> { + declare id: string // Primary key - Receipt ID from Dipper + declare agreement_id: ForeignKey + declare amount: string + declare status: DipsReceiptStatus + declare transaction_hash: string | null + declare error_message: string | null + declare created_at: CreationOptional + declare updated_at: CreationOptional + declare retry_count: CreationOptional +} + +export interface IndexingFeesModels { + IndexingAgreement: typeof IndexingAgreement + DipsReceipt: typeof DipsReceipt +} + +export const defineIndexingFeesModels = (sequelize: Sequelize): IndexingFeesModels => { + IndexingAgreement.init( + { + id: { + type: DataTypes.UUID, + primaryKey: true, + }, + signature: { + type: DataTypes.BLOB, + allowNull: false, + unique: true, + }, + signed_payload: { + type: DataTypes.BLOB, + allowNull: false, + }, + protocol_network: { + type: DataTypes.STRING(255), + allowNull: false, + }, + chain_id: { + type: DataTypes.STRING(255), + allowNull: false, + }, + base_price_per_epoch: { + type: DataTypes.DECIMAL(39), + allowNull: false, + }, + price_per_entity: { + type: DataTypes.DECIMAL(39), + allowNull: false, + }, + subgraph_deployment_id: { + type: DataTypes.STRING(255), + allowNull: false, + }, + service: { + type: DataTypes.CHAR(40), + allowNull: false, + get() { + const rawValue = this.getDataValue('service') + return toAddress(rawValue) + }, + set(value: Address) { + const addressWithoutPrefix = value.toLowerCase().replace('0x', '') + this.setDataValue('service', addressWithoutPrefix) + }, + }, + payee: { + type: DataTypes.CHAR(40), + allowNull: false, + get() { + const rawValue = this.getDataValue('payee') + return toAddress(rawValue) + }, + set(value: Address) { + const addressWithoutPrefix = value.toLowerCase().replace('0x', '') + this.setDataValue('payee', addressWithoutPrefix) + }, + }, + payer: { + type: DataTypes.CHAR(40), + allowNull: false, + get() { + const rawValue = this.getDataValue('payer') + return toAddress(rawValue) + }, + set(value: Address) { + const addressWithoutPrefix = value.toLowerCase().replace('0x', '') + this.setDataValue('payer', addressWithoutPrefix) + }, + }, + deadline: { + type: DataTypes.DATE, + allowNull: false, + }, + duration_epochs: { + type: DataTypes.BIGINT, + allowNull: false, + }, + max_initial_amount: { + type: DataTypes.DECIMAL(39), + allowNull: false, + }, + max_ongoing_amount_per_epoch: { + type: DataTypes.DECIMAL(39), + allowNull: false, + }, + min_epochs_per_collection: { + type: DataTypes.BIGINT, + allowNull: false, + }, + max_epochs_per_collection: { + type: DataTypes.BIGINT, + allowNull: false, + }, + created_at: { + type: DataTypes.DATE, + allowNull: false, + }, + updated_at: { + type: DataTypes.DATE, + allowNull: false, + }, + cancelled_at: { + type: DataTypes.DATE, + allowNull: true, + }, + signed_cancellation_payload: { + type: DataTypes.BLOB, + allowNull: true, + }, + current_allocation_id: { + type: DataTypes.CHAR(40), + allowNull: true, + get() { + const rawValue = this.getDataValue('current_allocation_id') + if (!rawValue) { + return null + } + return toAddress(rawValue) + }, + set(value: Address | null) { + if (!value) { + this.setDataValue('current_allocation_id', null) + } else { + const addressWithoutPrefix = value.toLowerCase().replace('0x', '') + this.setDataValue('current_allocation_id', addressWithoutPrefix) + } + }, + }, + last_allocation_id: { + type: DataTypes.CHAR(40), + allowNull: true, + get() { + const rawValue = this.getDataValue('last_allocation_id') + if (!rawValue) { + return null + } + return toAddress(rawValue) + }, + set(value: Address | null) { + if (!value) { + this.setDataValue('last_allocation_id', null) + } else { + const addressWithoutPrefix = value.toLowerCase().replace('0x', '') + this.setDataValue('last_allocation_id', addressWithoutPrefix) + } + }, + }, + last_payment_collected_at: { + type: DataTypes.DATE, + allowNull: true, + }, + }, + { + modelName: 'IndexingAgreement', + sequelize, + tableName: 'indexing_agreements', + timestamps: true, + createdAt: 'created_at', + updatedAt: 'updated_at', + }, + ) + + DipsReceipt.init( + { + id: { + type: DataTypes.STRING(255), + primaryKey: true, + allowNull: false, + }, + agreement_id: { + type: DataTypes.UUID, + allowNull: false, + references: { + model: IndexingAgreement, + key: 'id', + }, + }, + amount: { + type: DataTypes.DECIMAL(39), + allowNull: false, + }, + status: { + type: DataTypes.ENUM('PENDING', 'SUBMITTED', 'FAILED'), + allowNull: false, + defaultValue: 'PENDING', + }, + transaction_hash: { + type: DataTypes.CHAR(66), + allowNull: true, + }, + error_message: { + type: DataTypes.TEXT, + allowNull: true, + }, + created_at: { + type: DataTypes.DATE, + allowNull: false, + }, + updated_at: { + type: DataTypes.DATE, + allowNull: false, + }, + retry_count: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 0, + }, + }, + { + modelName: 'DipsReceipt', + sequelize, + tableName: 'dips_receipts', + timestamps: true, + createdAt: 'created_at', + updatedAt: 'updated_at', + indexes: [ + { + fields: ['agreement_id'], + }, + { + fields: ['status'], + }, + ], + }, + ) + + // Define associations + DipsReceipt.belongsTo(IndexingAgreement, { + foreignKey: 'agreement_id', + as: 'agreement', + }) + + IndexingAgreement.hasMany(DipsReceipt, { + foreignKey: 'agreement_id', + as: 'receipts', + }) + + return { + ['IndexingAgreement']: IndexingAgreement, + ['DipsReceipt']: DipsReceipt, + } +} diff --git a/packages/indexer-common/src/indexer-management/models/indexing-rule.ts b/packages/indexer-common/src/indexer-management/models/indexing-rule.ts index 76ee2b265..6ee5fca39 100644 --- a/packages/indexer-common/src/indexer-management/models/indexing-rule.ts +++ b/packages/indexer-common/src/indexer-management/models/indexing-rule.ts @@ -9,6 +9,7 @@ export enum IndexingDecisionBasis { NEVER = 'never', ALWAYS = 'always', OFFCHAIN = 'offchain', + DIPS = 'dips', } export const INDEXING_RULE_GLOBAL = 'global' @@ -66,26 +67,26 @@ export class IndexingRule extends Model implements IndexingRuleAttributes { - public id!: number - public identifier!: string - public identifierType!: SubgraphIdentifierType - public allocationAmount!: string | null - public allocationLifetime!: number | null - public autoRenewal!: boolean - public parallelAllocations!: number | null - public maxAllocationPercentage!: number | null - public minSignal!: string | null - public maxSignal!: string | null - public minStake!: string | null - public minAverageQueryFees!: string | null - public custom!: string | null - public decisionBasis!: IndexingDecisionBasis - public requireSupported!: boolean - public safety!: boolean - public protocolNetwork!: string + declare id: number + declare identifier: string + declare identifierType: SubgraphIdentifierType + declare allocationAmount: string | null + declare allocationLifetime: number | null + declare autoRenewal: boolean + declare parallelAllocations: number | null + declare maxAllocationPercentage: number | null + declare minSignal: string | null + declare maxSignal: string | null + declare minStake: string | null + declare minAverageQueryFees: string | null + declare custom: string | null + declare decisionBasis: IndexingDecisionBasis + declare requireSupported: boolean + declare safety: boolean + declare protocolNetwork: string - public createdAt!: Date - public updatedAt!: Date + declare createdAt: Date + declare updatedAt: Date // eslint-disable-next-line @typescript-eslint/ban-types public toGraphQL(): object { @@ -245,7 +246,7 @@ export const defineIndexingRuleModels = (sequelize: Sequelize): IndexingRuleMode allowNull: true, }, decisionBasis: { - type: DataTypes.ENUM('rules', 'never', 'always', 'offchain'), + type: DataTypes.ENUM('rules', 'never', 'always', 'offchain', 'dips'), allowNull: false, defaultValue: 'rules', }, diff --git a/packages/indexer-common/src/indexer-management/models/poi-dispute.ts b/packages/indexer-common/src/indexer-management/models/poi-dispute.ts index 3be43835b..a4cd1e862 100644 --- a/packages/indexer-common/src/indexer-management/models/poi-dispute.ts +++ b/packages/indexer-common/src/indexer-management/models/poi-dispute.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-empty-interface */ import { Optional, Model, DataTypes, Sequelize } from 'sequelize' -import { utils } from 'ethers' +import { isHexString } from 'ethers' import { caip2IdRegex } from '../../parsers' export interface POIDisputeAttributes { @@ -51,23 +51,23 @@ export class POIDispute extends Model implements POIDisputeAttributes { - public allocationID!: string - public subgraphDeploymentID!: string - public allocationIndexer!: string - public allocationAmount!: string - public allocationProof!: string - public closedEpoch!: number - public closedEpochReferenceProof!: string | null - public closedEpochStartBlockHash!: string - public closedEpochStartBlockNumber!: number - public previousEpochReferenceProof!: string | null - public previousEpochStartBlockHash!: string - public previousEpochStartBlockNumber!: number - public status!: string - public protocolNetwork!: string + declare allocationID: string + declare subgraphDeploymentID: string + declare allocationIndexer: string + declare allocationAmount: string + declare allocationProof: string + declare closedEpoch: number + declare closedEpochReferenceProof: string | null + declare closedEpochStartBlockHash: string + declare closedEpochStartBlockNumber: number + declare previousEpochReferenceProof: string | null + declare previousEpochStartBlockHash: string + declare previousEpochStartBlockNumber: number + declare status: string + declare protocolNetwork: string - public createdAt!: Date - public updatedAt!: Date + declare createdAt: Date + declare updatedAt: Date // eslint-disable-next-line @typescript-eslint/ban-types public toGraphQL(): object { @@ -95,7 +95,7 @@ export const definePOIDisputeModels = (sequelize: Sequelize): POIDisputeModels = } // "0x..." is ok - if (utils.isHexString(value, 20)) { + if (isHexString(value, 20)) { return } @@ -128,7 +128,7 @@ export const definePOIDisputeModels = (sequelize: Sequelize): POIDisputeModels = } // "0x..." is ok - if (utils.isHexString(value, 20)) { + if (isHexString(value, 20)) { return } @@ -155,7 +155,7 @@ export const definePOIDisputeModels = (sequelize: Sequelize): POIDisputeModels = } // "0x..." is ok - if (utils.isHexString(value, 32)) { + if (isHexString(value, 32)) { return } @@ -178,7 +178,7 @@ export const definePOIDisputeModels = (sequelize: Sequelize): POIDisputeModels = } // null or "0x..." is ok - if (!value || utils.isHexString(value, 32)) { + if (!value || isHexString(value, 32)) { return } @@ -197,7 +197,7 @@ export const definePOIDisputeModels = (sequelize: Sequelize): POIDisputeModels = } // "0x..." is ok - if (utils.isHexString(value, 32)) { + if (isHexString(value, 32)) { return } @@ -220,7 +220,7 @@ export const definePOIDisputeModels = (sequelize: Sequelize): POIDisputeModels = } // null or "0x..." is ok - if (!value || utils.isHexString(value, 32)) { + if (!value || isHexString(value, 32)) { return } @@ -239,7 +239,7 @@ export const definePOIDisputeModels = (sequelize: Sequelize): POIDisputeModels = } // "0x..." is ok - if (utils.isHexString(value, 32)) { + if (isHexString(value, 32)) { return } diff --git a/packages/indexer-common/src/indexer-management/monitor.ts b/packages/indexer-common/src/indexer-management/monitor.ts index e09e43fef..b8c2c3741 100644 --- a/packages/indexer-common/src/indexer-management/monitor.ts +++ b/packages/indexer-common/src/indexer-management/monitor.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-case-declarations */ import { Allocation, AllocationStatus, @@ -18,20 +19,27 @@ import { resolveChainAlias, TransferredSubgraphDeployment, sequentialTimerReduce, + HorizonTransitionValue, + Provision, + parseGraphQLProvision, + POIData, + IndexingStatusCode, } from '@graphprotocol/indexer-common' +import { + GraphHorizonContracts, + SubgraphServiceContracts, +} from '@graphprotocol/toolshed/deployments' import { Address, Eventual, Logger, mutable, - NetworkContracts, SubgraphDeploymentID, toAddress, formatGRT, } from '@graphprotocol/common-ts' -import { BigNumber } from 'ethers' +import { HDNodeWallet, hexlify, Provider, ZeroAddress } from 'ethers' import gql from 'graphql-tag' -import { providers, utils, Wallet } from 'ethers' import pRetry, { Options } from 'p-retry' import { IndexerOptions } from '../network-specification' import pMap from 'p-map' @@ -41,12 +49,12 @@ import { SubgraphClient } from '../subgraph-client' export class NetworkMonitor { constructor( public networkCAIPID: string, - private contracts: NetworkContracts, + private contracts: GraphHorizonContracts & SubgraphServiceContracts, private indexerOptions: IndexerOptions, private logger: Logger, private graphNode: GraphNode, private networkSubgraph: SubgraphClient, - private ethereum: providers.BaseProvider, + private ethereum: Provider, private epochSubgraph: SubgraphClient, ) {} @@ -55,11 +63,86 @@ export class NetworkMonitor { } async currentEpochNumber(): Promise { - return (await this.contracts.epochManager.currentEpoch()).toNumber() + return Number(await this.contracts.EpochManager.currentEpoch()) } - async maxAllocationEpoch(): Promise { - return await this.contracts.staking.maxAllocationEpochs() + // Maximum allocation duration is different for legacy and horizon allocations + // - Legacy allocations - expiration measured in epochs, determined by maxAllocationEpochs + // - Horizon allocations - expiration measured in seconds, determined by maxPOIStaleness. + // To simplify the agent logic, this function converts horizon allocation values, returning epoch values + // regardless of the allocation type. + async maxAllocationDuration(): Promise { + const isHorizon = await this.isHorizon() + + if (isHorizon) { + // TODO HORIZON: this assumes a block time of 12 seconds which is true for current protocol chain but not always + const BLOCK_IN_SECONDS = 12n + const epochLengthInBlocks = await this.contracts.EpochManager.epochLength() + const epochLengthInSeconds = Number(epochLengthInBlocks * BLOCK_IN_SECONDS) + + // When converting to epochs we give it a bit of leeway since missing the allocation expiration in horizon + // incurs in a severe penalty (missing out on indexing rewards) + const horizonDurationInSeconds = Number( + await this.contracts.SubgraphService.maxPOIStaleness(), + ) + const horizonDurationInEpochs = Math.max( + 1, + Math.floor(horizonDurationInSeconds / epochLengthInSeconds) - 1, + ) + + return { + legacy: 28, // Hardcode to the latest known value. This is required for legacy allos in the transition period. + horizon: horizonDurationInEpochs, + } + } else { + return { + legacy: Number(await this.contracts.LegacyStaking.maxAllocationEpochs()), + horizon: 0, + } + } + } + + /** + * Returns the amount of free stake for the indexer. + * + * The free stake is the amount of tokens that the indexer can use to stake in + * new allocations. + * + * Horizon: It's calculated as the difference between the tokens + * available in the provision and the tokens already locked allocations. + * + * Legacy: It's given by the indexer's stake capacity. + * + * @returns The amount of free stake for the indexer. + */ + async freeStake(): Promise> { + const isHorizon = await this.isHorizon() + + if (isHorizon) { + const address = this.indexerOptions.address + const dataService = this.contracts.SubgraphService.target.toString() + const delegationRatio = await this.contracts.SubgraphService.getDelegationRatio() + const tokensAvailable = await this.contracts.HorizonStaking.getTokensAvailable( + address, + dataService, + delegationRatio, + ) + const lockedStake = + await this.contracts.SubgraphService.allocationProvisionTracker(address) + const freeStake = tokensAvailable > lockedStake ? tokensAvailable - lockedStake : 0n + + return { + legacy: 0n, // In horizon new legacy allocations cannot be created so we return 0 + horizon: freeStake, + } + } else { + return { + legacy: await this.contracts.LegacyStaking.getIndexerCapacity( + this.indexerOptions.address, + ), + horizon: 0n, + } + } } /** @@ -99,12 +182,15 @@ export class NetworkMonitor { allocation(id: $allocation) { id status + isLegacy indexer { id } allocatedTokens + createdAt createdAtEpoch createdAtBlockHash + closedAt closedAtEpoch subgraphDeployment { id @@ -153,11 +239,14 @@ export class NetworkMonitor { orderDirection: asc ) { id + isLegacy indexer { id } allocatedTokens + createdAt createdAtEpoch + closedAt closedAtEpoch createdAtBlockHash subgraphDeployment { @@ -215,6 +304,50 @@ export class NetworkMonitor { } } + async provision(indexer: string, dataService: string): Promise { + const result = await this.networkSubgraph.checkedQuery( + gql` + query provisions($indexer: String!, $dataService: String!) { + provisions(where: { indexer: $indexer, dataService: $dataService }) { + id + indexer { + id + } + dataService { + id + } + tokensProvisioned + tokensAllocated + tokensThawing + thawingPeriod + maxVerifierCut + } + } + `, + { indexer, dataService }, + ) + if (result.error) { + throw result.error + } + + if ( + !result.data.provisions || + result.data.length == 0 || + result.data.provisions.length == 0 + ) { + const errorMessage = `No provision found for indexer '${indexer}' and data service '${dataService}'` + this.logger.warn(errorMessage) + throw indexerError(IndexerErrorCode.IE078, errorMessage) + } + + if (result.data.provisions.length > 1) { + const errorMessage = `Multiple provisions found for indexer '${indexer}' and data service '${dataService}'` + this.logger.warn(errorMessage) + throw indexerError(IndexerErrorCode.IE081, errorMessage) + } + return parseGraphQLProvision(result.data.provisions[0]) + } + async epochs(epochNumbers: number[]): Promise { try { const result = await this.networkSubgraph.checkedQuery( @@ -281,11 +414,14 @@ export class NetworkMonitor { orderDirection: desc ) { id + isLegacy indexer { id } allocatedTokens + createdAt createdAtEpoch + closedAt closedAtEpoch createdAtBlockHash subgraphDeployment { @@ -356,12 +492,15 @@ export class NetworkMonitor { orderDirection: desc ) { id + isLegacy poi indexer { id } allocatedTokens + createdAt createdAtEpoch + closedAt closedAtEpoch createdAtBlockHash subgraphDeployment { @@ -505,7 +644,7 @@ export class NetworkMonitor { return subgraphs } - async subgraphDeployment(ipfsHash: string): Promise { + async subgraphDeployment(ipfsHash: string): Promise { try { const result = await this.networkSubgraph.checkedQuery( gql` @@ -542,7 +681,14 @@ export class NetworkMonitor { this.logger.warn( `SubgraphDeployment with ipfsHash = ${ipfsHash} not found on chain`, ) - return undefined + return { + id: new SubgraphDeploymentID(ipfsHash), + deniedAt: 1, // We assume the deployment won't be eligible for rewards if it's not found + stakedTokens: 0n, + signalledTokens: 0n, + queryFeesAmount: 0n, + protocolNetwork: this.networkCAIPID, + } } return parseGraphQLSubgraphDeployment( @@ -620,18 +766,18 @@ export class NetworkMonitor { idOnL1: deployment.idOnL1, idOnL2: deployment.idOnL2, startedTransferToL2: deployment.startedTransferToL2, - startedTransferToL2At: BigNumber.from(deployment.startedTransferToL2At), - startedTransferToL2AtBlockNumber: BigNumber.from( + startedTransferToL2At: BigInt(deployment.startedTransferToL2At), + startedTransferToL2AtBlockNumber: BigInt( deployment.startedTransferToL2AtBlockNumber, ), startedTransferToL2AtTx: deployment.startedTransferToL2AtTx, transferredToL2: deployment.transferredToL2, transferredToL2At: deployment.transferredToL2At - ? BigNumber.from(deployment.transferredToL2At) + ? BigInt(deployment.transferredToL2At) : null, transferredToL2AtTx: deployment.transferredToL2AtTx, transferredToL2AtBlockNumber: deployment.transferredToL2AtBlockNumber - ? BigNumber.from(deployment.transferredToL2AtBlockNumber) + ? BigInt(deployment.transferredToL2AtBlockNumber) : null, ipfsHash: version.subgraphDeployment.ipfsHash, protocolNetwork: this.networkCAIPID, @@ -832,7 +978,8 @@ Please submit an issue at https://github.com/graphprotocol/block-oracle/issues/n // Calls the configured provider for blocks from protocol chain, or Graph Node otherwise. let startBlockHash: string if (networkID == this.networkCAIPID) { - startBlockHash = (await this.ethereum.getBlock(+validBlock.blockNumber)).hash + const block = await this.ethereum.getBlock(+validBlock.blockNumber) + startBlockHash = block!.hash! } else { startBlockHash = await this.graphNode.blockHashFromNumber( networkAlias, @@ -913,89 +1060,55 @@ Please submit an issue at https://github.com/graphprotocol/block-oracle/issues/n async resolvePOI( allocation: Allocation, poi: string | undefined, + publicPOI: string | undefined, + blockNumber: number | undefined, force: boolean, - ): Promise { - // If the network is not supported, we can't resolve POI, as there will be no active epoch - const supportedNetworkAlias = await this.allocationNetworkAlias(allocation) - if (null === supportedNetworkAlias) { - this.logger.info("Network is not supported, can't resolve POI") - return utils.hexlify(Array(32).fill(0)) - } + ): Promise { + const [resolvedPOI, resolvedPOIBlockNumber] = await this._resolvePOI( + allocation, + poi, + force, + ) - // poi = undefined, force=true -- submit even if poi is 0x0 - // poi = defined, force=true -- no generatedPOI needed, just submit the POI supplied (with some sanitation?) - // poi = undefined, force=false -- submit with generated POI if one available - // poi = defined, force=false -- submit user defined POI only if generated POI matches - switch (force) { - case true: - switch (!!poi) { - case true: - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - return poi! - case false: - return ( - (await this.graphNode.proofOfIndexing( - allocation.subgraphDeployment.id, - await this.fetchPOIBlockPointer(supportedNetworkAlias, allocation), - allocation.indexer, - )) || utils.hexlify(Array(32).fill(0)) - ) - } - break - case false: { - const epochStartBlock = await this.fetchPOIBlockPointer( - supportedNetworkAlias, - allocation, - ) - // Obtain the start block of the current epoch - const generatedPOI = await this.graphNode.proofOfIndexing( - allocation.subgraphDeployment.id, - epochStartBlock, - allocation.indexer, - ) - switch (poi == generatedPOI) { - case true: - if (poi == undefined) { - const deploymentStatus = await this.graphNode.indexingStatus([ - allocation.subgraphDeployment.id, - ]) - throw indexerError( - IndexerErrorCode.IE067, - `POI not available for deployment at current epoch start block. - currentEpochStartBlock: ${epochStartBlock.number} - deploymentStatus: ${ - deploymentStatus.length > 0 - ? JSON.stringify(deploymentStatus) - : 'not deployed' - }`, - ) - } else { - return poi - } - case false: - if (poi == undefined && generatedPOI !== undefined) { - return generatedPOI - } else if (poi !== undefined && generatedPOI == undefined) { - return poi - } - throw indexerError( - IndexerErrorCode.IE068, - `User provided POI does not match reference fetched from the graph-node. Use '--force' to bypass this POI accuracy check. - POI: ${poi}, - referencePOI: ${generatedPOI}`, - ) - } + if (allocation.isLegacy) { + return { + poi: resolvedPOI, + publicPOI: hexlify(new Uint8Array(32).fill(0)), + blockNumber: 0, + indexingStatus: IndexingStatusCode.Unknown, + } + } else { + const resolvedBlockNumber = await this._resolvePOIBlockNumber( + blockNumber, + resolvedPOIBlockNumber, + force, + ) + const resolvedPublicPOI = await this._resolvePublicPOI( + allocation, + publicPOI, + resolvedBlockNumber, + force, + ) + const resolvedIndexingStatus = await this._resolveIndexingStatus( + allocation.subgraphDeployment.id, + ) + + return { + poi: resolvedPOI, + publicPOI: resolvedPublicPOI, + blockNumber: resolvedBlockNumber, + indexingStatus: resolvedIndexingStatus, } } } async monitorNetworkPauses( logger: Logger, - contracts: NetworkContracts, + contracts: GraphHorizonContracts & SubgraphServiceContracts, networkSubgraph: SubgraphClient, ): Promise> { // eslint-disable-next-line @typescript-eslint/no-unused-vars - const initialPauseValue = await contracts.controller.paused().catch((_) => { + const initialPauseValue = await contracts.Controller.paused().catch((_) => { return false }) return sequentialTimerReduce( @@ -1043,9 +1156,8 @@ Please submit an issue at https://github.com/graphprotocol/block-oracle/issues/n async monitorIsOperator( logger: Logger, - contracts: NetworkContracts, indexerAddress: Address, - wallet: Wallet, + wallet: HDNodeWallet, ): Promise> { // If indexer and operator address are identical, operator status is // implicitly granted => we'll never have to check again @@ -1062,7 +1174,7 @@ Please submit an issue at https://github.com/graphprotocol/block-oracle/issues/n async (isOperator) => { try { logger.debug('Check operator status') - return await contracts.staking.isOperator(wallet.address, indexerAddress) + return await this.isOperator(wallet.address, indexerAddress) } catch (err) { logger.warn( `Failed to check operator status for indexer, assuming it has not changed`, @@ -1071,7 +1183,7 @@ Please submit an issue at https://github.com/graphprotocol/block-oracle/issues/n return isOperator } }, - await contracts.staking.isOperator(wallet.address, indexerAddress), + await this.isOperator(wallet.address, indexerAddress), ).map((isOperator) => { logger.info( isOperator @@ -1082,6 +1194,34 @@ Please submit an issue at https://github.com/graphprotocol/block-oracle/issues/n }) } + async monitorIsHorizon( + logger: Logger, + interval: number = 300_000, + ): Promise> { + return sequentialTimerReduce( + { + logger, + milliseconds: interval, + }, + async (isHorizon) => { + try { + logger.debug('Check if network is Horizon ready') + return await this.isHorizon() + } catch (err) { + logger.warn( + `Failed to check if network is Horizon ready, assuming it has not changed`, + { err: indexerError(IndexerErrorCode.IE008, err), isHorizon }, + ) + return isHorizon + } + }, + await this.isHorizon(), + ).map((isHorizon) => { + logger.info(isHorizon ? `Network is Horizon ready` : `Network is not Horizon ready`) + return isHorizon + }) + } + async claimableAllocations(disputableEpoch: number): Promise { try { this.logger.debug('Fetch claimable allocations', { @@ -1105,12 +1245,15 @@ Please submit an issue at https://github.com/graphprotocol/block-oracle/issues/n first: 1000 ) { id + isLegacy indexer { id } queryFeesCollected allocatedTokens + createdAt createdAtEpoch + closedAt closedAtEpoch createdAtBlockHash closedAtBlockHash @@ -1134,11 +1277,11 @@ Please submit an issue at https://github.com/graphprotocol/block-oracle/issues/n throw result.error } - const totalFees: BigNumber = result.data.allocations.reduce( - (total: BigNumber, rawAlloc: { queryFeesCollected: string }) => { - return total.add(BigNumber.from(rawAlloc.queryFeesCollected)) + const totalFees: bigint = result.data.allocations.reduce( + (total: bigint, rawAlloc: { queryFeesCollected: string }) => { + return total + BigInt(rawAlloc.queryFeesCollected) }, - BigNumber.from(0), + 0n, ) const parsedAllocs: Allocation[] = @@ -1147,7 +1290,7 @@ Please submit an issue at https://github.com/graphprotocol/block-oracle/issues/n // If the total fees claimable do not meet the minimum required for batching, return an empty array if ( parsedAllocs.length > 0 && - totalFees.lt(this.indexerOptions.rebateClaimBatchThreshold) + totalFees < this.indexerOptions.rebateClaimBatchThreshold ) { this.logger.info( `Allocation rebate batch value does not meet minimum for claiming`, @@ -1198,7 +1341,7 @@ Please submit an issue at https://github.com/graphprotocol/block-oracle/issues/n let allocations: Allocation[] = [] try { - const zeroPOI = utils.hexlify(Array(32).fill(0)) + const zeroPOI = hexlify(new Uint8Array(32).fill(0)) const disputableEpoch = currentEpoch - this.indexerOptions.poiDisputableEpochs let lastId = '' while (dataRemaining) { @@ -1225,6 +1368,7 @@ Please submit an issue at https://github.com/graphprotocol/block-oracle/issues/n orderDirection: asc ) { id + isLegacy createdAt indexer { id @@ -1233,6 +1377,7 @@ Please submit an issue at https://github.com/graphprotocol/block-oracle/issues/n allocatedTokens createdAtEpoch closedAtEpoch + closedAt closedAtBlockHash subgraphDeployment { id @@ -1278,7 +1423,7 @@ Please submit an issue at https://github.com/graphprotocol/block-oracle/issues/n async (epoch) => { try { const startBlock = await this.ethereum.getBlock(epoch.startBlock) - epoch.startBlockHash = startBlock?.hash + epoch.startBlockHash = startBlock!.hash! } catch { logger.debug('Failed to fetch block hash for startBlock of epoch', { epoch: epoch.id, @@ -1321,4 +1466,235 @@ Please submit an issue at https://github.com/graphprotocol/block-oracle/issues/n throw err } } + + private async isHorizon() { + try { + const maxThawingPeriod = await this.contracts.HorizonStaking.getMaxThawingPeriod() + return maxThawingPeriod > 0 + } catch (err) { + return false + } + } + + private async isOperator(operatorAddress: string, indexerAddress: string) { + if (await this.isHorizon()) { + return await this.contracts.HorizonStaking.isAuthorized( + indexerAddress, + this.contracts.SubgraphService.target, + operatorAddress, + ) + } else { + return await this.contracts.LegacyStaking.isOperator( + operatorAddress, + indexerAddress, + ) + } + } + + // Returns a tuple of [POI, blockNumber] + // - POI is the POI to submit, which could be user provider or generated + // - blockNumber is the block number of the POI. If it's 0 then the block number is not known at this point. + private async _resolvePOI( + allocation: Allocation, + poi: string | undefined, + force: boolean, + ): Promise<[string, number]> { + // If the network is not supported, we can't resolve POI, as there will be no active epoch + const supportedNetworkAlias = await this.allocationNetworkAlias(allocation) + if (null === supportedNetworkAlias) { + this.logger.info("Network is not supported, can't resolve POI") + return [hexlify(new Uint8Array(32).fill(0)), 0] + } + + // poi = undefined, force=true -- submit even if poi is 0x0 + // poi = defined, force=true -- no generatedPOI needed, just submit the POI supplied (with some sanitation?) + // poi = undefined, force=false -- submit with generated POI if one available + // poi = defined, force=false -- submit user defined POI only if generated POI matches + switch (force) { + case true: + switch (!!poi) { + case true: + this.logger.trace('Resolve POI: Force true, poi defined', { + poi, + blockNumber: 0, + }) + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return [poi!, 0] + case false: + const poiBlockNumber = await this.fetchPOIBlockPointer( + supportedNetworkAlias, + allocation, + ) + const generatedPOI = await this.graphNode.proofOfIndexing( + allocation.subgraphDeployment.id, + poiBlockNumber, + allocation.indexer, + ) + const returnValue: [string, number] = + generatedPOI !== undefined + ? [generatedPOI, poiBlockNumber.number] + : [hexlify(new Uint8Array(32).fill(0)), 0] + + this.logger.trace('Resolve POI: Force true, poi undefined', { + poi: returnValue[0], + blockNumber: returnValue[1], + }) + return returnValue + } + break + case false: { + const epochStartBlock = await this.fetchPOIBlockPointer( + supportedNetworkAlias, + allocation, + ) + // Obtain the start block of the current epoch + const generatedPOI = await this.graphNode.proofOfIndexing( + allocation.subgraphDeployment.id, + epochStartBlock, + allocation.indexer, + ) + switch (poi == generatedPOI) { + case true: + this.logger.trace('Resolve POI: Force false, poi matches generated', { + poi, + blockNumber: epochStartBlock.number, + }) + if (poi == undefined) { + const deploymentStatus = await this.graphNode.indexingStatus([ + allocation.subgraphDeployment.id, + ]) + throw indexerError( + IndexerErrorCode.IE067, + `POI not available for deployment at current epoch start block. + currentEpochStartBlock: ${epochStartBlock.number} + deploymentStatus: ${ + deploymentStatus.length > 0 + ? JSON.stringify(deploymentStatus) + : 'not deployed' + }`, + ) + } else { + return [poi, epochStartBlock.number] + } + case false: + this.logger.trace('Resolve POI: Force false, poi does not match generated', { + poi, + generatedPOI, + blockNumber: epochStartBlock.number, + }) + if (poi == undefined && generatedPOI !== undefined) { + return [generatedPOI, epochStartBlock.number] + } else if (poi !== undefined && generatedPOI == undefined) { + return [poi, 0] + } + throw indexerError( + IndexerErrorCode.IE068, + `User provided POI does not match reference fetched from the graph-node. Use '--force' to bypass this POI accuracy check. + POI: ${poi}, + referencePOI: ${generatedPOI}`, + ) + } + } + } + } + + private async _resolvePOIBlockNumber( + blockNumber: number | undefined, + generatedPOIBlockNumber: number, + force: boolean, + ): Promise { + let returnBlockNumber = 0 + if (generatedPOIBlockNumber === 0) { + if (blockNumber === undefined) { + throw indexerError( + IndexerErrorCode.IE084, + 'No block number generated and none provided', + ) + } + returnBlockNumber = blockNumber + } else if (blockNumber === undefined || generatedPOIBlockNumber === blockNumber) { + returnBlockNumber = generatedPOIBlockNumber + } else { + returnBlockNumber = force ? blockNumber : generatedPOIBlockNumber + } + + this.logger.trace('Resolve POI block number:', { + blockNumber, + generatedPOIBlockNumber, + returnBlockNumber, + force, + }) + + return returnBlockNumber + } + + private async _resolvePublicPOI( + allocation: Allocation, + publicPOI: string | undefined, + blockNumber: number, + force: boolean, + ): Promise { + const blockHash = await this.graphNode.blockHashFromNumber( + resolveChainAlias(this.networkCAIPID), + blockNumber, + ) + const generatedPublicPOI = await this.graphNode.proofOfIndexing( + allocation.subgraphDeployment.id, + { + number: blockNumber, + hash: blockHash, + }, + ZeroAddress, + ) + + let returnPublicPOI: string + if (generatedPublicPOI === undefined) { + if (publicPOI === undefined) { + throw indexerError( + IndexerErrorCode.IE085, + 'No public POI generated and none provided', + ) + } + returnPublicPOI = publicPOI + } else if (publicPOI === undefined || generatedPublicPOI === publicPOI) { + returnPublicPOI = generatedPublicPOI + } else { + returnPublicPOI = force ? publicPOI : generatedPublicPOI + } + + this.logger.trace('Resolve public POI:', { + blockNumber, + publicPOI, + generatedPublicPOI, + returnPublicPOI, + force, + }) + + return returnPublicPOI + } + + private async _resolveIndexingStatus( + deployment: SubgraphDeploymentID, + ): Promise { + const indexingStatus = await this.graphNode.indexingStatus([deployment]) + + let indexingStatusCode = IndexingStatusCode.Unknown + if (indexingStatus.length === 1) { + switch (indexingStatus[0].health) { + case 'healthy': + indexingStatusCode = IndexingStatusCode.Healthy + break + case 'unhealthy': + indexingStatusCode = IndexingStatusCode.Unhealthy + break + case 'failed': + indexingStatusCode = IndexingStatusCode.Failed + break + default: + indexingStatusCode = IndexingStatusCode.Unknown + break + } + } + return indexingStatusCode + } } diff --git a/packages/indexer-common/src/indexer-management/resolvers/actions.ts b/packages/indexer-common/src/indexer-management/resolvers/actions.ts index 1e246754c..308e57c3d 100644 --- a/packages/indexer-common/src/indexer-management/resolvers/actions.ts +++ b/packages/indexer-common/src/indexer-management/resolvers/actions.ts @@ -20,6 +20,7 @@ import { import { literal, Op, Transaction } from 'sequelize' import { ActionManager } from '../actions' import groupBy from 'lodash.groupby' +import { extractNetwork } from './utils' // Perform insert, update, or no-op depending on existing queue data // INSERT - No item in the queue yet targeting this deploymentID @@ -170,6 +171,14 @@ export default { } }) + // Set proper value for isLegacy - any new actions in horizon are not legacy + await Promise.all( + actions.map(async (action) => { + const network = extractNetwork(action.protocolNetwork, multiNetworks) + action.isLegacy = !(await network.isHorizon.value()) + }), + ) + // Let Network Monitors validate actions based on their protocol networks await multiNetworks.mapNetworkMapped( groupBy(actions, (action) => action.protocolNetwork), diff --git a/packages/indexer-common/src/indexer-management/resolvers/allocations.ts b/packages/indexer-common/src/indexer-management/resolvers/allocations.ts index 5d2e72690..38e7d6d83 100644 --- a/packages/indexer-common/src/indexer-management/resolvers/allocations.ts +++ b/packages/indexer-common/src/indexer-management/resolvers/allocations.ts @@ -1,10 +1,9 @@ -import { epochElapsedBlocks, Network } from '@graphprotocol/indexer-common' /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ /* eslint-disable @typescript-eslint/ban-types */ import pMap from 'p-map' import gql from 'graphql-tag' -import { BigNumber, utils } from 'ethers' +import { ethers, hexlify, ZeroAddress } from 'ethers' import { Address, @@ -15,21 +14,35 @@ import { toAddress, } from '@graphprotocol/common-ts' import { - allocationIdProof, + Allocation, AllocationStatus, CloseAllocationResult, CreateAllocationResult, + epochElapsedBlocks, + horizonAllocationIdProof, + HorizonTransitionValue, indexerError, IndexerErrorCode, IndexerManagementResolverContext, IndexingDecisionBasis, IndexingRuleAttributes, + legacyAllocationIdProof, + Network, + POIData, ReallocateAllocationResult, SubgraphClient, SubgraphIdentifierType, uniqueAllocationID, } from '@graphprotocol/indexer-common' +import { + encodeCollectIndexingRewardsData, + encodePOIMetadata, + encodeStartServiceData, + encodeStopServiceData, + PaymentTypes, +} from '@graphprotocol/toolshed' import { extractNetwork } from './utils' +import { GraphNode } from '../../graph-node' interface AllocationFilter { status: 'active' | 'closed' @@ -62,6 +75,7 @@ interface AllocationInfo { queryFeesCollected: string status: string protocolNetwork: string + isLegacy: boolean } const ALLOCATION_QUERIES = { @@ -88,6 +102,7 @@ const ALLOCATION_QUERIES = { indexingRewards queryFeesCollected status + isLegacy } } `, @@ -114,6 +129,7 @@ const ALLOCATION_QUERIES = { indexingRewards queryFeesCollected status + isLegacy } } `, @@ -140,6 +156,7 @@ const ALLOCATION_QUERIES = { indexingRewards queryFeesCollected status + isLegacy } } `, @@ -166,6 +183,7 @@ const ALLOCATION_QUERIES = { indexingRewards queryFeesCollected status + isLegacy } } `, @@ -183,7 +201,7 @@ async function queryAllocations( currentEpoch: number currentEpochStartBlock: number currentEpochElapsedBlocks: number - maxAllocationEpochs: number + maxAllocationDuration: HorizonTransitionValue blocksPerEpoch: number avgBlockTime: number protocolNetwork: string @@ -263,7 +281,10 @@ async function queryAllocations( resultAllocations, // eslint-disable-next-line @typescript-eslint/no-explicit-any async (allocation: any): Promise => { - const deadlineEpoch = allocation.createdAtEpoch + context.maxAllocationEpochs + const maxAllocationDuration = allocation.isLegacy + ? context.maxAllocationDuration.legacy + : context.maxAllocationDuration.horizon + const deadlineEpoch = allocation.createdAtEpoch + maxAllocationDuration const remainingBlocks = // blocks remaining in current epoch context.blocksPerEpoch - @@ -277,24 +298,1061 @@ async function queryAllocations( .ipfsHash, signalledTokens: allocation.subgraphDeployment.signalledTokens, stakedTokens: allocation.subgraphDeployment.stakedTokens, - allocatedTokens: BigNumber.from(allocation.allocatedTokens).toString(), + allocatedTokens: allocation.allocatedTokens.toString(), createdAtEpoch: allocation.createdAtEpoch, closedAtEpoch: allocation.closedAtEpoch, ageInEpochs: allocation.closedAtEpoch ? allocation.closedAtEpoch - allocation.createdAtEpoch : context.currentEpoch - allocation.createdAtEpoch, - closeDeadlineEpoch: allocation.createdAtEpoch + context.maxAllocationEpochs, + closeDeadlineEpoch: allocation.createdAtEpoch + context.maxAllocationDuration, closeDeadlineBlocksRemaining: remainingBlocks, closeDeadlineTimeRemaining: remainingBlocks * context.avgBlockTime, indexingRewards: allocation.indexingRewards, queryFeesCollected: allocation.queryFeesCollected, status: allocation.status, protocolNetwork: context.protocolNetwork, + isLegacy: allocation.isLegacy, } }, ) } +async function createLegacyAllocation( + network: Network, + graphNode: GraphNode, + allocationAmount: bigint, + logger: Logger, + subgraphDeployment: SubgraphDeploymentID, + currentEpoch: bigint, + activeAllocations: Allocation[], + protocolNetwork: string, +): Promise<{ txHash: string; allocationId: Address }> { + const contracts = network.contracts + const transactionManager = network.transactionManager + const address = network.specification.indexerOptions.address + + // Identify how many GRT the indexer has staked + const freeStake = await contracts.LegacyStaking.getIndexerCapacity(address) + + // If there isn't enough left for allocating, abort + if (freeStake < allocationAmount) { + logger.error( + `Legacy allocation of ${formatGRT( + allocationAmount, + )} GRT cancelled: indexer only has a free stake amount of ${formatGRT( + freeStake, + )} GRT`, + ) + throw indexerError( + IndexerErrorCode.IE013, + `Legacy allocation of ${formatGRT( + allocationAmount, + )} GRT cancelled: indexer only has a free stake amount of ${formatGRT( + freeStake, + )} GRT`, + ) + } + + // Ensure subgraph is deployed before allocating + await graphNode.ensure( + `indexer-agent/${subgraphDeployment.ipfsHash.slice(-10)}`, + subgraphDeployment, + ) + + logger.debug('Obtain a unique legacy Allocation ID') + + // Obtain a unique allocation ID + const recentlyClosedAllocations = + await network.networkMonitor.recentlyClosedAllocations(Number(currentEpoch), 2) + const activeAndRecentlyClosedAllocations: Allocation[] = [ + ...recentlyClosedAllocations, + ...activeAllocations, + ] + const { allocationSigner, allocationId } = uniqueAllocationID( + transactionManager.wallet.mnemonic!.phrase, + Number(currentEpoch), + subgraphDeployment, + activeAndRecentlyClosedAllocations.map((allocation) => allocation.id), + ) + + // Double-check whether the allocationID already exists on chain, to + // avoid unnecessary transactions. + // Note: We're checking the allocation state here, which is defined as + // + // enum AllocationState { Null, Active, Closed, Finalized } + // + // in the contracts. + const state = await contracts.LegacyStaking.getAllocationState(allocationId) + if (state !== 0n) { + logger.debug(`Skipping legacy allocation as it already exists onchain`, { + indexer: address, + allocation: allocationId, + }) + throw indexerError( + IndexerErrorCode.IE066, + `Legacy allocation '${allocationId}' already exists onchain`, + ) + } + + logger.debug('Generating new legacy allocation ID proof', { + newAllocationSigner: allocationSigner, + newAllocationID: allocationId, + indexerAddress: address, + }) + + const proof = await legacyAllocationIdProof(allocationSigner, address, allocationId) + + logger.debug('Successfully generated legacy allocation ID proof', { + allocationIDProof: proof, + }) + + logger.debug(`Sending legacy allocateFrom transaction`, { + indexer: address, + subgraphDeployment: subgraphDeployment.ipfsHash, + amount: formatGRT(allocationAmount), + allocation: allocationId, + proof, + protocolNetwork, + }) + + const receipt = await transactionManager.executeTransaction( + async () => + contracts.LegacyStaking.allocateFrom.estimateGas( + address, + subgraphDeployment.bytes32, + allocationAmount, + allocationId, + hexlify(new Uint8Array(32).fill(0)), + proof, + ), + async (gasLimit) => + contracts.LegacyStaking.allocateFrom( + address, + subgraphDeployment.bytes32, + allocationAmount, + allocationId, + hexlify(new Uint8Array(32).fill(0)), + proof, + { gasLimit }, + ), + logger.child({ action: 'allocate' }), + ) + + if (receipt === 'paused' || receipt === 'unauthorized') { + throw indexerError( + IndexerErrorCode.IE062, + `Legacy allocation not created. ${ + receipt === 'paused' ? 'Network paused' : 'Operator not authorized' + }`, + ) + } + + const createAllocationEventLogs = network.transactionManager.findEvent( + 'AllocationCreated', + network.contracts.LegacyStaking.interface, + 'subgraphDeploymentID', + subgraphDeployment.toString(), + receipt, + logger, + ) + + if (!createAllocationEventLogs) { + throw indexerError( + IndexerErrorCode.IE014, + `Legacy allocation create transaction was never mined`, + ) + } + + logger.info(`Successfully legacy allocated to subgraph deployment`, { + amountGRT: formatGRT(createAllocationEventLogs.tokens), + allocation: createAllocationEventLogs.allocationID, + epoch: createAllocationEventLogs.epoch.toString(), + transaction: receipt.hash, + }) + + return { txHash: receipt.hash, allocationId: createAllocationEventLogs.allocationID } +} + +async function createHorizonAllocation( + network: Network, + graphNode: GraphNode, + allocationAmount: bigint, + logger: Logger, + subgraphDeployment: SubgraphDeploymentID, + currentEpoch: bigint, + activeAllocations: Allocation[], + protocolNetwork: string, +): Promise<{ txHash: string; allocationId: Address }> { + const contracts = network.contracts + const transactionManager = network.transactionManager + const address = network.specification.indexerOptions.address + const dataService = contracts.SubgraphService.target.toString() + + // Identify how many GRT the indexer has staked + const freeStake = (await network.networkMonitor.freeStake()).horizon + + // If there isn't enough left for allocating, abort + if (freeStake < allocationAmount) { + logger.error( + `Allocation of ${formatGRT( + allocationAmount, + )} GRT cancelled: indexer only has a free stake amount of ${formatGRT( + freeStake, + )} GRT`, + ) + throw indexerError( + IndexerErrorCode.IE013, + `Allocation of ${formatGRT( + allocationAmount, + )} GRT cancelled: indexer only has a free stake amount of ${formatGRT( + freeStake, + )} GRT`, + ) + } + + // Ensure subgraph is deployed before allocating + await graphNode.ensure( + `indexer-agent/${subgraphDeployment.ipfsHash.slice(-10)}`, + subgraphDeployment, + ) + + logger.debug('Obtain a unique Allocation ID') + + // Obtain a unique allocation ID + const recentlyClosedAllocations = + await network.networkMonitor.recentlyClosedAllocations(Number(currentEpoch), 2) + const activeAndRecentlyClosedAllocations: Allocation[] = [ + ...recentlyClosedAllocations, + ...activeAllocations, + ] + const { allocationSigner, allocationId } = uniqueAllocationID( + transactionManager.wallet.mnemonic!.phrase, + Number(currentEpoch), + subgraphDeployment, + activeAndRecentlyClosedAllocations.map((allocation) => allocation.id), + ) + + // Double-check whether the allocationID already exists on chain, to + // avoid unnecessary transactions. + const allocation = await contracts.SubgraphService.getAllocation(allocationId) + const legacyAllocation = + await contracts.SubgraphService.getLegacyAllocation(allocationId) + const existsSubgraphService = allocation.createdAt !== 0n + const existsLegacyAllocation = legacyAllocation.indexer !== ZeroAddress + if (existsSubgraphService || existsLegacyAllocation) { + logger.debug(`Skipping allocation as it already exists onchain`, { + indexer: address, + allocation: allocationId, + existsSubgraphService, + existsLegacyAllocation, + }) + throw indexerError( + IndexerErrorCode.IE066, + `Allocation '${allocationId}' already exists onchain`, + ) + } + + logger.debug('Generating new allocation ID proof', { + newAllocationSigner: allocationSigner, + newAllocationID: allocationId, + indexerAddress: address, + }) + + const chainId = Number(protocolNetwork.split(':')[1]) + const proof = await horizonAllocationIdProof( + allocationSigner, + chainId, + address, + allocationId, + dataService, + ) + + logger.debug('Successfully generated allocation ID proof', { + allocationIDProof: proof, + }) + + logger.debug(`Sending startService (allocate) transaction`, { + indexer: address, + subgraphDeployment: subgraphDeployment.ipfsHash, + amount: formatGRT(allocationAmount), + allocation: allocationId, + proof, + protocolNetwork, + }) + + const data = encodeStartServiceData( + subgraphDeployment.bytes32, + allocationAmount, + allocationId, + proof, + ) + const receipt = await transactionManager.executeTransaction( + async () => contracts.SubgraphService.startService.estimateGas(address, data), + async (gasLimit) => + contracts.SubgraphService.startService(address, data, { gasLimit }), + logger.child({ action: 'startService' }), + ) + + if (receipt === 'paused' || receipt === 'unauthorized') { + throw indexerError( + IndexerErrorCode.IE062, + `Allocation not created. ${ + receipt === 'paused' ? 'Network paused' : 'Operator not authorized' + }`, + ) + } + + const createAllocationEventLogs = network.transactionManager.findEvent( + 'ServiceStarted', + network.contracts.SubgraphService.interface, + 'data', + data, + receipt, + logger, + ) + + if (!createAllocationEventLogs) { + throw indexerError( + IndexerErrorCode.IE014, + `Allocation create transaction was never mined`, + ) + } + + logger.info(`Successfully allocated to subgraph deployment`, { + amountGRT: formatGRT(allocationAmount), + allocation: allocationId, + epoch: currentEpoch.toString(), + transaction: receipt.hash, + }) + + return { txHash: receipt.hash, allocationId } +} + +async function closeLegacyAllocation( + allocation: Allocation, + poi: string, + network: Network, + logger: Logger, +): Promise<{ txHash: string; rewardsAssigned: bigint }> { + const contracts = network.contracts + const transactionManager = network.transactionManager + const isHorizon = await network.isHorizon.value() + + // Double-check whether the allocation is still active on chain, to + // avoid unnecessary transactions. + // Note: We're checking the allocation state here, which is defined as + // + // enum AllocationState { Null, Active, Closed, Finalized } + // + // in the contracts. + const state = await contracts.LegacyStaking.getAllocationState(allocation.id) + if (state !== 1n) { + throw indexerError( + IndexerErrorCode.IE065, + 'Legacy allocation has already been closed', + ) + } + + logger.debug('Sending legacy closeAllocation transaction') + const receipt = await transactionManager.executeTransaction( + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + () => contracts.LegacyStaking.closeAllocation.estimateGas(allocation.id, poi!), + (gasLimit) => + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + contracts.LegacyStaking.closeAllocation(allocation.id, poi!, { + gasLimit, + }), + logger, + ) + + if (receipt === 'paused' || receipt === 'unauthorized') { + throw indexerError( + IndexerErrorCode.IE062, + `Legacy allocation '${allocation.id}' could not be closed: ${receipt}`, + ) + } + + const closeAllocationEventLogs = transactionManager.findEvent( + 'AllocationClosed', + contracts.LegacyStaking.interface, + 'allocationID', + allocation.id, + receipt, + logger, + ) + + if (!closeAllocationEventLogs) { + throw indexerError( + IndexerErrorCode.IE015, + `Legacy allocation close transaction was never successfully mined`, + ) + } + + const rewardsEventLogs = transactionManager.findEvent( + isHorizon ? 'HorizonRewardsAssigned' : 'RewardsAssigned', + contracts.RewardsManager.interface, + 'allocationID', + allocation.id, + receipt, + logger, + ) + + const rewardsAssigned = rewardsEventLogs ? rewardsEventLogs.amount : 0 + if (rewardsAssigned == 0) { + logger.warn('No rewards were distributed upon closing the legacy allocation') + } + + logger.info(`Successfully closed legacy allocation`, { + deployment: closeAllocationEventLogs.subgraphDeploymentID, + allocation: closeAllocationEventLogs.allocationID, + indexer: closeAllocationEventLogs.indexer, + amountGRT: formatGRT(closeAllocationEventLogs.tokens), + effectiveAllocation: closeAllocationEventLogs.effectiveAllocation.toString(), + poi: closeAllocationEventLogs.poi, + epoch: closeAllocationEventLogs.epoch.toString(), + transaction: receipt.hash, + indexingRewards: rewardsAssigned, + }) + + return { txHash: receipt.hash, rewardsAssigned } +} + +async function closeHorizonAllocation( + allocation: Allocation, + poiData: POIData, + network: Network, + logger: Logger, +): Promise<{ txHash: string; rewardsAssigned: bigint }> { + const contracts = network.contracts + const transactionManager = network.transactionManager + const address = network.specification.indexerOptions.address + const currentEpoch = await contracts.EpochManager.currentEpoch() + + // Double-check whether the allocation is still active on chain, to + // avoid unnecessary transactions. + const allocationState = await contracts.SubgraphService.getAllocation(allocation.id) + if (allocationState.closedAt !== 0n) { + throw indexerError(IndexerErrorCode.IE065, 'Allocation has already been closed') + } + + const encodedPOIMetadata = encodePOIMetadata( + poiData.blockNumber, + poiData.publicPOI, + poiData.indexingStatus, + 0, + 0, + ) + const collectIndexingRewardsData = encodeCollectIndexingRewardsData( + allocation.id, + poiData.poi, + encodedPOIMetadata, + ) + + const collectCallData = contracts.SubgraphService.interface.encodeFunctionData( + 'collect', + [address, PaymentTypes.IndexingRewards, collectIndexingRewardsData], + ) + const closeAllocationData = encodeStopServiceData(allocation.id) + const stopServiceCallData = contracts.SubgraphService.interface.encodeFunctionData( + 'stopService', + [address, closeAllocationData], + ) + + const receipt = await transactionManager.executeTransaction( + async () => + contracts.SubgraphService.multicall.estimateGas([ + collectCallData, + stopServiceCallData, + ]), + async (gasLimit) => + contracts.SubgraphService.multicall([collectCallData, stopServiceCallData], { + gasLimit, + }), + logger, + ) + + if (receipt === 'paused' || receipt === 'unauthorized') { + throw indexerError( + IndexerErrorCode.IE062, + `Allocation '${allocation.id}' could not be closed: ${receipt}`, + ) + } + + const collectIndexingRewardsEventLogs = transactionManager.findEvent( + 'ServicePaymentCollected', + contracts.SubgraphService.interface, + 'serviceProvider', + address, + receipt, + logger, + ) + + if (!collectIndexingRewardsEventLogs) { + throw indexerError( + IndexerErrorCode.IE015, + `Collecting indexing rewards for allocation '${allocation.id}' failed`, + ) + } + + const rewardsAssigned = collectIndexingRewardsEventLogs + ? collectIndexingRewardsEventLogs.tokens + : 0n + if (rewardsAssigned === 0n) { + logger.warn('No rewards were distributed upon closing the allocation') + } + + const closeAllocationEventLogs = transactionManager.findEvent( + 'ServiceStopped', + contracts.SubgraphService.interface, + 'serviceProvider', + address, + receipt, + logger, + ) + + if (!closeAllocationEventLogs) { + throw indexerError( + IndexerErrorCode.IE015, + `Allocation close transaction was never successfully mined`, + ) + } + + const allocationStateAfter = await contracts.SubgraphService.getAllocation( + allocation.id, + ) + + logger.info(`Successfully closed allocation`, { + deployment: allocationStateAfter.subgraphDeploymentId, + allocation: allocation.id, + indexer: allocationStateAfter.indexer, + amountGRT: formatGRT(allocationStateAfter.tokens), + poi: poiData.poi, + blockNumber: poiData.blockNumber, + publicPOI: poiData.publicPOI, + epoch: currentEpoch.toString(), + transaction: receipt.hash, + indexingRewards: rewardsAssigned, + }) + + logger.info('Identifying receipts worth collecting', { + allocation: allocation.id, + }) + + return { txHash: receipt.hash, rewardsAssigned } +} + +// isHorizon: false +async function reallocateLegacyAllocation( + allocation: Allocation, + allocationAmount: bigint, + activeAllocations: Allocation[], + poi: string, + network: Network, + logger: Logger, +): Promise<{ txHash: string; rewardsAssigned: bigint; newAllocationId: Address }> { + const contracts = network.contracts + const transactionManager = network.transactionManager + const address = network.specification.indexerOptions.address + const currentEpoch = await contracts.EpochManager.currentEpoch() + const isHorizon = await network.isHorizon.value() + + // Double-check whether the allocation is still active on chain, to + // avoid unnecessary transactions. + // Note: We're checking the allocation state here, which is defined as + // + // enum AllocationState { Null, Active, Closed, Finalized } + // + // in the contracts. + const state = await contracts.LegacyStaking.getAllocationState(allocation.id) + if (state !== 1n) { + logger.warn(`Legacy allocation has already been closed`) + throw indexerError( + IndexerErrorCode.IE065, + `Legacy allocation has already been closed`, + ) + } + + if (allocationAmount < 0n) { + logger.warn('Cannot legacy reallocate a negative amount of GRT', { + amount: allocationAmount.toString(), + }) + throw indexerError( + IndexerErrorCode.IE061, + 'Cannot legacy reallocate a negative amount of GRT', + ) + } + + logger.info(`Legacy reallocate to subgraph deployment`, { + existingAllocationAmount: formatGRT(allocation.allocatedTokens), + newAllocationAmount: formatGRT(allocationAmount), + epoch: currentEpoch.toString(), + }) + + // Identify how many GRT the indexer has staked + const freeStake = (await network.networkMonitor.freeStake()).legacy + + // When reallocating, we will first close the old allocation and free up the GRT in that allocation + // This GRT will be available in addition to freeStake for the new allocation + const postCloseFreeStake = freeStake + allocation.allocatedTokens + + // If there isn't enough left for allocating, abort + if (postCloseFreeStake < allocationAmount) { + throw indexerError( + IndexerErrorCode.IE013, + `Unable to legacy allocate ${formatGRT( + allocationAmount, + )} GRT: indexer only has a free stake amount of ${formatGRT( + freeStake, + )} GRT, plus ${formatGRT( + allocation.allocatedTokens, + )} GRT from the existing allocation`, + ) + } + + logger.debug('Generating a new unique legacy Allocation ID') + const recentlyClosedAllocations = + await network.networkMonitor.recentlyClosedAllocations(Number(currentEpoch), 2) + const activeAndRecentlyClosedAllocations: Allocation[] = [ + ...recentlyClosedAllocations, + ...activeAllocations, + ] + const { allocationSigner, allocationId: newAllocationId } = uniqueAllocationID( + transactionManager.wallet.mnemonic!.phrase, + Number(currentEpoch), + allocation.subgraphDeployment.id, + activeAndRecentlyClosedAllocations.map((allocation) => allocation.id), + ) + + logger.debug('New unique legacy Allocation ID generated', { + newAllocationID: newAllocationId, + newAllocationSigner: allocationSigner, + }) + + // Double-check whether the allocationID already exists on chain, to + // avoid unnecessary transactions. + // Note: We're checking the allocation state here, which is defined as + // + // enum AllocationState { Null, Active, Closed, Finalized } + // + // in the contracts. + const newAllocationState = + await contracts.LegacyStaking.getAllocationState(newAllocationId) + if (newAllocationState !== 0n) { + logger.warn(`Skipping legacy Allocation as it already exists onchain`, { + indexer: address, + allocation: newAllocationId, + newAllocationState, + }) + throw indexerError(IndexerErrorCode.IE066, 'AllocationID already exists') + } + + logger.debug('Generating new legacy allocation ID proof', { + newAllocationSigner: allocationSigner, + newAllocationID: newAllocationId, + indexerAddress: address, + }) + const proof = await legacyAllocationIdProof(allocationSigner, address, newAllocationId) + logger.debug('Successfully generated legacy allocation ID proof', { + allocationIDProof: proof, + }) + + logger.info(`Sending legacy close and legacy allocate multicall transaction`, { + indexer: address, + amount: formatGRT(allocationAmount), + oldAllocation: allocation.id, + newAllocation: newAllocationId, + newAllocationAmount: formatGRT(allocationAmount), + deployment: allocation.subgraphDeployment.id.toString(), + poi: poi, + proof, + epoch: currentEpoch.toString(), + }) + + const callData = [ + await contracts.LegacyStaking.closeAllocation.populateTransaction(allocation.id, poi), + await contracts.LegacyStaking.allocateFrom.populateTransaction( + address, + allocation.subgraphDeployment.id.bytes32, + allocationAmount, + newAllocationId, + hexlify(new Uint8Array(32).fill(0)), // metadata + proof, + ), + ].map((tx) => tx.data as string) + + const receipt = await transactionManager.executeTransaction( + async () => contracts.LegacyStaking.multicall.estimateGas(callData), + async (gasLimit) => contracts.LegacyStaking.multicall(callData, { gasLimit }), + logger.child({ + function: 'closeAndAllocate', + }), + ) + + if (receipt === 'paused' || receipt === 'unauthorized') { + throw indexerError( + IndexerErrorCode.IE062, + `Legacy allocation '${newAllocationId}' could not be closed: ${receipt}`, + ) + } + + const createAllocationEventLogs = transactionManager.findEvent( + 'AllocationCreated', + contracts.LegacyStaking.interface, + 'subgraphDeploymentID', + allocation.subgraphDeployment.id.toString(), + receipt, + logger, + ) + + if (!createAllocationEventLogs) { + throw indexerError(IndexerErrorCode.IE014, `Legacy allocation was never mined`) + } + + const closeAllocationEventLogs = transactionManager.findEvent( + 'AllocationClosed', + contracts.LegacyStaking.interface, + 'allocationID', + allocation.id, + receipt, + logger, + ) + + if (!closeAllocationEventLogs) { + throw indexerError( + IndexerErrorCode.IE015, + `Legacy allocation close transaction was never successfully mined`, + ) + } + + const rewardsEventLogs = transactionManager.findEvent( + isHorizon ? 'HorizonRewardsAssigned' : 'RewardsAssigned', + contracts.RewardsManager.interface, + 'allocationID', + allocation.id, + receipt, + logger, + ) + + const rewardsAssigned = rewardsEventLogs ? rewardsEventLogs.amount : 0 + if (rewardsAssigned == 0) { + logger.warn('No rewards were distributed upon closing the legacy allocation') + } + + logger.info(`Successfully reallocated legacy allocation`, { + deployment: createAllocationEventLogs.subgraphDeploymentID, + closedAllocation: closeAllocationEventLogs.allocationID, + closedAllocationStakeGRT: formatGRT(closeAllocationEventLogs.tokens), + closedAllocationPOI: closeAllocationEventLogs.poi, + closedAllocationEpoch: closeAllocationEventLogs.epoch.toString(), + indexingRewardsCollected: rewardsAssigned, + createdAllocation: createAllocationEventLogs.allocationID, + createdAllocationStakeGRT: formatGRT(createAllocationEventLogs.tokens), + indexer: createAllocationEventLogs.indexer, + epoch: createAllocationEventLogs.epoch.toString(), + transaction: receipt.hash, + }) + + logger.info('Identifying receipts worth collecting', { + allocation: closeAllocationEventLogs.allocationID, + }) + + return { txHash: receipt.hash, rewardsAssigned, newAllocationId } +} + +// isHorizon: true and allocation: not legacy +async function reallocateHorizonAllocation( + allocation: Allocation, + allocationAmount: bigint, + activeAllocations: Allocation[], + poiData: POIData, + network: Network, + logger: Logger, +): Promise<{ txHash: string; rewardsAssigned: bigint; newAllocationId: Address }> { + const contracts = network.contracts + const transactionManager = network.transactionManager + const address = network.specification.indexerOptions.address + const currentEpoch = await contracts.EpochManager.currentEpoch() + const dataService = contracts.SubgraphService.target.toString() + + // Double-check whether the allocation is still active on chain, to + // avoid unnecessary transactions. + const allocationData = await contracts.SubgraphService.getAllocation(allocation.id) + + if (allocationData.closedAt !== 0n) { + logger.warn(`Allocation has already been closed`) + throw indexerError(IndexerErrorCode.IE065, `Allocation has already been closed`) + } + + if (allocationAmount < 0n) { + logger.warn('Cannot reallocate a negative amount of GRT', { + amount: allocationAmount.toString(), + }) + throw indexerError( + IndexerErrorCode.IE061, + 'Cannot reallocate a negative amount of GRT', + ) + } + + logger.info(`Reallocate to subgraph deployment`, { + existingAllocationAmount: formatGRT(allocation.allocatedTokens), + newAllocationAmount: formatGRT(allocationAmount), + epoch: currentEpoch.toString(), + }) + + // Identify how many GRT the indexer has staked + const freeStake = (await network.networkMonitor.freeStake()).horizon + + // When reallocating, we will first close the old allocation and free up the GRT in that allocation + // This GRT will be available in addition to freeStake for the new allocation + const postCloseFreeStake = freeStake + allocationData.tokens + + // If there isn't enough left for allocating, abort + if (postCloseFreeStake < allocationAmount) { + throw indexerError( + IndexerErrorCode.IE013, + `Unable to allocate ${formatGRT( + allocationAmount, + )} GRT: indexer only has a free stake amount of ${formatGRT( + freeStake, + )} GRT, plus ${formatGRT( + allocation.allocatedTokens, + )} GRT from the existing allocation`, + ) + } + + logger.debug('Generating a new unique Allocation ID') + const recentlyClosedAllocations = + await network.networkMonitor.recentlyClosedAllocations(Number(currentEpoch), 2) + const activeAndRecentlyClosedAllocations: Allocation[] = [ + ...recentlyClosedAllocations, + ...activeAllocations, + ] + const { allocationSigner, allocationId: newAllocationId } = uniqueAllocationID( + transactionManager.wallet.mnemonic!.phrase, + Number(currentEpoch), + allocation.subgraphDeployment.id, + activeAndRecentlyClosedAllocations.map((allocation) => allocation.id), + ) + + logger.debug('New unique Allocation ID generated', { + newAllocationID: newAllocationId, + newAllocationSigner: allocationSigner, + }) + + // Double-check whether the allocationID already exists on chain, to + // avoid unnecessary transactions. + const newAllocationData = await contracts.SubgraphService.getAllocation(newAllocationId) + if (newAllocationData.createdAt !== 0n) { + logger.warn(`Skipping Allocation as it already exists onchain`, { + indexer: address, + allocation: newAllocationId, + newAllocationData, + }) + throw indexerError(IndexerErrorCode.IE066, 'AllocationID already exists') + } + + logger.debug('Generating new allocation ID proof', { + newAllocationSigner: allocationSigner, + newAllocationID: newAllocationId, + indexerAddress: address, + }) + const chainId = Number(network.specification.networkIdentifier.split(':')[1]) + const proof = await horizonAllocationIdProof( + allocationSigner, + chainId, + address, + newAllocationId, + dataService, + ) + logger.debug('Successfully generated allocation ID proof', { + allocationIDProof: proof, + }) + + logger.info(`Sending close and allocate multicall transaction`, { + indexer: address, + amount: formatGRT(allocationAmount), + oldAllocation: allocation.id, + newAllocation: newAllocationId, + newAllocationAmount: formatGRT(allocationAmount), + deployment: allocation.subgraphDeployment.id.toString(), + poi: poiData.poi, + proof, + epoch: currentEpoch.toString(), + }) + + const encodedPOIMetadata = encodePOIMetadata( + poiData.blockNumber, + poiData.publicPOI, + poiData.indexingStatus, + 0, + 0, + ) + const collectIndexingRewardsData = encodeCollectIndexingRewardsData( + allocation.id, + poiData.poi, + encodedPOIMetadata, + ) + const closeAllocationData = ethers.AbiCoder.defaultAbiCoder().encode( + ['address'], + [allocation.id], + ) + const createAllocationData = encodeStartServiceData( + allocation.subgraphDeployment.id.bytes32, + allocationAmount, + newAllocationId, + proof, + ) + + const collectCallData = contracts.SubgraphService.interface.encodeFunctionData( + 'collect', + [address, PaymentTypes.IndexingRewards, collectIndexingRewardsData], + ) + const stopServiceCallData = contracts.SubgraphService.interface.encodeFunctionData( + 'stopService', + [address, closeAllocationData], + ) + const startServiceCallData = contracts.SubgraphService.interface.encodeFunctionData( + 'startService', + [address, createAllocationData], + ) + + const receipt = await transactionManager.executeTransaction( + async () => + contracts.SubgraphService.multicall.estimateGas([ + collectCallData, + stopServiceCallData, + startServiceCallData, + ]), + async (gasLimit) => + contracts.SubgraphService.multicall( + [collectCallData, stopServiceCallData, startServiceCallData], + { gasLimit }, + ), + logger.child({ + function: 'closeAndAllocate', + }), + ) + + if (receipt === 'paused' || receipt === 'unauthorized') { + throw indexerError( + IndexerErrorCode.IE062, + `Allocation '${newAllocationId}' could not be closed: ${receipt}`, + ) + } + + logger.info('Finding create allocation event logs') + const createAllocationEventLogs = network.transactionManager.findEvent( + 'ServiceStarted', + network.contracts.SubgraphService.interface, + 'serviceProvider', + address, + receipt, + logger, + ) + + if (!createAllocationEventLogs) { + throw indexerError(IndexerErrorCode.IE014, `Allocation was never mined`) + } + + logger.info('Finding collect indexing rewards event logs') + const collectIndexingRewardsEventLogs = transactionManager.findEvent( + 'ServicePaymentCollected', + contracts.SubgraphService.interface, + 'serviceProvider', + address, + receipt, + logger, + ) + + if (!collectIndexingRewardsEventLogs) { + throw indexerError( + IndexerErrorCode.IE015, + `Collecting indexing rewards for allocation '${allocation.id}' failed`, + ) + } + + const rewardsAssigned = collectIndexingRewardsEventLogs + ? collectIndexingRewardsEventLogs.tokens + : 0n + if (rewardsAssigned === 0n) { + logger.warn('No rewards were distributed upon closing the allocation') + } + + logger.info('Finding close allocation event logs') + const closeAllocationEventLogs = transactionManager.findEvent( + 'ServiceStopped', + contracts.SubgraphService.interface, + 'serviceProvider', + address, + receipt, + logger, + ) + + if (!closeAllocationEventLogs) { + throw indexerError( + IndexerErrorCode.IE015, + `Allocation close transaction was never successfully mined`, + ) + } + + logger.info(`Successfully reallocated allocation`, { + deployment: createAllocationEventLogs.subgraphDeploymentID, + closedAllocation: allocation.id, + closedAllocationStakeGRT: formatGRT(allocation.allocatedTokens), + closedAllocationPOI: poiData.poi, + closedAllocationEpoch: currentEpoch.toString(), + indexingRewardsCollected: rewardsAssigned, + createdAllocation: newAllocationId, + createdAllocationStakeGRT: formatGRT(allocationAmount), + indexer: address, + epoch: currentEpoch.toString(), + transaction: receipt.hash, + }) + + return { txHash: receipt.hash, rewardsAssigned, newAllocationId } +} + +// isHorizon: true and allocation: legacy +async function migrateLegacyAllocationToHorizon( + allocation: Allocation, + allocationAmount: bigint, + activeAllocations: Allocation[], + poi: string, + network: Network, + graphNode: GraphNode, + logger: Logger, +): Promise<{ txHash: string; rewardsAssigned: bigint; newAllocationId: Address }> { + const contracts = network.contracts + const currentEpoch = await contracts.EpochManager.currentEpoch() + + // We want to make sure that we close the legacy allocation even if reallocating to horizon would fail + // so we don't use a multicall but send separate transactions for closing + const closeAllocationResult = await closeLegacyAllocation( + allocation, + poi, + network, + logger, + ) + + // After closing the legacy allocation, we attempt to create a new horizon allocation + const createAllocationResult = await createHorizonAllocation( + network, + graphNode, + allocationAmount, + logger, + allocation.subgraphDeployment.id, + currentEpoch, + activeAllocations, + network.specification.networkIdentifier, + ) + + return { + txHash: createAllocationResult.txHash, + rewardsAssigned: closeAllocationResult.rewardsAssigned, + newAllocationId: createAllocationResult.allocationId, + } +} + export default { allocations: async ( { filter }: { filter: AllocationFilter }, @@ -328,10 +1386,10 @@ export default { }, } = network - const [currentEpoch, maxAllocationEpochs, epochLength] = await Promise.all([ + const [currentEpoch, maxAllocationDuration, epochLength] = await Promise.all([ networkMonitor.networkCurrentEpoch(), - contracts.staking.maxAllocationEpochs(), - contracts.epochManager.epochLength(), + networkMonitor.maxAllocationDuration(), + contracts.EpochManager.epochLength(), ]) const allocation = filter.allocation @@ -351,8 +1409,8 @@ export default { currentEpochStartBlock: currentEpoch.startBlockNumber, currentEpochElapsedBlocks: epochElapsedBlocks(currentEpoch), latestBlock: currentEpoch.latestBlock, - maxAllocationEpochs, - blocksPerEpoch: epochLength.toNumber(), + maxAllocationDuration: maxAllocationDuration, + blocksPerEpoch: Number(epochLength), avgBlockTime: 13000, protocolNetwork: network.specification.networkIdentifier, } @@ -374,7 +1432,13 @@ export default { amount: string protocolNetwork: string }, - { multiNetworks, graphNode, logger, models }: IndexerManagementResolverContext, + { + multiNetworks, + graphNode, + logger, + models, + actionManager, + }: IndexerManagementResolverContext, ): Promise => { logger.debug('Execute createAllocation() mutation', { deployment, @@ -388,10 +1452,6 @@ export default { } const network = extractNetwork(protocolNetwork, multiNetworks) const networkMonitor = network.networkMonitor - const contracts = network.contracts - const transactionManager = network.transactionManager - const address = network.specification.indexerOptions.address - const allocationAmount = parseGRT(amount) const subgraphDeployment = new SubgraphDeploymentID(deployment) @@ -412,7 +1472,7 @@ export default { ) } - if (allocationAmount.lt('0')) { + if (allocationAmount < 0n) { logger.warn('Cannot allocate a negative amount of GRT', { amount: formatGRT(allocationAmount), }) @@ -423,142 +1483,45 @@ export default { } try { - const currentEpoch = await contracts.epochManager.currentEpoch() - - // Identify how many GRT the indexer has staked - const freeStake = await contracts.staking.getIndexerCapacity(address) - - // If there isn't enough left for allocating, abort - if (freeStake.lt(allocationAmount)) { - logger.error( - `Allocation of ${formatGRT( - allocationAmount, - )} GRT cancelled: indexer only has a free stake amount of ${formatGRT( - freeStake, - )} GRT`, - ) - throw indexerError( - IndexerErrorCode.IE013, - `Allocation of ${formatGRT( - allocationAmount, - )} GRT cancelled: indexer only has a free stake amount of ${formatGRT( - freeStake, - )} GRT`, - ) - } - - // Ensure subgraph is deployed before allocating - await graphNode.ensure( - `indexer-agent/${subgraphDeployment.ipfsHash.slice(-10)}`, - subgraphDeployment, - ) - - logger.debug('Obtain a unique Allocation ID') - - // Obtain a unique allocation ID - const { allocationSigner, allocationId } = uniqueAllocationID( - transactionManager.wallet.mnemonic.phrase, - currentEpoch.toNumber(), - subgraphDeployment, - activeAllocations.map((allocation) => allocation.id), - ) + const currentEpoch = await network.contracts.EpochManager.currentEpoch() + const isHorizon = await network.isHorizon.value() - // Double-check whether the allocationID already exists on chain, to - // avoid unnecessary transactions. - // Note: We're checking the allocation state here, which is defined as - // - // enum AllocationState { Null, Active, Closed, Finalized } - // - // in the contracts. - const state = await contracts.staking.getAllocationState(allocationId) - if (state !== 0) { - logger.debug(`Skipping allocation as it already exists onchain`, { - indexer: address, - allocation: allocationId, - state, - }) - throw indexerError( - IndexerErrorCode.IE066, - `Allocation '${allocationId}' already exists onchain`, - ) - } - - logger.debug('Generating new allocation ID proof', { - newAllocationSigner: allocationSigner, - newAllocationID: allocationId, - indexerAddress: address, - }) - - const proof = await allocationIdProof(allocationSigner, address, allocationId) - - logger.debug('Successfully generated allocation ID proof', { - allocationIDProof: proof, - }) - - logger.debug(`Sending allocateFrom transaction`, { - indexer: address, - subgraphDeployment: subgraphDeployment.ipfsHash, - amount: formatGRT(allocationAmount), - allocation: allocationId, - proof, - protocolNetwork, + logger.debug('createAllocation: Checking allocation resolution path', { + isHorizon, }) - const receipt = await transactionManager.executeTransaction( - async () => - contracts.staking.estimateGas.allocateFrom( - address, - subgraphDeployment.bytes32, - allocationAmount, - allocationId, - utils.hexlify(Array(32).fill(0)), - proof, - ), - async (gasLimit) => - contracts.staking.allocateFrom( - address, - subgraphDeployment.bytes32, - allocationAmount, - allocationId, - utils.hexlify(Array(32).fill(0)), - proof, - { gasLimit }, - ), - logger.child({ action: 'allocate' }), - ) - - if (receipt === 'paused' || receipt === 'unauthorized') { - throw indexerError( - IndexerErrorCode.IE062, - `Allocation not created. ${ - receipt === 'paused' ? 'Network paused' : 'Operator not authorized' - }`, + let txHash: string + let allocationId: Address + if (isHorizon) { + logger.debug('Creating horizon allocation') + const result = await createHorizonAllocation( + network, + graphNode, + allocationAmount, + logger, + subgraphDeployment, + currentEpoch, + activeAllocations, + protocolNetwork, ) - } - - const createAllocationEventLogs = network.transactionManager.findEvent( - 'AllocationCreated', - network.contracts.staking.interface, - 'subgraphDeploymentID', - subgraphDeployment.toString(), - receipt, - logger, - ) - - if (!createAllocationEventLogs) { - throw indexerError( - IndexerErrorCode.IE014, - `Allocation create transaction was never mined`, + txHash = result.txHash + allocationId = result.allocationId + } else { + logger.debug('Creating legacy allocation') + const result = await createLegacyAllocation( + network, + graphNode, + allocationAmount, + logger, + subgraphDeployment, + currentEpoch, + activeAllocations, + protocolNetwork, ) + txHash = result.txHash + allocationId = result.allocationId } - logger.info(`Successfully allocated to subgraph deployment`, { - amountGRT: formatGRT(createAllocationEventLogs.tokens), - allocation: createAllocationEventLogs.allocationID, - epoch: createAllocationEventLogs.epoch.toString(), - transaction: receipt.transactionHash, - }) - logger.debug( `Updating indexing rules, so indexer-agent will now manage the active allocation`, ) @@ -572,6 +1535,16 @@ export default { await models.IndexingRule.upsert(indexingRule) + const allocationManager = + actionManager?.allocationManagers[network.specification.networkIdentifier] + if (allocationManager?.dipsManager) { + await allocationManager.dipsManager.tryUpdateAgreementAllocation( + deployment, + null, + toAddress(allocationId), + ) + } + // Since upsert succeeded, we _must_ have a rule const updatedRule = await models.IndexingRule.findOne({ where: { identifier: indexingRule.identifier }, @@ -584,9 +1557,9 @@ export default { return { actionID: 0, type: 'allocate', - transactionID: receipt.transactionHash, + transactionID: txHash, deployment, - allocation: createAllocationEventLogs.allocationID, + allocation: allocationId, allocatedTokens: formatGRT(allocationAmount.toString()), protocolNetwork, } @@ -603,19 +1576,25 @@ export default { { allocation, poi, + blockNumber, + publicPOI, force, protocolNetwork, }: { allocation: string poi: string | undefined + blockNumber: string | undefined + publicPOI: string | undefined force: boolean protocolNetwork: string }, - { logger, models, multiNetworks }: IndexerManagementResolverContext, + { logger, models, multiNetworks, actionManager }: IndexerManagementResolverContext, ): Promise => { logger.debug('Execute closeAllocation() mutation', { allocationID: allocation, poi: poi || 'none provided', + blockNumber: blockNumber || 'none provided', + publicPOI: publicPOI || 'none provided', }) if (!multiNetworks) { throw Error( @@ -624,98 +1603,53 @@ export default { } const network = extractNetwork(protocolNetwork, multiNetworks) const networkMonitor = network.networkMonitor - const contracts = network.contracts - const transactionManager = network.transactionManager - const receiptCollector = network.receiptCollector - const allocationData = await networkMonitor.allocation(allocation) try { - poi = await networkMonitor.resolvePOI(allocationData, poi, force) - - // Double-check whether the allocation is still active on chain, to - // avoid unnecessary transactions. - // Note: We're checking the allocation state here, which is defined as - // - // enum AllocationState { Null, Active, Closed, Finalized } - // - // in the contracts. - const state = await contracts.staking.getAllocationState(allocationData.id) - if (state !== 1) { - throw indexerError(IndexerErrorCode.IE065, 'Allocation has already been closed') - } - - logger.debug('Sending closeAllocation transaction') - const receipt = await transactionManager.executeTransaction( - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - () => contracts.staking.estimateGas.closeAllocation(allocationData.id, poi!), - (gasLimit) => - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - contracts.staking.closeAllocation(allocationData.id, poi!, { - gasLimit, - }), - logger, - ) - - if (receipt === 'paused' || receipt === 'unauthorized') { - throw indexerError( - IndexerErrorCode.IE062, - `Allocation '${allocationData.id}' could not be closed: ${receipt}`, - ) - } - - const closeAllocationEventLogs = transactionManager.findEvent( - 'AllocationClosed', - contracts.staking.interface, - 'allocationID', - allocation, - receipt, - logger, - ) - - if (!closeAllocationEventLogs) { - throw indexerError( - IndexerErrorCode.IE015, - `Allocation close transaction was never successfully mined`, - ) - } - - const rewardsEventLogs = transactionManager.findEvent( - 'RewardsAssigned', - contracts.rewardsManager.interface, - 'allocationID', - allocation, - receipt, - logger, + logger.debug('Resolving POI') + const poiData = await networkMonitor.resolvePOI( + allocationData, + poi, + allocationData.isLegacy ? undefined : publicPOI, + allocationData.isLegacy || blockNumber === null ? undefined : Number(blockNumber), + force, ) - - const rewardsAssigned = rewardsEventLogs ? rewardsEventLogs.amount : 0 - - if (rewardsAssigned == 0) { - logger.warn('No rewards were distributed upon closing the allocation') - } - - logger.info(`Successfully closed allocation`, { - deployment: closeAllocationEventLogs.subgraphDeploymentID, - allocation: closeAllocationEventLogs.allocationID, - indexer: closeAllocationEventLogs.indexer, - amountGRT: formatGRT(closeAllocationEventLogs.tokens), - effectiveAllocation: closeAllocationEventLogs.effectiveAllocation.toString(), - poi: closeAllocationEventLogs.poi, - epoch: closeAllocationEventLogs.epoch.toString(), - transaction: receipt.transactionHash, - indexingRewards: rewardsAssigned, + logger.debug('POI resolved', { + userProvidedPOI: poi, + userProvidedPublicPOI: publicPOI, + userProvidedBlockNumber: blockNumber, + poi: poiData.poi, + publicPOI: poiData.publicPOI, + blockNumber: poiData.blockNumber, + force, }) - logger.info('Identifying receipts worth collecting', { - allocation: closeAllocationEventLogs.allocationID, + logger.debug('closeAllocation: Checking allocation resolution path', { + allocationIsLegacy: allocationData.isLegacy, }) - // TODO: deprecated - // Collect query fees for this allocation - let isCollectingQueryFees = false - if (receiptCollector) { - isCollectingQueryFees = await receiptCollector.collectReceipts(0, allocationData) + let txHash: string + let rewardsAssigned: bigint + if (allocationData.isLegacy) { + logger.debug('Closing legacy allocation') + const result = await closeLegacyAllocation( + allocationData, + poiData.poi, + network, + logger, + ) + txHash = result.txHash + rewardsAssigned = result.rewardsAssigned + } else { + logger.debug('Closing horizon allocation') + const result = await closeHorizonAllocation( + allocationData, + poiData, + network, + logger, + ) + txHash = result.txHash + rewardsAssigned = result.rewardsAssigned } logger.debug( @@ -730,6 +1664,17 @@ export default { await models.IndexingRule.upsert(offchainIndexingRule) + const allocationManager = + actionManager?.allocationManagers[network.specification.networkIdentifier] + if (allocationManager?.dipsManager) { + await allocationManager.dipsManager.tryCancelAgreement(allocation) + await allocationManager.dipsManager.tryUpdateAgreementAllocation( + allocationData.subgraphDeployment.id.toString(), + toAddress(allocation), + null, + ) + } + // Since upsert succeeded, we _must_ have a rule const updatedRule = await models.IndexingRule.findOne({ where: { identifier: offchainIndexingRule.identifier }, @@ -742,11 +1687,10 @@ export default { return { actionID: 0, type: 'unallocate', - transactionID: receipt.transactionHash, - allocation: closeAllocationEventLogs.allocationID, - allocatedTokens: formatGRT(closeAllocationEventLogs.tokens), + transactionID: txHash, + allocation: allocation, + allocatedTokens: formatGRT(allocationData.allocatedTokens), indexingRewards: formatGRT(rewardsAssigned), - receiptsWorthCollecting: isCollectingQueryFees, protocolNetwork: network.specification.networkIdentifier, } } catch (error) { @@ -759,17 +1703,27 @@ export default { { allocation, poi, + blockNumber, + publicPOI, amount, force, protocolNetwork, }: { allocation: string poi: string | undefined + blockNumber: string | undefined + publicPOI: string | undefined amount: string force: boolean protocolNetwork: string }, - { logger, models, multiNetworks }: IndexerManagementResolverContext, + { + logger, + models, + multiNetworks, + graphNode, + actionManager, + }: IndexerManagementResolverContext, ): Promise => { logger = logger.child({ component: 'reallocateAllocationResolver', @@ -791,10 +1745,6 @@ export default { // Obtain the Network object and its associated components and data const network = extractNetwork(protocolNetwork, multiNetworks) const networkMonitor = network.networkMonitor - const contracts = network.contracts - const transactionManager = network.transactionManager - const receiptCollector = network.receiptCollector - const address = network.specification.indexerOptions.address const allocationAmount = parseGRT(amount) @@ -813,215 +1763,74 @@ export default { } try { - const currentEpoch = await contracts.epochManager.currentEpoch() - logger.debug('Resolving POI') - const allocationPOI = await networkMonitor.resolvePOI(allocationData, poi, force) + const poiData = await networkMonitor.resolvePOI( + allocationData, + poi, + publicPOI, + blockNumber === null ? undefined : Number(blockNumber), + force, + ) logger.debug('POI resolved', { userProvidedPOI: poi, - poi: allocationPOI, + userProvidedPublicPOI: publicPOI, + userProvidedBlockNumber: blockNumber, + poi: poiData.poi, + publicPOI: poiData.publicPOI, + blockNumber: poiData.blockNumber, + force, }) - // Double-check whether the allocation is still active on chain, to - // avoid unnecessary transactions. - // Note: We're checking the allocation state here, which is defined as - // - // enum AllocationState { Null, Active, Closed, Finalized } - // - // in the contracts. - const state = await contracts.staking.getAllocationState(allocationData.id) - if (state !== 1) { - logger.warn(`Allocation has already been closed`) - throw indexerError(IndexerErrorCode.IE065, `Allocation has already been closed`) - } - - if (allocationAmount.lt('0')) { - logger.warn('Cannot reallocate a negative amount of GRT', { - amount: allocationAmount.toString(), - }) - throw indexerError( - IndexerErrorCode.IE061, - 'Cannot reallocate a negative amount of GRT', - ) - } + const isHorizon = await network.isHorizon.value() - logger.info(`Reallocate to subgraph deployment`, { - existingAllocationAmount: formatGRT(allocationData.allocatedTokens), - newAllocationAmount: formatGRT(allocationAmount), - epoch: currentEpoch.toString(), + logger.debug('reallocateAllocation: Checking allocation resolution path', { + isHorizon, + allocationIsLegacy: allocationData.isLegacy, }) - // Identify how many GRT the indexer has staked - const freeStake = await contracts.staking.getIndexerCapacity(address) - - // When reallocating, we will first close the old allocation and free up the GRT in that allocation - // This GRT will be available in addition to freeStake for the new allocation - const postCloseFreeStake = freeStake.add(allocationData.allocatedTokens) - - // If there isn't enough left for allocating, abort - if (postCloseFreeStake.lt(allocationAmount)) { - throw indexerError( - IndexerErrorCode.IE013, - `Unable to allocate ${formatGRT( - allocationAmount, - )} GRT: indexer only has a free stake amount of ${formatGRT( - freeStake, - )} GRT, plus ${formatGRT( - allocationData.allocatedTokens, - )} GRT from the existing allocation`, + let txHash: string + let rewardsAssigned: bigint + let newAllocationId: Address + if (!isHorizon) { + logger.debug('Reallocating legacy allocation') + const result = await reallocateLegacyAllocation( + allocationData, + allocationAmount, + activeAllocations, + poiData.poi, + network, + logger, ) - } - - logger.debug('Generating a new unique Allocation ID') - const { allocationSigner, allocationId: newAllocationId } = uniqueAllocationID( - transactionManager.wallet.mnemonic.phrase, - currentEpoch.toNumber(), - allocationData.subgraphDeployment.id, - activeAllocations.map((allocation) => allocation.id), - ) - - logger.debug('New unique Allocation ID generated', { - newAllocationID: newAllocationId, - newAllocationSigner: allocationSigner, - }) - - // Double-check whether the allocationID already exists on chain, to - // avoid unnecessary transactions. - // Note: We're checking the allocation state here, which is defined as - // - // enum AllocationState { Null, Active, Closed, Finalized } - // - // in the contracts. - const newAllocationState = - await contracts.staking.getAllocationState(newAllocationId) - if (newAllocationState !== 0) { - logger.warn(`Skipping Allocation as it already exists onchain`, { - indexer: address, - allocation: newAllocationId, - newAllocationState, - }) - throw indexerError(IndexerErrorCode.IE066, 'AllocationID already exists') - } - - logger.debug('Generating new allocation ID proof', { - newAllocationSigner: allocationSigner, - newAllocationID: newAllocationId, - indexerAddress: address, - }) - const proof = await allocationIdProof(allocationSigner, address, newAllocationId) - logger.debug('Successfully generated allocation ID proof', { - allocationIDProof: proof, - }) - - logger.info(`Sending close and allocate multicall transaction`, { - indexer: address, - amount: formatGRT(allocationAmount), - oldAllocation: allocationData.id, - newAllocation: newAllocationId, - newAllocationAmount: formatGRT(allocationAmount), - deployment: allocationData.subgraphDeployment.id.toString(), - poi: allocationPOI, - proof, - epoch: currentEpoch.toString(), - }) - - const callData = [ - await contracts.staking.populateTransaction.closeAllocation( - allocationData.id, - allocationPOI, - ), - await contracts.staking.populateTransaction.allocateFrom( - address, - allocationData.subgraphDeployment.id.bytes32, + txHash = result.txHash + rewardsAssigned = result.rewardsAssigned + newAllocationId = result.newAllocationId + } else if (allocationData.isLegacy) { + logger.debug('Migrating legacy allocation to horizon') + const result = await migrateLegacyAllocationToHorizon( + allocationData, allocationAmount, - newAllocationId, - utils.hexlify(Array(32).fill(0)), // metadata - proof, - ), - ].map((tx) => tx.data as string) - - const receipt = await transactionManager.executeTransaction( - async () => contracts.staking.estimateGas.multicall(callData), - async (gasLimit) => contracts.staking.multicall(callData, { gasLimit }), - logger.child({ - function: 'closeAndAllocate', - }), - ) - - if (receipt === 'paused' || receipt === 'unauthorized') { - throw indexerError( - IndexerErrorCode.IE062, - `Allocation '${newAllocationId}' could not be closed: ${receipt}`, + activeAllocations, + poiData.poi, + network, + graphNode, + logger, ) - } - - const createAllocationEventLogs = transactionManager.findEvent( - 'AllocationCreated', - contracts.staking.interface, - 'subgraphDeploymentID', - allocationData.subgraphDeployment.id.toString(), - receipt, - logger, - ) - - if (!createAllocationEventLogs) { - throw indexerError(IndexerErrorCode.IE014, `Allocation was never mined`) - } - - const closeAllocationEventLogs = transactionManager.findEvent( - 'AllocationClosed', - contracts.staking.interface, - 'allocationID', - allocation, - receipt, - logger, - ) - - if (!closeAllocationEventLogs) { - throw indexerError( - IndexerErrorCode.IE015, - `Allocation close transaction was never successfully mined`, + txHash = result.txHash + rewardsAssigned = result.rewardsAssigned + newAllocationId = result.newAllocationId + } else { + logger.debug('Reallocating horizon allocation') + const result = await reallocateHorizonAllocation( + allocationData, + allocationAmount, + activeAllocations, + poiData, + network, + logger, ) - } - - const rewardsEventLogs = transactionManager.findEvent( - 'RewardsAssigned', - contracts.rewardsManager.interface, - 'allocationID', - allocation, - receipt, - logger, - ) - - const rewardsAssigned = rewardsEventLogs ? rewardsEventLogs.amount : 0 - - if (rewardsAssigned == 0) { - logger.warn('No rewards were distributed upon closing the allocation') - } - - logger.info(`Successfully reallocated allocation`, { - deployment: createAllocationEventLogs.subgraphDeploymentID, - closedAllocation: closeAllocationEventLogs.allocationID, - closedAllocationStakeGRT: formatGRT(closeAllocationEventLogs.tokens), - closedAllocationPOI: closeAllocationEventLogs.poi, - closedAllocationEpoch: closeAllocationEventLogs.epoch.toString(), - indexingRewardsCollected: rewardsAssigned, - createdAllocation: createAllocationEventLogs.allocationID, - createdAllocationStakeGRT: formatGRT(createAllocationEventLogs.tokens), - indexer: createAllocationEventLogs.indexer, - epoch: createAllocationEventLogs.epoch.toString(), - transaction: receipt.transactionHash, - }) - - logger.info('Identifying receipts worth collecting', { - allocation: closeAllocationEventLogs.allocationID, - }) - - // TODO: deprecated - let isCollectingQueryFees = false - if (receiptCollector) { - // Collect query fees for this allocation - isCollectingQueryFees = await receiptCollector.collectReceipts(0, allocationData) + txHash = result.txHash + rewardsAssigned = result.rewardsAssigned + newAllocationId = result.newAllocationId } logger.debug( @@ -1037,6 +1846,16 @@ export default { await models.IndexingRule.upsert(indexingRule) + const allocationManager = + actionManager?.allocationManagers[network.specification.networkIdentifier] + if (allocationManager?.dipsManager) { + await allocationManager.dipsManager.tryUpdateAgreementAllocation( + allocationData.subgraphDeployment.id.toString(), + toAddress(allocation), + toAddress(newAllocationId), + ) + } + // Since upsert succeeded, we _must_ have a rule const updatedRule = await models.IndexingRule.findOne({ where: { identifier: indexingRule.identifier }, @@ -1049,12 +1868,11 @@ export default { return { actionID: 0, type: 'reallocate', - transactionID: receipt.transactionHash, - closedAllocation: closeAllocationEventLogs.allocationID, + transactionID: txHash, + closedAllocation: allocation, indexingRewardsCollected: formatGRT(rewardsAssigned), - receiptsWorthCollecting: isCollectingQueryFees, - createdAllocation: createAllocationEventLogs.allocationID, - createdAllocationStake: formatGRT(createAllocationEventLogs.tokens), + createdAllocation: newAllocationId, + createdAllocationStake: formatGRT(allocationAmount), protocolNetwork, } } catch (error) { @@ -1062,52 +1880,4 @@ export default { throw error } }, - - // TODO: deprecated - submitCollectReceiptsJob: async ( - { - allocation, - protocolNetwork, - }: { - allocation: string - protocolNetwork: string - }, - { logger, multiNetworks }: IndexerManagementResolverContext, - ): Promise => { - logger.debug('Execute collectAllocationReceipts() mutation', { - allocationID: allocation, - protocolNetwork, - }) - if (!multiNetworks) { - throw Error( - 'IndexerManagementClient must be in `network` mode to collect receipts for an allocation', - ) - } - const network = extractNetwork(protocolNetwork, multiNetworks) - const networkMonitor = network.networkMonitor - const receiptCollector = network.receiptCollector - - const allocationData = await networkMonitor.allocation(allocation) - - try { - logger.info('Identifying receipts worth collecting', { - allocation: allocation, - }) - - // Collect query fees for this allocation - let collecting = false - if (receiptCollector) { - collecting = await receiptCollector.collectReceipts(0, allocationData) - } - - logger.info(`Submitted allocation receipt collection job for execution`, { - allocationID: allocation, - protocolNetwork: network.specification.networkIdentifier, - }) - return collecting - } catch (error) { - logger.error(error.toString()) - throw error - } - }, } diff --git a/packages/indexer-common/src/indexer-management/resolvers/indexer-status.ts b/packages/indexer-common/src/indexer-management/resolvers/indexer-status.ts index 3c3461d12..e8744997b 100644 --- a/packages/indexer-common/src/indexer-management/resolvers/indexer-status.ts +++ b/packages/indexer-common/src/indexer-management/resolvers/indexer-status.ts @@ -63,7 +63,7 @@ const URL_VALIDATION_TEST: Test = { export default { indexerRegistration: async ( { protocolNetwork: unvalidatedProtocolNetwork }: { protocolNetwork: string }, - { multiNetworks }: IndexerManagementResolverContext, + { multiNetworks, logger }: IndexerManagementResolverContext, ): Promise => { if (!multiNetworks) { throw Error( @@ -75,28 +75,58 @@ export default { const protocolNetwork = network.specification.networkIdentifier const address = network.specification.indexerOptions.address const contracts = network.contracts - const registered = await contracts.serviceRegistry.isRegistered(address) - if (registered) { - const service = await contracts.serviceRegistry.services(address) - return { - address, - protocolNetwork, - url: service.url, - location: geohash.decode(service.geohash), - registered, - __typename: 'IndexerRegistration', + const registrationInfo: RegistrationInfo[] = [] + + // Check if the indexer is registered in the legacy service registry + try { + const registered = await contracts.LegacyServiceRegistry.isRegistered(address) + if (registered) { + const service = await contracts.LegacyServiceRegistry.services(address) + registrationInfo.push({ + address, + protocolNetwork, + url: service.url, + location: geohash.decode(service.geoHash), + registered, + isLegacy: true, + __typename: 'IndexerRegistration', + }) + } + } catch (e) { + logger?.debug( + `Could not get legacy service registration for indexer. It's likely that the legacy protocol is not reachable.`, + ) + } + + if (await network.isHorizon.value()) { + const service = await contracts.SubgraphService.indexers(address) + if (service.registeredAt !== 0n) { + registrationInfo.push({ + address, + protocolNetwork, + url: service.url, + location: geohash.decode(service.geoHash), + registered: true, + isLegacy: false, + __typename: 'IndexerRegistration', + }) } - } else { - return { + } + + if (registrationInfo.length === 0) { + registrationInfo.push({ address, url: null, - registered, + registered: false, + isLegacy: false, protocolNetwork, location: null, __typename: 'IndexerRegistration', - } + }) } + + return registrationInfo }, indexerDeployments: async ( @@ -218,8 +248,21 @@ export default { return } try { - const networkEndpoints = await endpointForNetwork(network) - endpoints.push(networkEndpoints) + // Always try to get legacy endpoints, but fail gracefully if they don't exist + try { + const networkEndpoints = await endpointForNetwork(network, false) + endpoints.push(networkEndpoints) + } catch (e) { + logger?.debug( + `Could not get legacy service endpoints for network. It's likely that the legacy protocol is not reachable.`, + ) + } + + // Only get horizon endpoints when horizon is enabled + if (await network.isHorizon.value()) { + const networkEndpoints = await endpointForNetwork(network, true) + endpoints.push(networkEndpoints) + } } catch (err) { // Ignore endpoints for this network logger?.warn(`Failed to detect service endpoints for network`, { @@ -232,12 +275,24 @@ export default { }, } +interface RegistrationInfo { + address: string + protocolNetwork: string + url: string | null + location: { latitude: number; longitude: number } | null + registered: boolean + __typename: 'IndexerRegistration' + isLegacy: boolean +} + interface Endpoint { + name: string | null url: string | null healthy: boolean protocolNetwork: string // eslint-disable-next-line @typescript-eslint/no-explicit-any tests: any[] + isLegacy: boolean } interface Endpoints { @@ -245,26 +300,45 @@ interface Endpoints { status: Endpoint } -function defaultEndpoint(protocolNetwork: string): Endpoint { +function defaultEndpoint( + protocolNetwork: string, + name: string, + isLegacy: boolean, +): Endpoint { return { + name, url: null as string | null, healthy: false, protocolNetwork, tests: [] as TestResult[], + isLegacy, } } -function defaultEndpoints(protocolNetwork: string): Endpoints { +function defaultEndpoints(protocolNetwork: string, isHorizon: boolean): Endpoints { return { - service: defaultEndpoint(protocolNetwork), - status: defaultEndpoint(protocolNetwork), + service: defaultEndpoint( + protocolNetwork, + isHorizon ? 'service' : 'legacy-service', + !isHorizon, + ), + status: defaultEndpoint( + protocolNetwork, + isHorizon ? 'status' : 'legacy-status', + !isHorizon, + ), } } -async function endpointForNetwork(network: Network): Promise { +async function endpointForNetwork( + network: Network, + isHorizon: boolean, +): Promise { const contracts = network.contracts const address = network.specification.indexerOptions.address - const endpoints = defaultEndpoints(network.specification.networkIdentifier) - const service = await contracts.serviceRegistry.services(address) + const endpoints = defaultEndpoints(network.specification.networkIdentifier, isHorizon) + const service = isHorizon + ? await contracts.SubgraphService.indexers(address) + : await contracts.LegacyServiceRegistry.services(address) if (service) { { const { url, tests, ok } = await testURL(service.url, [ diff --git a/packages/indexer-common/src/indexer-management/resolvers/indexing-rules.ts b/packages/indexer-common/src/indexer-management/resolvers/indexing-rules.ts index acaa5021c..2adcdfe8e 100644 --- a/packages/indexer-common/src/indexer-management/resolvers/indexing-rules.ts +++ b/packages/indexer-common/src/indexer-management/resolvers/indexing-rules.ts @@ -9,9 +9,10 @@ import { import { IndexerManagementDefaults, IndexerManagementResolverContext } from '../client' import { Transaction } from 'sequelize' import { fetchIndexingRules } from '../rules' -import { processIdentifier } from '../../' +import { ensureAllocationLifetime, processIdentifier } from '../../' import { validateNetworkIdentifier } from '../../parsers' import groupBy from 'lodash.groupby' +import { extractNetwork } from './utils' const resetGlobalRule = async ( ruleIdentifier: IndexingRuleIdentifier, @@ -77,7 +78,7 @@ export default { setIndexingRule: async ( { rule }: { rule: IndexingRuleCreationAttributes }, - { models }: IndexerManagementResolverContext, + { multiNetworks, models }: IndexerManagementResolverContext, ): Promise => { if (!rule.identifier) { throw Error('Cannot set indexingRule without identifier') @@ -93,6 +94,20 @@ export default { } } + if (!multiNetworks) { + throw Error( + 'IndexerManagementClient must be in `network` mode to set indexing rules', + ) + } + const network = extractNetwork(rule.protocolNetwork, multiNetworks) + + const [isValid, maxSuggestedLifetime] = await ensureAllocationLifetime(rule, network) + if (!isValid) { + throw Error( + `Allocation lifetime must be at most ${maxSuggestedLifetime} epochs, otherwise indexing rewards will be forefited.`, + ) + } + const [identifier] = await processIdentifier(rule.identifier, { all: false, global: true, diff --git a/packages/indexer-common/src/indexer-management/resolvers/provisions.ts b/packages/indexer-common/src/indexer-management/resolvers/provisions.ts new file mode 100644 index 000000000..cf45ef8f6 --- /dev/null +++ b/packages/indexer-common/src/indexer-management/resolvers/provisions.ts @@ -0,0 +1,642 @@ +import { indexerError, IndexerErrorCode, Network } from '@graphprotocol/indexer-common' +/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ +/* eslint-disable @typescript-eslint/ban-types */ + +import gql from 'graphql-tag' + +import { IndexerManagementResolverContext } from '@graphprotocol/indexer-common' +import { extractNetwork } from './utils' +import { formatGRT, parseGRT } from '@graphprotocol/common-ts' +import { ThawRequestType } from '@graphprotocol/toolshed' + +enum ProvisionQuery { + all = 'all', + thawRequests = 'thawRequests', +} + +interface ProvisionInfo { + id: string + dataService: string + indexer: string + tokensProvisioned: string + tokensAllocated: string + tokensThawing: string + maxVerifierCut: string + thawingPeriod: string + protocolNetwork: string + idleStake: string +} + +interface AddToProvisionResult { + id: string + dataService: string + indexer: string + tokensProvisioned: string + protocolNetwork: string +} + +interface ThawFromProvisionResult { + id: string + dataService: string + indexer: string + tokensThawing: string + thawingPeriod: string + thawingUntil: string + protocolNetwork: string +} + +interface ThawRequestInfo { + id: string + fulfilled: string + dataService: string + indexer: string + shares: string + thawingUntil: string + currentBlockTimestamp: string +} + +interface RemoveFromProvisionResult { + id: string + dataService: string + indexer: string + tokensProvisioned: string + tokensThawing: string + tokensRemoved: string + protocolNetwork: string +} + +const PROVISION_QUERIES = { + // No need to paginate, there can only be one provision per (indexer, dataService) pair + [ProvisionQuery.all]: gql` + query provisions($indexer: String!, $dataService: String!) { + provisions( + where: { indexer: $indexer, dataService: $dataService } + orderBy: id + orderDirection: asc + first: 1000 + ) { + id + indexer { + id + } + dataService { + id + } + tokensProvisioned + tokensAllocated + tokensThawing + thawingPeriod + maxVerifierCut + } + } + `, + // No need to paginate, there can be at most 1000 thaw requests for any given (indexer, dataService) pair + [ProvisionQuery.thawRequests]: gql` + query thawRequests($indexer: String!, $dataService: String!) { + thawRequests( + where: { indexer: $indexer, dataService: $dataService, owner: $indexer } + orderBy: thawingUntil + orderDirection: asc + first: 1000 + ) { + id + fulfilled + shares + thawingUntil + } + } + `, +} + +export default { + provisions: async ( + { + protocolNetwork, + }: { + protocolNetwork: string + }, + { multiNetworks, logger }: IndexerManagementResolverContext, + ): Promise => { + logger.debug('Execute provisions() query', { + protocolNetwork, + }) + + if (!multiNetworks) { + throw Error('IndexerManagementClient must be in `network` mode to fetch provisions') + } + + const network = extractNetwork(protocolNetwork, multiNetworks) + + if (!(await network.isHorizon.value())) { + throw indexerError(IndexerErrorCode.IE082) + } + + const indexer = network.specification.indexerOptions.address.toLowerCase() + const dataService = network.contracts.SubgraphService.target.toString().toLowerCase() + const idleStake = await network.contracts.HorizonStaking.getIdleStake(indexer) + + const provisionsByNetwork = await multiNetworks.map( + async (network: Network): Promise => { + // Return early if a different protocol network is specifically requested + if ( + protocolNetwork && + protocolNetwork !== network.specification.networkIdentifier + ) { + return [] + } + + const { networkSubgraph } = network + + logger.trace('Query Provisions', { + indexer, + dataService, + }) + + const result = await networkSubgraph.checkedQuery(PROVISION_QUERIES.all, { + indexer, + dataService, + }) + + if (result.error) { + logger.error('Querying provisions failed', { + error: result.error, + }) + } + + return result.data.provisions.map((provision) => ({ + id: provision.id, + dataService, + indexer, + tokensProvisioned: provision.tokensProvisioned, + tokensAllocated: provision.tokensAllocated, + tokensThawing: provision.tokensThawing, + maxVerifierCut: provision.maxVerifierCut, + thawingPeriod: provision.thawingPeriod, + protocolNetwork: network.specification.networkIdentifier, + idleStake: idleStake.toString(), + })) + }, + ) + + return Object.values(provisionsByNetwork).flat() + }, + addToProvision: async ( + { + protocolNetwork, + amount, + }: { + protocolNetwork: string + amount: string + }, + { multiNetworks, logger }: IndexerManagementResolverContext, + ): Promise => { + logger.debug('Execute addToProvision() mutation', { + protocolNetwork, + amount, + }) + + if (!multiNetworks) { + throw Error( + 'IndexerManagementClient must be in `network` mode to add stake to a provision', + ) + } + + const network = extractNetwork(protocolNetwork, multiNetworks) + const networkMonitor = network.networkMonitor + const contracts = network.contracts + const transactionManager = network.transactionManager + + if (!(await network.isHorizon.value())) { + throw indexerError(IndexerErrorCode.IE082) + } + + const indexer = network.specification.indexerOptions.address.toLowerCase() + const dataService = contracts.SubgraphService.target.toString().toLowerCase() + const provisionAmount = parseGRT(amount) + + if (provisionAmount < 0n) { + logger.warn('Cannot add a negative amount of GRT', { + amount: formatGRT(provisionAmount), + }) + throw indexerError( + IndexerErrorCode.IE079, + `Invalid stake amount provided (${amount.toString()}). Must use positive stake amount`, + ) + } + + try { + // Check if the provision exists - this will throw if it doesn't + const provision = await networkMonitor.provision(indexer, dataService) + + logger.debug('Provision found', { + provision, + }) + + logger.debug(`Sending addToProvision transaction`, { + indexer: indexer, + dataService: dataService, + amount: formatGRT(provisionAmount), + protocolNetwork, + }) + + const receipt = await transactionManager.executeTransaction( + async () => + contracts.HorizonStaking.addToProvision.estimateGas( + indexer, + dataService, + provisionAmount, + ), + async (gasLimit) => + contracts.HorizonStaking.addToProvision(indexer, dataService, provisionAmount, { + gasLimit, + }), + logger.child({ action: 'addToProvision' }), + ) + + if (receipt === 'paused' || receipt === 'unauthorized') { + throw indexerError( + IndexerErrorCode.IE062, + `Stake not added to provision. ${ + receipt === 'paused' ? 'Network paused' : 'Operator not authorized' + }`, + ) + } + + const addToProvisionEventLogs = network.transactionManager.findEvent( + 'ProvisionIncreased', + network.contracts.HorizonStaking.interface, + 'tokens', + provisionAmount.toString(), + receipt, + logger, + ) + + if (!addToProvisionEventLogs) { + throw indexerError( + IndexerErrorCode.IE080, + `Add to provision transaction was never mined`, + ) + } + + logger.info(`Successfully added stake to provision`, { + amountGRT: formatGRT(addToProvisionEventLogs.tokens), + transaction: receipt.hash, + }) + + return { + id: provision.id, + dataService, + indexer, + tokensProvisioned: (provision.tokensProvisioned + provisionAmount).toString(), // TODO: we could re-fetch the provision instead + protocolNetwork: network.specification.networkIdentifier, + } + } catch (error) { + logger.error('Failed to add stake to provision', { + amount: formatGRT(provisionAmount), + error, + }) + throw error + } + }, + thawFromProvision: async ( + { + protocolNetwork, + amount, + }: { + protocolNetwork: string + amount: string + }, + { multiNetworks, logger }: IndexerManagementResolverContext, + ): Promise => { + logger.debug('Execute thawFromProvision() mutation', { + protocolNetwork, + amount, + }) + + if (!multiNetworks) { + throw Error( + 'IndexerManagementClient must be in `network` mode to add stake to a provision', + ) + } + + const network = extractNetwork(protocolNetwork, multiNetworks) + const networkMonitor = network.networkMonitor + const contracts = network.contracts + const transactionManager = network.transactionManager + + if (!(await network.isHorizon.value())) { + throw indexerError(IndexerErrorCode.IE082) + } + + const indexer = network.specification.indexerOptions.address.toLowerCase() + const dataService = contracts.SubgraphService.target.toString().toLowerCase() + const thawAmount = parseGRT(amount) + + if (thawAmount <= 0n) { + logger.warn('Cannot thaw zero or a negative amount of GRT', { + amount: formatGRT(thawAmount), + }) + throw indexerError( + IndexerErrorCode.IE083, + `Invalid stake amount provided (${amount.toString()}). Must use positive stake amount`, + ) + } + + try { + // Check if the provision exists - this will throw if it doesn't + const provision = await networkMonitor.provision(indexer, dataService) + + logger.debug('Provision found', { + provision, + }) + + const tokensAvailable = await contracts.HorizonStaking.getProviderTokensAvailable( + indexer, + dataService, + ) + + if (thawAmount > tokensAvailable) { + throw indexerError( + IndexerErrorCode.IE083, + `Cannot thaw more stake than is available in the provision: thaw amount (${formatGRT( + thawAmount, + )}) > tokens available (${formatGRT(tokensAvailable)})`, + ) + } + + logger.debug(`Sending thawFromProvision transaction`, { + indexer: indexer, + dataService: dataService, + amount: formatGRT(thawAmount), + protocolNetwork, + }) + + const receipt = await transactionManager.executeTransaction( + async () => + contracts.HorizonStaking.thaw.estimateGas(indexer, dataService, thawAmount), + async (gasLimit) => + contracts.HorizonStaking.thaw(indexer, dataService, thawAmount, { + gasLimit, + }), + logger.child({ action: 'thawFromProvision' }), + ) + + if (receipt === 'paused' || receipt === 'unauthorized') { + throw indexerError( + IndexerErrorCode.IE062, + `Stake not thawed from provision. ${ + receipt === 'paused' ? 'Network paused' : 'Operator not authorized' + }`, + ) + } + + const thawFromProvisionEventLogs = network.transactionManager.findEvent( + 'ProvisionThawed', + network.contracts.HorizonStaking.interface, + 'tokens', + thawAmount.toString(), + receipt, + logger, + ) + + if (!thawFromProvisionEventLogs) { + throw indexerError( + IndexerErrorCode.IE083, + `Thaw from provision transaction was never mined`, + ) + } + + const thawRequestCreatedTopic = + network.contracts.HorizonStaking.interface.getEvent( + 'ThawRequestCreated', + ).topicHash + const thawRequestCreatedLog = receipt.logs.filter((log) => + log.topics.includes(thawRequestCreatedTopic), + )[0] + const thawRequestCreatedEvent = + network.contracts.HorizonStaking.interface.decodeEventLog( + network.contracts.HorizonStaking.interface.getEvent('ThawRequestCreated'), + thawRequestCreatedLog.data, + thawRequestCreatedLog.topics, + ) + + logger.info(`Successfully thawed stake from provision`, { + amountGRT: formatGRT(thawFromProvisionEventLogs.tokens), + thawingUntil: thawRequestCreatedEvent.thawingUntil, + transaction: receipt.hash, + }) + + return { + id: provision.id, + dataService, + indexer, + tokensThawing: (provision.tokensThawing + thawAmount).toString(), // TODO: we could re-fetch the provision instead + thawingPeriod: provision.thawingPeriod.toString(), + thawingUntil: thawRequestCreatedEvent.thawingUntil.toString(), + protocolNetwork: network.specification.networkIdentifier, + } + } catch (error) { + logger.error('Failed to thaw stake from provision', { + amount: formatGRT(thawAmount), + error, + }) + throw error + } + }, + thawRequests: async ( + { + protocolNetwork, + }: { + protocolNetwork: string + }, + { multiNetworks, logger }: IndexerManagementResolverContext, + ): Promise => { + logger.debug('Execute thawRequests() query', { + protocolNetwork, + }) + + if (!multiNetworks) { + throw Error('IndexerManagementClient must be in `network` mode to fetch provisions') + } + + const network = extractNetwork(protocolNetwork, multiNetworks) + + if (!(await network.isHorizon.value())) { + throw indexerError(IndexerErrorCode.IE082) + } + + const indexer = network.specification.indexerOptions.address.toLowerCase() + const dataService = network.contracts.SubgraphService.target.toString().toLowerCase() + + const thawRequestsByNetwork = await multiNetworks.map( + async (network: Network): Promise => { + // Return early if a different protocol network is specifically requested + if ( + protocolNetwork && + protocolNetwork !== network.specification.networkIdentifier + ) { + return [] + } + + const { networkSubgraph } = network + + logger.trace('Query Thaw Requests', { + indexer, + dataService, + }) + + const result = await networkSubgraph.checkedQuery( + PROVISION_QUERIES.thawRequests, + { + indexer, + dataService, + }, + ) + + if (result.error) { + logger.error('Querying thaw requests failed', { + error: result.error, + }) + } + + const currentBlockTimestamp = + (await network.networkProvider.getBlock('latest'))?.timestamp ?? 0 + + return result.data.thawRequests.map((thawRequest) => ({ + id: thawRequest.id, + fulfilled: thawRequest.fulfilled, + dataService, + indexer, + shares: thawRequest.shares, + thawingUntil: thawRequest.thawingUntil, + currentBlockTimestamp: currentBlockTimestamp.toString(), + protocolNetwork: network.specification.networkIdentifier, + })) + }, + ) + + return Object.values(thawRequestsByNetwork).flat() + }, + removeFromProvision: async ( + { + protocolNetwork, + }: { + protocolNetwork: string + }, + { multiNetworks, logger }: IndexerManagementResolverContext, + ): Promise => { + logger.debug('Execute removeFromProvision() mutation', { + protocolNetwork, + }) + + if (!multiNetworks) { + throw Error( + 'IndexerManagementClient must be in `network` mode to add stake to a provision', + ) + } + + const network = extractNetwork(protocolNetwork, multiNetworks) + const networkMonitor = network.networkMonitor + const contracts = network.contracts + const transactionManager = network.transactionManager + + if (!(await network.isHorizon.value())) { + throw indexerError(IndexerErrorCode.IE082) + } + + const indexer = network.specification.indexerOptions.address.toLowerCase() + const dataService = contracts.SubgraphService.target.toString().toLowerCase() + + try { + // Check if the provision exists - this will throw if it doesn't + const provision = await networkMonitor.provision(indexer, dataService) + + logger.debug('Provision found', { + provision, + }) + + const thawedTokens = await contracts.HorizonStaking.getThawedTokens( + ThawRequestType.Provision, + indexer, + dataService, + indexer, + ) + + // return early if there are no expired thaw requests + if (thawedTokens === 0n) { + return { + id: provision.id, + dataService, + indexer, + tokensProvisioned: provision.tokensProvisioned.toString(), + tokensThawing: provision.tokensThawing.toString(), + tokensRemoved: '0', + protocolNetwork: network.specification.networkIdentifier, + } + } + + logger.debug(`Sending deprovision transaction`, { + indexer: indexer, + dataService: dataService, + protocolNetwork, + }) + + // deprovision all expired thaw requests + const receipt = await transactionManager.executeTransaction( + async () => + contracts.HorizonStaking.deprovision.estimateGas(indexer, dataService, 0), + async (gasLimit) => + contracts.HorizonStaking.deprovision(indexer, dataService, 0, { + gasLimit, + }), + logger.child({ action: 'deprovision' }), + ) + + if (receipt === 'paused' || receipt === 'unauthorized') { + throw indexerError( + IndexerErrorCode.IE062, + `Stake not thawed from provision. ${ + receipt === 'paused' ? 'Network paused' : 'Operator not authorized' + }`, + ) + } + + const thawFromProvisionEventLogs = network.transactionManager.findEvent( + 'TokensDeprovisioned', + network.contracts.HorizonStaking.interface, + 'serviceProvider', + indexer.toString(), + receipt, + logger, + ) + + if (!thawFromProvisionEventLogs) { + throw indexerError( + IndexerErrorCode.IE083, + `Thaw from provision transaction was never mined`, + ) + } + + logger.info(`Successfully deprovisioned stake from provision`, { + amountGRT: formatGRT(thawFromProvisionEventLogs.tokens), + thawedTokens: thawedTokens.toString(), + transaction: receipt.hash, + }) + + return { + id: provision.id, + dataService, + indexer, + tokensProvisioned: provision.tokensProvisioned.toString(), + tokensThawing: (provision.tokensThawing - thawedTokens).toString(), // TODO: we could re-fetch the provision instead + tokensRemoved: thawedTokens.toString(), + protocolNetwork: network.specification.networkIdentifier, + } + } catch (error) { + logger.error('Failed to deprovision stake from provision', { + error, + }) + throw error + } + }, +} diff --git a/packages/indexer-common/src/indexer-management/rules.ts b/packages/indexer-common/src/indexer-management/rules.ts index 656dd532b..55a4d0ccd 100644 --- a/packages/indexer-common/src/indexer-management/rules.ts +++ b/packages/indexer-common/src/indexer-management/rules.ts @@ -1,12 +1,85 @@ -import { Logger } from '@graphprotocol/common-ts' +import { Eventual, join, Logger } from '@graphprotocol/common-ts' import { IndexerManagementModels, INDEXING_RULE_GLOBAL, IndexingRule, IndexingRuleAttributes, + MultiNetworks, + Network, + sequentialTimerMap, } from '@graphprotocol/indexer-common' import { parseIndexingRule } from '../rules' import groupBy from 'lodash.groupby' +import { extractNetwork } from './resolvers/utils' +import { IndexingRuleCreationAttributes } from './models' + +export class RulesManager { + declare multiNetworks: MultiNetworks + declare models: IndexerManagementModels + declare logger: Logger + + static async create( + multiNetworks: MultiNetworks, + logger: Logger, + models: IndexerManagementModels, + ) { + const rulesManager = new RulesManager() + rulesManager.multiNetworks = multiNetworks + rulesManager.logger = logger + rulesManager.models = models + + logger.info('Begin monitoring indexing rules for invalid allocation lifetimes') + await rulesManager.monitorRules() + + return rulesManager + } + + async monitorRules(): Promise { + const logger = this.logger.child({ component: 'RulesMonitor' }) + const rules: Eventual = sequentialTimerMap( + { + logger, + milliseconds: 30_000, + }, + async () => { + logger.trace('Fetching indexing rules') + let rules: IndexingRuleAttributes[] = [] + try { + rules = await fetchIndexingRules(this.models, true) + logger.trace(`Fetched ${rules.length} indexing rules`) + } catch (err) { + logger.warn('Failed to fetch indexing rules', { err }) + } + + return rules + }, + { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + onError: (err: any) => logger.warn('Failed to fetch indexing rules', { err }), + }, + ) + + join({ rules }).pipe(async ({ rules }) => { + logger.info(`Indexing rules found, evaluating allocation lifetime`) + for (const rule of rules) { + const network = extractNetwork(rule.protocolNetwork, this.multiNetworks) + const [isValid, maxSuggestedLifetime] = await ensureAllocationLifetime( + rule, + network, + ) + if (!isValid) { + logger.warn(`Invalid rule allocation lifetime. Indexing rewards at risk!`, { + maxLifetime: maxSuggestedLifetime, + ruleId: rule.id, + ruleIdentifier: rule.identifier, + ruleAllocationAmount: rule.allocationAmount, + ruleAllocationLifetime: rule.allocationLifetime, + }) + } + } + }) + } +} export const fetchIndexingRules = async ( models: IndexerManagementModels, @@ -56,3 +129,30 @@ export const upsertIndexingRule = async ( // eslint-disable-next-line @typescript-eslint/no-non-null-assertion return updatedRule! } + +// Enforce max allocation lifetime for Horizon +// This is to prevent indexing rewards from being automatically forefited due to a too long allocation lifetime +// Previously this was not enforced onchain, but anyone could force close expired allocations +export const ensureAllocationLifetime = async ( + rule: IndexingRuleAttributes | IndexingRuleCreationAttributes, + network: Network, +): Promise<[boolean, number]> => { + if (rule.allocationLifetime) { + const maxAllocationDuration = await network.networkMonitor.maxAllocationDuration() + const isHorizon = await network.isHorizon.value() + + if (isHorizon) { + // Don't enforce for altruistic allocations + if ( + rule.allocationLifetime > maxAllocationDuration.horizon && + (rule.allocationAmount === undefined || + rule.allocationAmount === null || + Number(rule.allocationAmount) > 0) + ) { + return [false, maxAllocationDuration.horizon] + } + } + } + + return [true, 0] +} diff --git a/packages/indexer-common/src/indexer-management/types.ts b/packages/indexer-common/src/indexer-management/types.ts index dee5caa3b..05a9d3f6e 100644 --- a/packages/indexer-common/src/indexer-management/types.ts +++ b/packages/indexer-common/src/indexer-management/types.ts @@ -4,10 +4,10 @@ import { SubgraphDeploymentID, toAddress, } from '@graphprotocol/common-ts' -import { BigNumber } from 'ethers' -import { Allocation } from '../allocations' +import { Allocation, Provision } from '../allocations' import { GraphNode } from '../graph-node' import { SubgraphDeployment } from '../types' +import { TransactionReceipt } from 'ethers' /* eslint-disable @typescript-eslint/no-explicit-any */ let registry: any @@ -34,7 +34,6 @@ export interface CloseAllocationResult { allocation: string allocatedTokens: string indexingRewards: string - receiptsWorthCollecting: boolean protocolNetwork: string } @@ -44,12 +43,23 @@ export interface ReallocateAllocationResult { transactionID: string | undefined closedAllocation: string indexingRewardsCollected: string - receiptsWorthCollecting: boolean createdAllocation: string createdAllocationStake: string protocolNetwork: string } +export interface ActionExecutionResult { + actionID: number + success: boolean + result: AllocationResult +} + +export interface ExecuteTransactionResult { + actionID: number + success: boolean + result: ActionFailure | TransactionReceipt | 'paused' | 'unauthorized' +} + export interface ActionFailure { actionID: number transactionID?: string @@ -61,6 +71,11 @@ export interface ActionFailure { export const isActionFailure = (variableToCheck: any): variableToCheck is ActionFailure => 'failureReason' in variableToCheck +export const isActionFailureArray = ( + variableToCheck: any, +): variableToCheck is ActionFailure[] => + Array.isArray(variableToCheck) && variableToCheck.every(isActionFailure) + export type AllocationResult = | CreateAllocationResult | CloseAllocationResult @@ -74,9 +89,9 @@ export const parseGraphQLSubgraphDeployment = ( ): SubgraphDeployment => ({ id: new SubgraphDeploymentID(subgraphDeployment.id), deniedAt: subgraphDeployment.deniedAt, - stakedTokens: BigNumber.from(subgraphDeployment.stakedTokens), - signalledTokens: BigNumber.from(subgraphDeployment.signalledTokens), - queryFeesAmount: BigNumber.from(subgraphDeployment.queryFeesAmount), + stakedTokens: BigInt(subgraphDeployment.stakedTokens), + signalledTokens: BigInt(subgraphDeployment.signalledTokens), + queryFeesAmount: BigInt(subgraphDeployment.queryFeesAmount), protocolNetwork, }) @@ -88,18 +103,21 @@ export const parseGraphQLAllocation = ( // Ensure the allocation ID (an address) is checksummed id: toAddress(allocation.id), status: allocation.status, + isLegacy: allocation.isLegacy, subgraphDeployment: { id: new SubgraphDeploymentID(allocation.subgraphDeployment.id), deniedAt: allocation.subgraphDeployment.deniedAt, - stakedTokens: BigNumber.from(allocation.subgraphDeployment.stakedTokens), - signalledTokens: BigNumber.from(allocation.subgraphDeployment.signalledTokens), - queryFeesAmount: BigNumber.from(allocation.subgraphDeployment.queryFeesAmount), + stakedTokens: BigInt(allocation.subgraphDeployment.stakedTokens), + signalledTokens: BigInt(allocation.subgraphDeployment.signalledTokens), + queryFeesAmount: BigInt(allocation.subgraphDeployment.queryFeesAmount), protocolNetwork, }, indexer: toAddress(allocation.indexer.id), - allocatedTokens: BigNumber.from(allocation.allocatedTokens), + allocatedTokens: BigInt(allocation.allocatedTokens), + createdAt: allocation.createdAt, createdAtBlockHash: allocation.createdAtBlockHash, createdAtEpoch: allocation.createdAtEpoch, + closedAt: allocation.closedAt, closedAtEpoch: allocation.closedAtEpoch, closedAtEpochStartBlockHash: undefined, previousEpochStartBlockHash: undefined, @@ -109,6 +127,17 @@ export const parseGraphQLAllocation = ( queryFeesCollected: allocation.queryFeesCollected, }) +export const parseGraphQLProvision = (provision: any): Provision => ({ + id: provision.id.toString(), + dataService: toAddress(provision.dataService), + indexer: toAddress(provision.indexer), + tokensProvisioned: BigInt(provision.tokensProvisioned), + tokensAllocated: BigInt(provision.tokensAllocated), + tokensThawing: BigInt(provision.tokensThawing), + maxVerifierCut: BigInt(provision.maxVerifierCut), + thawingPeriod: BigInt(provision.thawingPeriod), +}) + export interface RewardsPool { subgraphDeployment: SubgraphDeploymentID allocationIndexer: Address @@ -355,3 +384,17 @@ export function networkIsL2(networkIdentifier: string): boolean { networkIdentifier = resolveChainId(networkIdentifier) return networkIdentifier === 'eip155:42161' || networkIdentifier === 'eip155:421614' } + +export enum IndexingStatusCode { + Unknown = 0, + Healthy = 1, + Unhealthy = 2, + Failed = 3, +} + +export interface POIData { + poi: string + publicPOI: string + blockNumber: number + indexingStatus: IndexingStatusCode +} diff --git a/packages/indexer-common/src/indexing-fees/__tests__/dips.test.ts b/packages/indexer-common/src/indexing-fees/__tests__/dips.test.ts new file mode 100644 index 000000000..3fe1d46b5 --- /dev/null +++ b/packages/indexer-common/src/indexing-fees/__tests__/dips.test.ts @@ -0,0 +1,586 @@ +import { + DipsManager, + GraphNode, + IndexerManagementModels, + Network, + QueryFeeModels, + defineIndexerManagementModels, + defineQueryFeeModels, + SubgraphIdentifierType, + IndexingDecisionBasis, + AllocationManager, + DipsCollector, + TapCollector, + createIndexerManagementClient, + Operator, + ActionManager, + IndexerManagementClient, + MultiNetworks, +} from '@graphprotocol/indexer-common' +import { + connectDatabase, + createLogger, + createMetrics, + Logger, + Metrics, + parseGRT, + SubgraphDeploymentID, + toAddress, +} from '@graphprotocol/common-ts' +import { Sequelize } from 'sequelize' +import { testNetworkSpecification } from '../../indexer-management/__tests__/util' +import { CollectPaymentStatus } from '@graphprotocol/dips-proto/generated/gateway' + +// Make global Jest variables available +// eslint-disable-next-line @typescript-eslint/no-explicit-any +declare const __DATABASE__: any +declare const __LOG_LEVEL__: never + +// Add these type declarations after the existing imports +let sequelize: Sequelize +let logger: Logger +let metrics: Metrics +let graphNode: GraphNode +let managementModels: IndexerManagementModels +let queryFeeModels: QueryFeeModels +let network: Network +let multiNetworks: MultiNetworks +let dipsCollector: DipsCollector +let indexerManagementClient: IndexerManagementClient +let operator: Operator +const networkSpecWithDips = { + ...testNetworkSpecification, + indexerOptions: { + ...testNetworkSpecification.indexerOptions, + enableDips: true, + dipperEndpoint: 'https://test-dipper-endpoint.xyz', + dipsAllocationAmount: parseGRT('1.0'), // Amount of GRT to allocate for DIPs + dipsEpochsMargin: 1, // Optional: Number of epochs margin for DIPs + }, +} + +const mockSubgraphDeployment = (id: string) => { + return { + id: new SubgraphDeploymentID(id), + ipfsHash: id, + deniedAt: null, + stakedTokens: 1000n, + signalledTokens: 1000n, + queryFeesAmount: 0n, + protocolNetwork: 'eip155:421614', + } +} + +jest.spyOn(TapCollector.prototype, 'startRAVProcessing').mockImplementation(() => {}) +const startCollectionLoop = jest + .spyOn(DipsCollector.prototype, 'startCollectionLoop') + .mockImplementation(() => {}) +jest.spyOn(ActionManager.prototype, 'monitorQueue').mockImplementation(async () => {}) +const setup = async () => { + logger = createLogger({ + name: 'DIPs Test Logger', + async: false, + level: __LOG_LEVEL__ ?? 'error', + }) + metrics = createMetrics() + // Clearing the registry prevents duplicate metric registration in the default registry. + metrics.registry.clear() + + graphNode = new GraphNode( + logger, + 'https://test-admin-endpoint.xyz', + 'https://test-query-endpoint.xyz', + 'https://test-status-endpoint.xyz', + 'https://test-ipfs-endpoint.xyz', + ) + + sequelize = await connectDatabase(__DATABASE__) + managementModels = defineIndexerManagementModels(sequelize) + queryFeeModels = defineQueryFeeModels(sequelize) + sequelize = await sequelize.sync({ force: true }) + + network = await Network.create( + logger, + networkSpecWithDips, + managementModels, + queryFeeModels, + graphNode, + metrics, + ) + + multiNetworks = new MultiNetworks( + [network], + (n: Network) => n.specification.networkIdentifier, + ) + + dipsCollector = network.dipsCollector! + indexerManagementClient = await createIndexerManagementClient({ + models: managementModels, + graphNode, + logger, + defaults: { + globalIndexingRule: { + allocationAmount: parseGRT('1000'), + parallelAllocations: 1, + }, + }, + multiNetworks, + }) + + operator = new Operator(logger, indexerManagementClient, networkSpecWithDips) +} + +const ensureGlobalIndexingRule = async () => { + await operator.ensureGlobalIndexingRule() + logger.debug('Ensured global indexing rule') +} + +const setupEach = async () => { + sequelize = await sequelize.sync({ force: true }) + await ensureGlobalIndexingRule() +} + +const teardownEach = async () => { + // Clear out query fee model tables + await queryFeeModels.allocationReceipts.truncate({ cascade: true }) + await queryFeeModels.vouchers.truncate({ cascade: true }) + await queryFeeModels.transferReceipts.truncate({ cascade: true }) + await queryFeeModels.transfers.truncate({ cascade: true }) + await queryFeeModels.allocationSummaries.truncate({ cascade: true }) + await queryFeeModels.scalarTapReceipts.truncate({ cascade: true }) + + // Clear out indexer management models + await managementModels.Action.truncate({ cascade: true }) + await managementModels.CostModel.truncate({ cascade: true }) + await managementModels.IndexingRule.truncate({ cascade: true }) + await managementModels.POIDispute.truncate({ cascade: true }) + + // Clear out indexing agreement model + await managementModels.IndexingAgreement.truncate({ cascade: true }) +} + +const teardownAll = async () => { + await sequelize.drop({}) +} + +describe('DipsManager', () => { + beforeAll(setup) + beforeEach(setupEach) + afterEach(teardownEach) + afterAll(teardownAll) + + // We have been rate-limited on CI as this test uses RPC providers, + // so we set its timeout to a higher value than usual. + jest.setTimeout(30_000) + + describe('initialization', () => { + test('creates DipsManager when dipperEndpoint is configured', () => { + const dipsManager = new DipsManager(logger, managementModels, network, null) + expect(dipsManager).toBeDefined() + }) + + test('throws error when dipperEndpoint is not configured', async () => { + const specWithoutDipper = { + ...testNetworkSpecification, + indexerOptions: { + ...testNetworkSpecification.indexerOptions, + dipperEndpoint: undefined, + }, + } + + metrics.registry.clear() + const networkWithoutDipper = await Network.create( + logger, + specWithoutDipper, + managementModels, + queryFeeModels, + graphNode, + metrics, + ) + expect( + () => new DipsManager(logger, managementModels, networkWithoutDipper, null), + ).toThrow('dipperEndpoint is not set') + }) + }) + + describe('agreement management', () => { + let dipsManager: DipsManager + const testDeploymentId = 'QmTZ8ejXJxRo7vDBS4uwqBeGoxLSWbhaA7oXa1RvxunLy7' + const testAllocationId = 'abcd47df40c29949a75a6693c77834c00b8ad626' + const testAgreementId = '123e4567-e89b-12d3-a456-426614174000' + + beforeEach(async () => { + // Clear mock calls between tests + jest.clearAllMocks() + + const allocationManager = new AllocationManager( + logger, + managementModels, + graphNode, + network, + ) + + dipsManager = new DipsManager(logger, managementModels, network, allocationManager) + + // Create a test agreement + await managementModels.IndexingAgreement.create({ + id: testAgreementId, + subgraph_deployment_id: testDeploymentId, + current_allocation_id: testAllocationId, + last_allocation_id: null, + last_payment_collected_at: null, + cancelled_at: null, + min_epochs_per_collection: BigInt(1), + max_epochs_per_collection: BigInt(5), + payer: '123456df40c29949a75a6693c77834c00b8a5678', + signature: Buffer.from('1234', 'hex'), + signed_payload: Buffer.from('5678', 'hex'), + protocol_network: 'arbitrum-sepolia', + chain_id: 'eip155:1', + base_price_per_epoch: '100', + price_per_entity: '1', + service: 'deadbedf40c29949a75a2293c11834c00b8a1234', + payee: '1212564f40c29949a75a3423c11834c00b8aaaaa', + deadline: new Date(Date.now() + 86400000), // 1 day from now + duration_epochs: BigInt(10), + max_initial_amount: '1000', + max_ongoing_amount_per_epoch: '100', + created_at: new Date(), + updated_at: new Date(), + signed_cancellation_payload: null, + }) + }) + + test('cancels agreement when allocation is closed', async () => { + const client = dipsManager.gatewayDipsServiceClient + + client.CancelAgreement = jest.fn().mockResolvedValue({}) + + await dipsManager.tryCancelAgreement(testAllocationId) + + // Verify the client was called with correct parameters + expect((client.CancelAgreement as jest.Mock).mock.calls.length).toBe(1) + // TODO: Check the signed cancellation payload + expect((client.CancelAgreement as jest.Mock).mock.calls[0][0]).toEqual({ + version: 1, + signedCancellation: expect.any(Uint8Array), + }) + + const agreement = await managementModels.IndexingAgreement.findOne({ + where: { id: testAgreementId }, + }) + expect(agreement?.cancelled_at).toBeDefined() + }) + + test('handles errors when cancelling agreement', async () => { + const client = dipsManager.gatewayDipsServiceClient + client.CancelAgreement = jest + .fn() + .mockRejectedValueOnce(new Error('Failed to cancel')) + + await dipsManager.tryCancelAgreement(testAllocationId) + + const agreement = await managementModels.IndexingAgreement.findOne({ + where: { id: testAgreementId }, + }) + expect(agreement?.cancelled_at).toBeNull() + }) + + test('updates agreement allocation IDs during reallocation', async () => { + const newAllocationId = '5678bedf40c29945678a2293c15678c00b8a5678' + + await dipsManager.tryUpdateAgreementAllocation( + testDeploymentId, + toAddress(testAllocationId), + toAddress(newAllocationId), + ) + + const agreement = await managementModels.IndexingAgreement.findOne({ + where: { id: testAgreementId }, + }) + expect(agreement?.current_allocation_id).toBe(toAddress(newAllocationId)) + expect(agreement?.last_allocation_id).toBe(toAddress(testAllocationId)) + expect(agreement?.last_payment_collected_at).toBeNull() + }) + + test('creates indexing rules for active agreements', async () => { + // Mock fetch the subgraph deployment from the network subgraph + network.networkMonitor.subgraphDeployment = jest + .fn() + .mockResolvedValue(mockSubgraphDeployment(testDeploymentId)) + + await dipsManager.ensureAgreementRules() + + const rules = await managementModels.IndexingRule.findAll({ + where: { + identifier: testDeploymentId, + }, + }) + + expect(rules).toHaveLength(1) + expect(rules[0]).toMatchObject({ + identifier: testDeploymentId, + identifierType: SubgraphIdentifierType.DEPLOYMENT, + decisionBasis: IndexingDecisionBasis.DIPS, + allocationAmount: + network.specification.indexerOptions.dipsAllocationAmount.toString(), + autoRenewal: true, + allocationLifetime: 4, // max_epochs_per_collection - dipsEpochsMargin + }) + }) + + test('does not create or modify an indexing rule if it already exists', async () => { + // Create an indexing rule with the same identifier + await managementModels.IndexingRule.create({ + identifier: testDeploymentId, + identifierType: SubgraphIdentifierType.DEPLOYMENT, + decisionBasis: IndexingDecisionBasis.ALWAYS, + allocationLifetime: 16, + requireSupported: true, + safety: true, + protocolNetwork: 'eip155:421614', + allocationAmount: '1030', + }) + + // Mock fetch the subgraph deployment from the network subgraph + network.networkMonitor.subgraphDeployment = jest + .fn() + .mockResolvedValue(mockSubgraphDeployment(testDeploymentId)) + + await dipsManager.ensureAgreementRules() + + const rules = await managementModels.IndexingRule.findAll({ + where: { identifier: testDeploymentId }, + }) + expect(rules).toHaveLength(1) + expect(rules[0]).toMatchObject({ + identifier: testDeploymentId, + identifierType: SubgraphIdentifierType.DEPLOYMENT, + decisionBasis: IndexingDecisionBasis.ALWAYS, + allocationLifetime: 16, + requireSupported: true, + safety: true, + protocolNetwork: 'eip155:421614', + allocationAmount: '1030', + }) + }) + + test('removes DIPs indexing rule for cancelled agreement', async () => { + await dipsManager.ensureAgreementRules() + const rule = await managementModels.IndexingRule.findOne({ + where: { + identifier: testDeploymentId, + identifierType: SubgraphIdentifierType.DEPLOYMENT, + decisionBasis: IndexingDecisionBasis.DIPS, + }, + }) + expect(rule).toBeDefined() + await managementModels.IndexingAgreement.update( + { + cancelled_at: new Date(), + }, + { + where: { id: testAgreementId }, + }, + ) + await dipsManager.ensureAgreementRules() + const ruleAfter = await managementModels.IndexingRule.findOne({ + where: { + identifier: testDeploymentId, + identifierType: SubgraphIdentifierType.DEPLOYMENT, + decisionBasis: IndexingDecisionBasis.DIPS, + }, + }) + expect(ruleAfter).toBeNull() + }) + + test('does not remove pre-existing non-DIPS indexing rule', async () => { + // Create an indexing rule with the same identifier + await managementModels.IndexingRule.create({ + identifier: testDeploymentId, + identifierType: SubgraphIdentifierType.DEPLOYMENT, + decisionBasis: IndexingDecisionBasis.ALWAYS, + allocationLifetime: 16, + requireSupported: true, + safety: true, + protocolNetwork: 'eip155:421614', + allocationAmount: '1030', + }) + await dipsManager.ensureAgreementRules() + const ruleBefore = await managementModels.IndexingRule.findOne({ + where: { + identifier: testDeploymentId, + identifierType: SubgraphIdentifierType.DEPLOYMENT, + decisionBasis: IndexingDecisionBasis.ALWAYS, + }, + }) + expect(ruleBefore).toBeDefined() + await managementModels.IndexingAgreement.update( + { + cancelled_at: new Date(), + }, + { + where: { id: testAgreementId }, + }, + ) + await dipsManager.ensureAgreementRules() + const ruleAfter = await managementModels.IndexingRule.findOne({ + where: { + identifier: testDeploymentId, + identifierType: SubgraphIdentifierType.DEPLOYMENT, + decisionBasis: IndexingDecisionBasis.ALWAYS, + }, + }) + expect(ruleAfter).toBeDefined() + }) + + test('returns active DIPs deployments', async () => { + const deployments = await dipsManager.getActiveDipsDeployments() + + expect(deployments).toHaveLength(1) + expect(deployments[0].ipfsHash).toBe(testDeploymentId) + }) + }) +}) + +describe('DipsCollector', () => { + beforeAll(setup) + beforeEach(setupEach) + afterEach(teardownEach) + afterAll(teardownAll) + + describe('initialization', () => { + test('creates DipsCollector when dipperEndpoint is configured', () => { + const dipsCollector = new DipsCollector( + logger, + managementModels, + networkSpecWithDips, + network.wallet, + graphNode, + ) + expect(dipsCollector).toBeDefined() + }) + test('starts payment collection loop', () => { + const dipsCollector = new DipsCollector( + logger, + managementModels, + networkSpecWithDips, + network.wallet, + graphNode, + ) + expect(dipsCollector).toBeDefined() + expect(startCollectionLoop).toHaveBeenCalled() + }) + test('throws error when dipperEndpoint is not configured', () => { + const specWithoutDipper = { + ...testNetworkSpecification, + indexerOptions: { + ...testNetworkSpecification.indexerOptions, + dipperEndpoint: undefined, + }, + } + expect( + () => + new DipsCollector( + logger, + managementModels, + specWithoutDipper, + network.wallet, + graphNode, + ), + ).toThrow('dipperEndpoint is not set') + }) + }) + + describe('payment collection', () => { + const testDeploymentId = 'QmTZ8ejXJxRo7vDBS4uwqBeGoxLSWbhaA7oXa1RvxunLy7' + const testAllocationId = 'abcd47df40c29949a75a6693c77834c00b8ad626' + const testAgreementId = '123e4567-e89b-12d3-a456-426614174000' + + beforeEach(async () => { + // Clear mock calls between tests + jest.clearAllMocks() + + // Create a test agreement + // Note last_allocation_id is set to the testAllocationId + // current_allocation_id is set to null so that we can collect payment + // (also last_payment_collected_at is set to null) + await managementModels.IndexingAgreement.create({ + id: testAgreementId, + subgraph_deployment_id: testDeploymentId, + current_allocation_id: null, + last_allocation_id: testAllocationId, + last_payment_collected_at: null, + cancelled_at: null, + min_epochs_per_collection: BigInt(1), + max_epochs_per_collection: BigInt(5), + payer: '123456df40c29949a75a6693c77834c00b8a5678', + signature: Buffer.from('1234', 'hex'), + signed_payload: Buffer.from('5678', 'hex'), + protocol_network: 'arbitrum-sepolia', + chain_id: 'eip155:1', + base_price_per_epoch: '100', + price_per_entity: '1', + service: 'deadbedf40c29949a75a2293c11834c00b8a1234', + payee: '1212564f40c29949a75a3423c11834c00b8aaaaa', + deadline: new Date(Date.now() + 86400000), // 1 day from now + duration_epochs: BigInt(10), + max_initial_amount: '1000', + max_ongoing_amount_per_epoch: '100', + created_at: new Date(), + updated_at: new Date(), + signed_cancellation_payload: null, + }) + graphNode.entityCount = jest.fn().mockResolvedValue([250000]) + }) + test('collects payment for a specific agreement', async () => { + const agreement = await managementModels.IndexingAgreement.findOne({ + where: { id: testAgreementId }, + }) + if (!agreement) { + throw new Error('Agreement not found') + } + + const client = dipsCollector.gatewayDipsServiceClient + + client.CollectPayment = jest.fn().mockResolvedValue({ + version: 1, + status: CollectPaymentStatus.ACCEPT, + tapReceipt: Buffer.from('1234', 'hex'), + }) + dipsCollector.gatewayDipsServiceMessagesCodec.decodeTapReceipt = jest + .fn() + .mockImplementation(() => { + logger.info('MOCK Decoding TAP receipt') + return { + allocation_id: toAddress(testAllocationId), + signer_address: toAddress('0xabcd56df41234949a75a6693c77834c00b8abbbb'), + signature: Buffer.from('1234', 'hex'), + timestamp_ns: 1234567890, + nonce: 1, + value: '1000', + } + }) + // escrowSenderGetter has been removed from DipsCollector + + await dipsCollector.tryCollectPayment(agreement) + + expect(client.CollectPayment).toHaveBeenCalledWith({ + version: 1, + signedCollection: expect.any(Uint8Array), + }) + expect(agreement.last_payment_collected_at).not.toBeNull() + + const receipt = await queryFeeModels.scalarTapReceipts.findOne({ + where: { + allocation_id: testAllocationId, + }, + }) + expect(receipt).not.toBeNull() + expect(receipt?.signer_address).toBe( + toAddress('0xabcd56df41234949a75a6693c77834c00b8abbbb'), + ) + expect(receipt?.value).toBe('1000') + }) + }) +}) diff --git a/packages/indexer-common/src/indexing-fees/dips.ts b/packages/indexer-common/src/indexing-fees/dips.ts new file mode 100644 index 000000000..7b8c66c18 --- /dev/null +++ b/packages/indexer-common/src/indexing-fees/dips.ts @@ -0,0 +1,527 @@ +import { + Address, + formatGRT, + Logger, + SubgraphDeploymentID, + toAddress, +} from '@graphprotocol/common-ts' +import { + ActionStatus, + Allocation, + AllocationManager, + DipsReceiptStatus, + GraphNode, + IndexerManagementModels, + IndexingDecisionBasis, + IndexingRuleAttributes, + Network, + sequentialTimerMap, + SubgraphIdentifierType, + upsertIndexingRule, +} from '@graphprotocol/indexer-common' +import { Op } from 'sequelize' + +import { + createGatewayDipsServiceClient, + GatewayDipsServiceMessagesCodec, +} from './gateway-dips-service-client' +import { + CollectPaymentStatus, + GatewayDipsServiceClientImpl, +} from '@graphprotocol/dips-proto/generated/gateway' +import { IndexingAgreement } from '../indexer-management/models/indexing-agreement' +import { NetworkSpecification } from '../network-specification' +import { BaseWallet } from 'ethers' + +const DIPS_COLLECTION_INTERVAL = 60_000 + +const uuidToHex = (uuid: string) => { + return `0x${uuid.replace(/-/g, '')}` +} + +const normalizeAddressForDB = (address: string) => { + return toAddress(address).toLowerCase().replace('0x', '') +} + +export class DipsManager { + declare gatewayDipsServiceClient: GatewayDipsServiceClientImpl + declare gatewayDipsServiceMessagesCodec: GatewayDipsServiceMessagesCodec + constructor( + private logger: Logger, + private models: IndexerManagementModels, + private network: Network, + private parent: AllocationManager | null, + ) { + if (!this.network.specification.indexerOptions.dipperEndpoint) { + throw new Error('dipperEndpoint is not set') + } + this.gatewayDipsServiceClient = createGatewayDipsServiceClient( + this.network.specification.indexerOptions.dipperEndpoint, + ) + this.gatewayDipsServiceMessagesCodec = new GatewayDipsServiceMessagesCodec() + } + // Cancel an agreement associated to an allocation if it exists + async tryCancelAgreement(allocationId: string) { + const normalizedAllocationId = normalizeAddressForDB(allocationId) + const agreement = await this.models.IndexingAgreement.findOne({ + where: { + current_allocation_id: normalizedAllocationId, + cancelled_at: null, + }, + }) + if (agreement) { + try { + await this._tryCancelAgreement(agreement) + } catch (error) { + this.logger.error(`Error cancelling agreement ${agreement.id}`, { error }) + } + } + } + async _tryCancelAgreement(agreement: IndexingAgreement) { + try { + const cancellation = + await this.gatewayDipsServiceMessagesCodec.createSignedCancellationRequest( + uuidToHex(agreement.id), + this.network.wallet, + ) + await this.gatewayDipsServiceClient.CancelAgreement({ + version: 1, + signedCancellation: cancellation, + }) + agreement.cancelled_at = new Date() + agreement.updated_at = new Date() + await agreement.save() + } catch (error) { + this.logger.error(`Error cancelling agreement ${agreement.id}`, { error }) + } + } + // Update the current and last allocation ids for an agreement if it exists + async tryUpdateAgreementAllocation( + deploymentId: string, + oldAllocationId: Address | null, + newAllocationId: Address | null, + ) { + const agreement = await this.models.IndexingAgreement.findOne({ + where: { + subgraph_deployment_id: deploymentId, + }, + }) + if (agreement) { + agreement.current_allocation_id = newAllocationId + agreement.last_allocation_id = oldAllocationId + agreement.last_payment_collected_at = null + agreement.updated_at = new Date() + await agreement.save() + } + } + async ensureAgreementRules() { + if (!this.parent) { + this.logger.error( + 'DipsManager has no parent AllocationManager, cannot ensure agreement rules', + ) + return + } + // Get all the indexing agreements that are not cancelled + const indexingAgreements = await this.models.IndexingAgreement.findAll({ + where: { + cancelled_at: null, + }, + }) + this.logger.debug( + `Ensuring indexing rules for ${indexingAgreements.length} active agreement${ + indexingAgreements.length === 1 ? '' : 's' + }`, + ) + // For each agreement, check that there is an indexing rule to always + // allocate to the agreement's subgraphDeploymentId, and if not, create one + for (const agreement of indexingAgreements) { + const subgraphDeploymentID = new SubgraphDeploymentID( + agreement.subgraph_deployment_id, + ) + this.logger.info( + `Checking if indexing rule exists for agreement ${ + agreement.id + }, deployment ${subgraphDeploymentID.toString()}`, + ) + // If there is not yet an indexingRule that deems this deployment worth allocating to, make one + const ruleExists = await this.parent.matchingRuleExists( + this.logger, + subgraphDeploymentID, + ) + // Check if there is an indexing rule saying we should NEVER allocate to this one, consider it blocklisted + const allDeploymentRules = await this.models.IndexingRule.findAll({ + where: { + identifierType: SubgraphIdentifierType.DEPLOYMENT, + }, + }) + const blocklistedRule = allDeploymentRules.find( + (rule) => + new SubgraphDeploymentID(rule.identifier).bytes32 === + subgraphDeploymentID.bytes32 && + rule.decisionBasis === IndexingDecisionBasis.NEVER, + ) + if (blocklistedRule) { + this.logger.info( + `Blocklisted deployment ${subgraphDeploymentID.toString()}, skipping indexing rule creation`, + ) + await this._tryCancelAgreement(agreement) + } else if (!ruleExists) { + this.logger.info( + `Creating indexing rule for agreement ${agreement.id}, deployment ${agreement.subgraph_deployment_id}`, + ) + const indexingRule = { + identifier: agreement.subgraph_deployment_id, + allocationAmount: formatGRT( + this.network.specification.indexerOptions.dipsAllocationAmount, + ), + identifierType: SubgraphIdentifierType.DEPLOYMENT, + decisionBasis: IndexingDecisionBasis.DIPS, + protocolNetwork: this.network.specification.networkIdentifier, + autoRenewal: true, + allocationLifetime: Math.max( + Number(agreement.min_epochs_per_collection), + Number(agreement.max_epochs_per_collection) - + this.network.specification.indexerOptions.dipsEpochsMargin, + ), + requireSupported: false, + } as Partial + + await upsertIndexingRule(this.logger, this.models, indexingRule) + } + } + + const cancelledAgreements = await this.models.IndexingAgreement.findAll({ + where: { + cancelled_at: { + [Op.ne]: null, + }, + }, + }) + this.logger.debug( + `Ensuring no DIPs indexing rules for ${ + cancelledAgreements.length + } cancelled agreement${cancelledAgreements.length === 1 ? '' : 's'}`, + ) + for (const agreement of cancelledAgreements) { + this.logger.info( + `Checking if indexing rule exists for cancelled agreement ${agreement.id}, deployment ${agreement.subgraph_deployment_id}`, + ) + // First check if there is another agreement that is not cancelled that has the same deployment id + const otherAgreement = indexingAgreements.find( + (a) => + a.subgraph_deployment_id === agreement.subgraph_deployment_id && + a.id !== agreement.id, + ) + if (otherAgreement) { + this.logger.info( + `Another agreement ${otherAgreement.id} exists for deployment ${agreement.subgraph_deployment_id}, skipping removal of DIPs indexing rule`, + ) + continue + } + const rule = await this.models.IndexingRule.findOne({ + where: { + identifier: agreement.subgraph_deployment_id, + identifierType: SubgraphIdentifierType.DEPLOYMENT, + decisionBasis: IndexingDecisionBasis.DIPS, + }, + }) + if (rule) { + this.logger.info( + `Removing DIPs indexing rule for cancelled agreement ${agreement.id}, deployment ${agreement.subgraph_deployment_id}`, + ) + await this.models.IndexingRule.destroy({ + where: { id: rule.id }, + }) + } + } + } + async getActiveDipsDeployments(): Promise { + // Get all the indexing agreements that are not cancelled + const indexingAgreements = await this.models.IndexingAgreement.findAll({ + where: { + cancelled_at: null, + }, + }) + return indexingAgreements.map( + (agreement) => new SubgraphDeploymentID(agreement.subgraph_deployment_id), + ) + } + async matchAgreementAllocations(allocations: Allocation[]) { + const indexingAgreements = await this.models.IndexingAgreement.findAll({ + where: { + cancelled_at: null, + }, + }) + for (const agreement of indexingAgreements) { + this.logger.trace(`Matching active agreement ${agreement.id}`) + const allocation = allocations.find( + (allocation) => + allocation.subgraphDeployment.id.bytes32 === + new SubgraphDeploymentID(agreement.subgraph_deployment_id).bytes32, + ) + const actions = await this.models.Action.findAll({ + where: { + deploymentID: agreement.subgraph_deployment_id, + status: { + [Op.or]: [ + ActionStatus.PENDING, + ActionStatus.QUEUED, + ActionStatus.APPROVED, + ActionStatus.DEPLOYING, + ], + }, + }, + }) + this.logger.trace(`Found ${actions.length} actions for agreement ${agreement.id}`) + if (allocation && actions.length === 0) { + const currentAllocationId = + agreement.current_allocation_id != null + ? toAddress(agreement.current_allocation_id) + : null + this.logger.trace( + `Current allocation id for agreement ${agreement.id} is ${currentAllocationId}`, + { + currentAllocationId, + allocation, + }, + ) + if (currentAllocationId !== allocation.id) { + this.logger.warn( + `Found mismatched allocation for agreement ${agreement.id}, updating from ${currentAllocationId} to ${allocation.id}`, + ) + await this.tryUpdateAgreementAllocation( + agreement.subgraph_deployment_id, + currentAllocationId, + allocation.id, + ) + } + } + } + // Now we find the cancelled agreements and check if their allocation is still active + const cancelledAgreements = await this.models.IndexingAgreement.findAll({ + where: { + cancelled_at: { + [Op.ne]: null, + }, + current_allocation_id: { + [Op.ne]: null, + }, + }, + }) + for (const agreement of cancelledAgreements) { + this.logger.trace(`Matching cancelled agreement ${agreement.id}`) + const allocation = allocations.find( + (allocation) => + allocation.subgraphDeployment.id.bytes32 === + new SubgraphDeploymentID(agreement.subgraph_deployment_id).bytes32, + ) + if (allocation == null && agreement.current_allocation_id != null) { + const actions = await this.models.Action.findAll({ + where: { + deploymentID: agreement.subgraph_deployment_id, + status: { + [Op.or]: [ + ActionStatus.PENDING, + ActionStatus.QUEUED, + ActionStatus.APPROVED, + ActionStatus.DEPLOYING, + ], + }, + }, + }) + if (actions.length > 0) { + this.logger.warn( + `Found active actions for cancelled agreement ${agreement.id}, deployment ${agreement.subgraph_deployment_id}, skipping matching allocation`, + ) + continue + } + this.logger.info( + `Updating last allocation id for cancelled agreement ${agreement.id}, deployment ${agreement.subgraph_deployment_id}`, + ) + await this.tryUpdateAgreementAllocation( + agreement.subgraph_deployment_id, + toAddress(agreement.current_allocation_id), + null, + ) + } + } + } +} + +export class DipsCollector { + declare gatewayDipsServiceClient: GatewayDipsServiceClientImpl + declare gatewayDipsServiceMessagesCodec: GatewayDipsServiceMessagesCodec + constructor( + private logger: Logger, + private managementModels: IndexerManagementModels, + private specification: NetworkSpecification, + private wallet: BaseWallet, + private graphNode: GraphNode, + ) { + if (!this.specification.indexerOptions.dipperEndpoint) { + throw new Error('dipperEndpoint is not set') + } + this.gatewayDipsServiceClient = createGatewayDipsServiceClient( + this.specification.indexerOptions.dipperEndpoint, + ) + this.gatewayDipsServiceMessagesCodec = new GatewayDipsServiceMessagesCodec() + } + + static create( + logger: Logger, + managementModels: IndexerManagementModels, + specification: NetworkSpecification, + wallet: BaseWallet, + graphNode: GraphNode, + ) { + const collector = new DipsCollector( + logger, + managementModels, + specification, + wallet, + graphNode, + ) + collector.startCollectionLoop() + return collector + } + + startCollectionLoop() { + sequentialTimerMap( + { + logger: this.logger, + milliseconds: DIPS_COLLECTION_INTERVAL, + }, + async () => { + this.logger.debug('Running DIPs payment collection loop') + await this.collectAllPayments() + }, + { + onError: (err) => { + this.logger.error('Failed to collect DIPs payments', { err }) + }, + }, + ) + } + + // Collect payments for all outstanding agreements + async collectAllPayments() { + // Part 1: Collect new payments + const outstandingAgreements = await this.managementModels.IndexingAgreement.findAll({ + where: { + last_payment_collected_at: null, + last_allocation_id: { + [Op.ne]: null, + }, + }, + }) + for (const agreement of outstandingAgreements) { + await this.tryCollectPayment(agreement) + } + + // Part 2: Poll pending receipts + await this.pollPendingReceipts() + } + + async pollPendingReceipts() { + // Find all pending receipts + const pendingReceipts = await this.managementModels.DipsReceipt.findAll({ + where: { + status: 'PENDING', + }, + }) + + if (pendingReceipts.length === 0) { + return + } + + this.logger.info(`Polling ${pendingReceipts.length} pending receipts`) + + for (const receipt of pendingReceipts) { + try { + const statusResponse = await this.gatewayDipsServiceClient.GetReceiptById({ + version: 1, + receiptId: receipt.id, + }) + + if (statusResponse.status !== receipt.status) { + const oldStatus = receipt.status + receipt.status = statusResponse.status as DipsReceiptStatus + receipt.transaction_hash = statusResponse.transactionHash || null + receipt.error_message = statusResponse.errorMessage || null + await receipt.save() + + this.logger.info( + `Receipt ${receipt.id} status updated from ${oldStatus} to ${statusResponse.status}`, + { + receiptId: receipt.id, + oldStatus: oldStatus, + newStatus: statusResponse.status, + transactionHash: statusResponse.transactionHash, + }, + ) + } + } catch (error) { + this.logger.error(`Error polling receipt ${receipt.id}`, { error }) + } + } + } + async tryCollectPayment(agreement: IndexingAgreement) { + if (!agreement.last_allocation_id) { + this.logger.error(`Agreement ${agreement.id} has no last allocation id`) + return + } + const entityCounts = await this.graphNode.entityCount([ + new SubgraphDeploymentID(agreement.subgraph_deployment_id), + ]) + if (entityCounts.length === 0) { + this.logger.error(`Agreement ${agreement.id} has no entity count`) + return + } + const entityCount = entityCounts[0] + const collection = + await this.gatewayDipsServiceMessagesCodec.createSignedCollectionRequest( + uuidToHex(agreement.id), + agreement.last_allocation_id, + entityCount, + this.wallet, + ) + try { + this.logger.info(`Collecting payment for agreement ${agreement.id}`) + const response = await this.gatewayDipsServiceClient.CollectPayment({ + version: 1, + signedCollection: collection, + }) + if (response.status === CollectPaymentStatus.ACCEPT) { + const receiptId = response.receiptId + const amount = response.amount + + // Store the receipt ID in the database + this.logger.info(`Received receipt ID ${receiptId} for agreement ${agreement.id}`) + + // Create DipsReceipt record with PENDING status + await this.managementModels.DipsReceipt.create({ + id: receiptId, + agreement_id: agreement.id, + amount: amount, + status: 'PENDING', + retry_count: 0, + }) + + // Mark the agreement as having had a payment collected + agreement.last_payment_collected_at = new Date() + agreement.updated_at = new Date() + await agreement.save() + + this.logger.info( + `Payment collection initiated for agreement ${agreement.id}, receipt ID: ${receiptId}`, + ) + } else { + throw new Error(`Payment request not accepted: ${response.status}`) + } + } catch (error) { + this.logger.error(`Error collecting payment for agreement ${agreement.id}`, { + error, + }) + } + } +} diff --git a/packages/indexer-common/src/indexing-fees/gateway-dips-service-client.ts b/packages/indexer-common/src/indexing-fees/gateway-dips-service-client.ts new file mode 100644 index 000000000..1b8019cf8 --- /dev/null +++ b/packages/indexer-common/src/indexing-fees/gateway-dips-service-client.ts @@ -0,0 +1,165 @@ +import { Client, credentials } from '@grpc/grpc-js' +import { UnaryCallback } from '@grpc/grpc-js/build/src/client' +import { GatewayDipsServiceClientImpl } from '@graphprotocol/dips-proto/generated/gateway' +import { BaseWallet, TypedDataEncoder, getBytes, AbiCoder, recoverAddress } from 'ethers' +import { toAddress } from '@graphprotocol/common-ts' + +type RpcImpl = (service: string, method: string, data: Uint8Array) => Promise + +interface Rpc { + request: RpcImpl +} + +export const domainSalt = + '0xb4632c657c26dce5d4d7da1d65bda185b14ff8f905ddbb03ea0382ed06c5ef28' +export const chainId = 0xa4b1 // 42161 +export const cancelAgreementDomain = { + name: 'Graph Protocol Indexing Agreement Cancellation', + version: '0', + chainId: chainId, + salt: domainSalt, +} +export const cancelAgreementTypes = { + CancellationRequest: [{ name: 'agreement_id', type: 'bytes16' }], +} + +export const collectPaymentsDomain = { + name: 'Graph Protocol Indexing Agreement Collection', + version: '0', + chainId: chainId, + salt: domainSalt, +} +export const collectPaymentsTypes = { + CollectionRequest: [ + { name: 'agreement_id', type: 'bytes16' }, + { name: 'allocation_id', type: 'address' }, + { name: 'entity_count', type: 'uint64' }, + ], +} + +export class GatewayDipsServiceMessagesCodec { + async createSignedCancellationRequest( + agreementId: string, + wallet: BaseWallet, + ): Promise { + const signature = await wallet.signTypedData( + cancelAgreementDomain, + cancelAgreementTypes, + { agreement_id: agreementId }, + ) + const abiCoder = AbiCoder.defaultAbiCoder() + return getBytes( + abiCoder.encode(['tuple(bytes16)', 'bytes'], [[agreementId], signature]), + ) + } + + async createSignedCollectionRequest( + agreementId: string, + allocationId: string, + entityCount: number, + wallet: BaseWallet, + ): Promise { + const signature = await wallet.signTypedData( + collectPaymentsDomain, + collectPaymentsTypes, + { + agreement_id: agreementId, + allocation_id: toAddress(allocationId), + entity_count: entityCount, + }, + ) + const abiCoder = AbiCoder.defaultAbiCoder() + return getBytes( + abiCoder.encode( + ['tuple(bytes16, address, uint64)', 'bytes'], + [[agreementId, toAddress(allocationId), entityCount], signature], + ), + ) + } + + decodeTapReceipt(receipt: Uint8Array, verifyingContract: string) { + const abiCoder = AbiCoder.defaultAbiCoder() + const [message, signature] = abiCoder.decode( + ['tuple(address,uint64,uint64,uint128)', 'bytes'], + receipt, + ) + + const [allocationId, timestampNs, nonce, value] = message + + // Recover the signer address from the signature + // compute the EIP-712 digest of the message + const domain = { + name: 'TAP', + version: '1', + chainId: chainId, + verifyingContract, + } + + const types = { + Receipt: [ + { name: 'allocation_id', type: 'address' }, + { name: 'timestamp_ns', type: 'uint64' }, + { name: 'nonce', type: 'uint64' }, + { name: 'value', type: 'uint128' }, + ], + } + + const digest = TypedDataEncoder.hash(domain, types, { + allocation_id: allocationId, + timestamp_ns: timestampNs, + nonce: nonce, + value: value, + }) + const signerAddress = recoverAddress(digest, signature) + return { + allocation_id: toAddress(allocationId), + signer_address: toAddress(signerAddress), + signature: signature, + timestamp_ns: timestampNs, + nonce: nonce, + value: value, + } + } +} + +export const createRpc = (url: string): Rpc => { + const client = new Client(url, credentials.createInsecure()) + const request: RpcImpl = (service, method, data) => { + // Conventionally in gRPC, the request path looks like + // "package.names.ServiceName/MethodName", + // we therefore construct such a string + const path = `/${service}/${method}` + + return new Promise((resolve, reject) => { + // makeUnaryRequest transmits the result (and error) with a callback + // transform this into a promise! + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const resultCallback: UnaryCallback = (err, res) => { + if (err) { + return reject(err) + } + resolve(res) + } + // eslint-disable-next-line @typescript-eslint/no-explicit-any + function passThrough(argument: any) { + return argument + } + + // Using passThrough as the deserialize functions + client.makeUnaryRequest( + path, + (d) => Buffer.from(d), + passThrough, + data, + resultCallback, + ) + }) + } + + return { request } +} + +export const createGatewayDipsServiceClient = (url: string) => { + const rpc = createRpc(url) + return new GatewayDipsServiceClientImpl(rpc) +} diff --git a/packages/indexer-common/src/indexing-fees/index.ts b/packages/indexer-common/src/indexing-fees/index.ts new file mode 100644 index 000000000..0b71f1b8e --- /dev/null +++ b/packages/indexer-common/src/indexing-fees/index.ts @@ -0,0 +1 @@ +export * from './dips' diff --git a/packages/indexer-common/src/network-specification.ts b/packages/indexer-common/src/network-specification.ts index f683cdec5..5610231b9 100644 --- a/packages/indexer-common/src/network-specification.ts +++ b/packages/indexer-common/src/network-specification.ts @@ -1,9 +1,8 @@ import { toAddress, parseGRT } from '@graphprotocol/common-ts' -import { BigNumber } from 'ethers' import { validateNetworkIdentifier, validateIpfsHash } from './parsers' import { AllocationManagementMode } from './types' import { z } from 'zod' -import { utils } from 'ethers' +import { isAddress } from 'ethers' // TODO: make sure those values are always in sync with the AllocationManagementMode enum. Can we do this in compile time? const ALLOCATION_MANAGEMENT_MODE = ['auto', 'manual', 'oversight'] as const @@ -12,7 +11,7 @@ function positiveNumber(): z.ZodNumber { return z.number().positive().finite() } -function GRT(): z.ZodEffects { +function GRT(): z.ZodEffects { return z .number() .nonnegative() @@ -33,13 +32,20 @@ export const IndexerOptions = z .object({ address: z .string() - .refine((val) => utils.isAddress(val), { + .refine((val) => isAddress(val), { message: 'Invalid contract address', }) .transform(toAddress), mnemonic: z.string(), url: z.string().url(), geoCoordinates: z.number().array().length(2).default([31.780715, -41.179504]), + paymentsDestination: z + .string() + .refine((val) => isAddress(val), { + message: 'Invalid contract address', + }) + .transform(toAddress) + .optional(), restakeRewards: z.boolean().default(true), rebateClaimThreshold: GRT().default(1), rebateClaimBatchThreshold: GRT().default(5), @@ -57,7 +63,16 @@ export const IndexerOptions = z autoAllocationMinBatchSize: positiveNumber().default(1), allocateOnNetworkSubgraph: z.boolean().default(false), register: z.boolean().default(true), + maxProvisionInitialSize: GRT() + .refine((x) => x >= parseGRT('100000') || x === 0n, { + message: 'Must be greater or equal than 100000 GRT', + }) + .default(0), finalityTime: positiveNumber().default(3600), + enableDips: z.boolean().default(false), + dipperEndpoint: z.string().url().optional(), + dipsAllocationAmount: GRT().default(1), + dipsEpochsMargin: positiveNumber().default(1), }) .strict() export type IndexerOptions = z.infer @@ -77,6 +92,7 @@ export const TransactionMonitoring = z .transform((x) => x * 10 ** 9) .optional(), maxTransactionAttempts: z.number().nonnegative().finite().default(0), + confirmationBlocks: positiveNumber().default(3), }) .strict() .default({}) // defaults will be used for instantiation when the TransactionMonitoring group is absent. @@ -145,13 +161,13 @@ export const TapContracts = z .record( z.string(), z.object({ - TAPVerifier: z.string().refine((val) => utils.isAddress(val), { + TAPVerifier: z.string().refine((val) => isAddress(val), { message: 'Invalid contract address', }), - AllocationIDTracker: z.string().refine((val) => utils.isAddress(val), { + AllocationIDTracker: z.string().refine((val) => isAddress(val), { message: 'Invalid contract address', }), - Escrow: z.string().refine((val) => utils.isAddress(val), { + Escrow: z.string().refine((val) => isAddress(val), { message: 'Invalid contract address', }), }), @@ -176,7 +192,8 @@ export const NetworkSpecification = z transactionMonitoring: TransactionMonitoring, subgraphs: ProtocolSubgraphs, networkProvider: NetworkProvider, - addressBook: z.string().optional(), + horizonAddressBook: z.string().optional(), + subgraphServiceAddressBook: z.string().optional(), tapAddressBook: TapContracts.optional(), allocationSyncInterval: positiveNumber().default(120000), }) diff --git a/packages/indexer-common/src/network.ts b/packages/indexer-common/src/network.ts index 1b8d436e2..6918c9157 100644 --- a/packages/indexer-common/src/network.ts +++ b/packages/indexer-common/src/network.ts @@ -1,18 +1,22 @@ import { Logger, Metrics, - NetworkContracts, SubgraphDeploymentID, - connectContracts, Eventual, - AddressBook, toAddress, + formatGRT, } from '@graphprotocol/common-ts' +import { + connectGraphHorizon, + connectSubgraphService, + GraphHorizonContracts, + SubgraphServiceContracts, +} from '@graphprotocol/toolshed/deployments' import { connectContracts as connectTapContracts, NetworkContracts as TapContracts, } from '@semiotic-labs/tap-contracts-bindings' -import { providers, Wallet } from 'ethers' +import { FetchRequest, HDNodeWallet, JsonRpcProvider, Provider, Wallet } from 'ethers' import { strict as assert } from 'assert' import geohash from 'ngeohash' import pRetry, { Options } from 'p-retry' @@ -26,46 +30,53 @@ import { specification as spec, GraphNode, NetworkMonitor, - AllocationReceiptCollector, SubgraphFreshnessChecker, monitorEligibleAllocations, + IndexerManagementModels, } from '.' import { resolveChainId } from './indexer-management' import { monitorEthBalance } from './utils' import { QueryFeeModels } from './query-fees' -import { readFileSync } from 'fs' import { TapCollector } from './allocations/tap-collector' +import { GraphTallyCollector } from './allocations/graph-tally-collector' +import { encodeRegistrationData } from '@graphprotocol/toolshed' +import { DipsCollector } from './indexing-fees/dips' export class Network { logger: Logger networkSubgraph: SubgraphClient - contracts: NetworkContracts - wallet: Wallet - networkProvider: providers.StaticJsonRpcProvider + contracts: GraphHorizonContracts & SubgraphServiceContracts + wallet: HDNodeWallet + networkProvider: JsonRpcProvider transactionManager: TransactionManager networkMonitor: NetworkMonitor - // TODO: deprecated - receiptCollector: AllocationReceiptCollector | undefined - tapCollector: TapCollector | undefined + graphTallyCollector: GraphTallyCollector | undefined + dipsCollector: DipsCollector | undefined specification: spec.NetworkSpecification paused: Eventual isOperator: Eventual - + isHorizon: Eventual + queryFeeModels: QueryFeeModels + managementModels: IndexerManagementModels private constructor( logger: Logger, - contracts: NetworkContracts, - wallet: Wallet, + contracts: GraphHorizonContracts & SubgraphServiceContracts, + wallet: HDNodeWallet, networkSubgraph: SubgraphClient, - networkProvider: providers.StaticJsonRpcProvider, + networkProvider: JsonRpcProvider, transactionManager: TransactionManager, networkMonitor: NetworkMonitor, - receiptCollector: AllocationReceiptCollector | undefined, tapCollector: TapCollector | undefined, + graphTallyCollector: GraphTallyCollector | undefined, specification: spec.NetworkSpecification, paused: Eventual, isOperator: Eventual, + isHorizon: Eventual, + queryFeeModels: QueryFeeModels, + managementModels: IndexerManagementModels, + dipsCollector: DipsCollector | undefined, ) { this.logger = logger this.contracts = contracts @@ -74,16 +85,21 @@ export class Network { this.networkProvider = networkProvider this.transactionManager = transactionManager this.networkMonitor = networkMonitor - this.receiptCollector = receiptCollector this.tapCollector = tapCollector + this.graphTallyCollector = graphTallyCollector this.specification = specification this.paused = paused this.isOperator = isOperator + this.isHorizon = isHorizon + this.queryFeeModels = queryFeeModels + this.managementModels = managementModels + this.dipsCollector = dipsCollector } static async create( parentLogger: Logger, specification: spec.NetworkSpecification, + managementModels: IndexerManagementModels, queryFeeModels: QueryFeeModels, graphNode: GraphNode, metrics: Metrics, @@ -186,7 +202,8 @@ export class Network { wallet, specification.networkIdentifier, logger, - specification.addressBook, + specification.horizonAddressBook, + specification.subgraphServiceAddressBook, ) // * ----------------------------------------------------------------------- @@ -246,11 +263,12 @@ export class Network { const isOperator = await networkMonitor.monitorIsOperator( logger, - contracts, specification.indexerOptions.address, wallet, ) + const isHorizon = await networkMonitor.monitorIsHorizon(logger) + const transactionManager = new TransactionManager( networkProvider, wallet, @@ -268,7 +286,7 @@ export class Network { try { tapContracts = await connectTapContracts( wallet, - networkIdentifier.chainId, + Number(networkIdentifier.chainId), specification.tapAddressBook, ) } catch (err) { @@ -283,50 +301,61 @@ export class Network { indexer: toAddress(specification.indexerOptions.address), logger, networkSubgraph, - protocolNetwork: resolveChainId(networkIdentifier.chainId), + protocolNetwork: resolveChainId(Number(networkIdentifier.chainId)), interval: specification.allocationSyncInterval, }) // -------------------------------------------------------------------------------- - // * Allocation Receipt Collector + // * TAP Collector // -------------------------------------------------------------------------------- - let scalarCollector: AllocationReceiptCollector | undefined = undefined - if (!(tapContracts && tapSubgraph)) { - logger.warn( - "deprecated scalar voucher collector is enabled - you probably don't want this", - ) - scalarCollector = await AllocationReceiptCollector.create({ + let tapCollector: TapCollector | undefined = undefined + let dipsCollector: DipsCollector | undefined = undefined + if (tapContracts && tapSubgraph) { + tapCollector = TapCollector.create({ logger, metrics, transactionManager: transactionManager, models: queryFeeModels, - allocationExchange: contracts.allocationExchange, + tapContracts, allocations, networkSpecification: specification, + tapSubgraph, networkSubgraph, }) + if (specification.indexerOptions.enableDips) { + dipsCollector = DipsCollector.create( + logger, + managementModels, + specification, + wallet, + graphNode, + ) + } + } else { + logger.info(`RAV (and DIPs) process not initiated. + Tap Contracts: ${!!tapContracts}. + Tap Subgraph: ${!!tapSubgraph}.`) } // -------------------------------------------------------------------------------- - // * TAP Collector + // * Graph Tally Collector // -------------------------------------------------------------------------------- - let tapCollector: TapCollector | undefined = undefined - if (tapContracts && tapSubgraph) { - tapCollector = TapCollector.create({ + let graphTallyCollector: GraphTallyCollector | undefined = undefined + if (contracts && networkSubgraph) { + graphTallyCollector = GraphTallyCollector.create({ logger, metrics, transactionManager: transactionManager, models: queryFeeModels, - tapContracts, + contracts, allocations, networkSpecification: specification, - tapSubgraph, networkSubgraph, }) } else { - logger.info(`RAV process not initiated. - Tap Contracts: ${!!tapContracts}. - Tap Subgraph: ${!!tapSubgraph}.`) + logger.info(`RAV v2 process not initiated. + Contracts: ${!!contracts}. + Subgraph: ${!!networkSubgraph}.`) } // -------------------------------------------------------------------------------- @@ -340,11 +369,15 @@ export class Network { networkProvider, transactionManager, networkMonitor, - scalarCollector, tapCollector, + graphTallyCollector, specification, paused, isOperator, + isHorizon, + queryFeeModels, + managementModels, + dipsCollector, ) } @@ -354,7 +387,7 @@ export class Network { networkIdentifier: string, networkURL: string, pollingInterval: number, - ): Promise { + ): Promise { logger.info(`Connect to Network chain`, { provider: networkURL, pollingInterval, @@ -398,12 +431,13 @@ export class Network { password = providerUrl.password } - const networkProvider = new providers.StaticJsonRpcProvider({ - url: providerUrl.toString(), - user: username, - password: password, - allowInsecureAuthentication: true, - }) + const providerFetchRequest = new FetchRequest(providerUrl.toString()) + if (username !== undefined && password !== undefined) { + providerFetchRequest.setCredentials(username, password) + providerFetchRequest.allowInsecureAuthentication = true + } + + const networkProvider = new JsonRpcProvider(providerFetchRequest) networkProvider.pollingInterval = pollingInterval networkProvider.on('debug', (info) => { @@ -428,31 +462,36 @@ export class Network { }) logger.info(`Connected to network`, { - provider: networkProvider.connection.url, + provider: providerFetchRequest.url, pollingInterval: networkProvider.pollingInterval, - network: await networkProvider.detectNetwork(), + network: await networkProvider.getNetwork(), }) return networkProvider } // Start of SEND functions - async register(): Promise { - const geoHash = geohash.encode( - +this.specification.indexerOptions.geoCoordinates[0], - +this.specification.indexerOptions.geoCoordinates[1], - ) - + async provision(): Promise { const logger = this.logger.child({ address: this.specification.indexerOptions.address, - url: this.specification.indexerOptions.url, - geoCoordinates: this.specification.indexerOptions.geoCoordinates, - geoHash, }) - if (!this.specification.indexerOptions.register) { - logger.debug( - "Indexer was not registered because it was explicitly disabled in this Network's configuration.", + logger.info('Provision indexer to the Subgraph Service', { + maxProvisionInitialSize: formatGRT( + this.specification.indexerOptions.maxProvisionInitialSize, + ), + }) + + if (!(await this.isHorizon.value())) { + logger.info('Graph Horizon upgrade not detected, skipping provisioning.') + return + } + + const maxProvisionInitialSize = + this.specification.indexerOptions.maxProvisionInitialSize + if (maxProvisionInitialSize === 0n) { + logger.info( + 'Max provision initial size is 0, skipping provisioning. Please set to a non-zero value to enable Graph Horizon functionality.', ) return } @@ -460,59 +499,85 @@ export class Network { await pRetry( async () => { try { - logger.info(`Register indexer`) + const provision = await this.contracts.HorizonStaking.getProvision( + this.specification.indexerOptions.address, + this.contracts.SubgraphService.target, + ) + + if (provision.createdAt > 0n) { + logger.info('Indexer already provisioned, skipping provisioning.') + return + } + + const [thawingPeriod] = + await this.contracts.SubgraphService.getThawingPeriodRange() + const [maxVerifierCut] = + await this.contracts.SubgraphService.getVerifierCutRange() + const [minProvisionTokens] = + await this.contracts.SubgraphService.getProvisionTokensRange() - // Register the indexer (only if it hasn't been registered yet or - // if its URL is different from what is registered on chain) - const isRegistered = await this.contracts.serviceRegistry.isRegistered( + const indexerIdleStake = await this.contracts.HorizonStaking.getIdleStake( this.specification.indexerOptions.address, ) - if (isRegistered) { - const service = await this.contracts.serviceRegistry.services( - this.specification.indexerOptions.address, + + if (indexerIdleStake < minProvisionTokens) { + logger.warn( + 'Indexer idle stake is less than minimum provision tokens, skipping provisioning.', + { + indexerIdleStake: formatGRT(indexerIdleStake), + minProvisionTokens: formatGRT(minProvisionTokens), + }, ) - if ( - service.url === this.specification.indexerOptions.url && - service.geohash === geoHash - ) { - if (await this.transactionManager.isOperator.value()) { - logger.info(`Indexer already registered, operator status already granted`) - } else { - logger.info(`Indexer already registered, operator status not yet granted`) - } - return - } + return } + + const provisionTokens = + indexerIdleStake > maxProvisionInitialSize + ? maxProvisionInitialSize + : indexerIdleStake + + logger.info('Creating provision', { + tokens: formatGRT(provisionTokens), + thawingPeriod, + maxVerifierCut, + }) + const receipt = await this.transactionManager.executeTransaction( () => - this.contracts.serviceRegistry.estimateGas.registerFor( + this.contracts.HorizonStaking.provision.estimateGas( this.specification.indexerOptions.address, - this.specification.indexerOptions.url, - geoHash, + this.contracts.SubgraphService.target, + provisionTokens, + maxVerifierCut, + thawingPeriod, ), (gasLimit) => - this.contracts.serviceRegistry.registerFor( + this.contracts.HorizonStaking.provision( this.specification.indexerOptions.address, - this.specification.indexerOptions.url, - geoHash, + this.contracts.SubgraphService.target, + provisionTokens, + maxVerifierCut, + thawingPeriod, { gasLimit, }, ), - logger.child({ function: 'serviceRegistry.registerFor' }), + logger.child({ function: 'horizonStaking.provision' }), ) if (receipt === 'paused' || receipt === 'unauthorized') { return } - const events = receipt.events || receipt.logs + const events = receipt.logs const event = events.find((event) => event.topics.includes( - this.contracts.serviceRegistry.interface.getEventTopic('ServiceRegistered'), + // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain + this.contracts.HorizonStaking.interface.getEvent('ProvisionCreated') + ?.topicHash!, ), ) assert.ok(event) - logger.info(`Successfully registered indexer`) + logger.info(`Successfully provisioned to the Subgraph Service`) } catch (error) { const err = indexerError(IndexerErrorCode.IE012, error) logger.error(INDEXER_ERROR_MESSAGES[IndexerErrorCode.IE012], { @@ -524,29 +589,194 @@ export class Network { { retries: 5 } as Options, ) } + async register(): Promise { + const geoHash = geohash.encode( + +this.specification.indexerOptions.geoCoordinates[0], + +this.specification.indexerOptions.geoCoordinates[1], + ) + const url = this.specification.indexerOptions.url + + const logger = this.logger.child({ + address: this.specification.indexerOptions.address, + }) + + if (!this.specification.indexerOptions.register) { + logger.debug( + "Indexer was not registered because it was explicitly disabled in this Network's configuration.", + ) + return + } + + await pRetry( + async () => { + try { + if (await this.isHorizon.value()) { + await this._register(logger, geoHash, url) + } else { + await this._registerLegacy(logger, geoHash, url) + } + } catch (error) { + const err = indexerError(IndexerErrorCode.IE012, error) + logger.error(INDEXER_ERROR_MESSAGES[IndexerErrorCode.IE012], { + err, + }) + throw error + } + }, + { retries: 5 } as Options, + ) + } + + private async _register(logger: Logger, geoHash: string, url: string): Promise { + const paymentsDestination = + this.specification.indexerOptions.paymentsDestination?.toString() ?? + '0x0000000000000000000000000000000000000000' + + logger.info(`Register indexer`, { + url, + geoCoordinates: this.specification.indexerOptions.geoCoordinates, + geoHash, + paymentsDestination, + }) + + // Register the indexer (only if it hasn't been registered yet or + // if its URL/geohash is different from what is registered on chain) + const indexerRegistrationData = await this.contracts.SubgraphService.indexers( + this.specification.indexerOptions.address, + ) + const isRegistered = indexerRegistrationData.registeredAt !== 0n + if (isRegistered) { + if ( + indexerRegistrationData.url === url && + indexerRegistrationData.geoHash === geoHash + ) { + if (await this.transactionManager.isOperator.value()) { + logger.info(`Indexer already registered, operator status already granted`) + } else { + logger.info(`Indexer already registered, operator status not yet granted`) + } + return + } + } + const encodedData = encodeRegistrationData(url, geoHash, paymentsDestination) + const receipt = await this.transactionManager.executeTransaction( + () => + this.contracts.SubgraphService.register.estimateGas( + this.specification.indexerOptions.address, + encodedData, + ), + (gasLimit) => + this.contracts.SubgraphService.register( + this.specification.indexerOptions.address, + encodedData, + { + gasLimit, + }, + ), + logger.child({ function: 'subgraphService.register' }), + ) + if (receipt === 'paused' || receipt === 'unauthorized') { + return + } + const events = receipt.logs + const event = events.find((event) => + event.topics.includes( + // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain + this.contracts.SubgraphService.interface.getEvent('ServiceProviderRegistered') + ?.topicHash!, + ), + ) + assert.ok(event) + + logger.info(`Successfully registered indexer`) + } + + private async _registerLegacy( + logger: Logger, + geoHash: string, + url: string, + ): Promise { + logger.info(`Register indexer`, { + url, + geoCoordinates: this.specification.indexerOptions.geoCoordinates, + geoHash, + }) + + // Register the indexer (only if it hasn't been registered yet or + // if its URL/geohash is different from what is registered on chain) + const isRegistered = await this.contracts.LegacyServiceRegistry.isRegistered( + this.specification.indexerOptions.address, + ) + if (isRegistered) { + const service = await this.contracts.LegacyServiceRegistry.services( + this.specification.indexerOptions.address, + ) + if (service.url === url && service.geoHash === geoHash) { + if (await this.transactionManager.isOperator.value()) { + logger.info(`Indexer already registered, operator status already granted`) + } else { + logger.info(`Indexer already registered, operator status not yet granted`) + } + return + } + } + const receipt = await this.transactionManager.executeTransaction( + () => + this.contracts.LegacyServiceRegistry.registerFor.estimateGas( + this.specification.indexerOptions.address, + this.specification.indexerOptions.url, + geoHash, + ), + (gasLimit) => + this.contracts.LegacyServiceRegistry.registerFor( + this.specification.indexerOptions.address, + this.specification.indexerOptions.url, + geoHash, + { + gasLimit, + }, + ), + logger.child({ function: 'serviceRegistry.registerFor' }), + ) + if (receipt === 'paused' || receipt === 'unauthorized') { + return + } + const events = receipt.logs + const event = events.find((event) => + event.topics.includes( + // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain + this.contracts.LegacyServiceRegistry.interface.getEvent('ServiceRegistered') + ?.topicHash!, + ), + ) + assert.ok(event) + + logger.info(`Successfully registered indexer (Legacy registration)`) + } } async function connectWallet( - networkProvider: providers.Provider, + networkProvider: Provider, networkIdentifier: string, mnemonic: string, logger: Logger, -): Promise { +): Promise { logger.info(`Connect wallet`, { networkIdentifier: networkIdentifier, }) - let wallet = Wallet.fromMnemonic(mnemonic) + let wallet = Wallet.fromPhrase(mnemonic) wallet = wallet.connect(networkProvider) logger.info(`Connected wallet`) return wallet } async function connectToProtocolContracts( - wallet: Wallet, + wallet: HDNodeWallet, networkIdentifier: string, logger: Logger, - addressBook?: string, -): Promise { + horizonAddressBook?: string, + subgraphServiceAddressBook?: string, +): Promise { const numericNetworkId = parseInt(networkIdentifier.split(':')[1]) // Confidence check: Should be unreachable since NetworkSpecification was validated before @@ -556,29 +786,76 @@ async function connectToProtocolContracts( logger.info(`Connect to contracts`, { network: networkIdentifier, + horizonAddressBook, + subgraphServiceAddressBook, }) - let contracts + let contracts: GraphHorizonContracts & SubgraphServiceContracts try { - const contractAddresses = addressBook - ? (JSON.parse(readFileSync(addressBook).toString()) as AddressBook) - : undefined - contracts = await connectContracts(wallet, numericNetworkId, contractAddresses) + const horizonContracts = connectGraphHorizon( + numericNetworkId, + wallet, + horizonAddressBook, + ) + const subgraphServiceContracts = connectSubgraphService( + numericNetworkId, + wallet, + subgraphServiceAddressBook, + ) + contracts = { + ...horizonContracts, + ...subgraphServiceContracts, + } } catch (error) { const errorMessage = 'Failed to connect to contracts, please ensure you are using the intended protocol network.' logger.error(errorMessage, { error, networkIdentifier, numericNetworkId }) throw new Error(`${errorMessage} Error: ${error}`) } - logger.info(`Successfully connected to contracts`, { - curation: contracts.curation.address, - disputeManager: contracts.disputeManager.address, - epochManager: contracts.epochManager.address, - gns: contracts.gns.address, - rewardsManager: contracts.rewardsManager.address, - serviceRegistry: contracts.serviceRegistry.address, - staking: contracts.staking.address, - token: contracts.token.address, + + // Ensure we are connected to all required contracts + const requiredContracts = [ + 'EpochManager', + 'RewardsManager', + 'HorizonStaking', + 'GraphTallyCollector', + 'PaymentsEscrow', + 'SubgraphService', + ] + + // Before horizon we need the LegacyServiceRegistry contract as well + const isHorizon = await contracts.HorizonStaking.getMaxThawingPeriod() + .then((maxThawingPeriod) => maxThawingPeriod > 0) + // eslint-disable-next-line @typescript-eslint/no-unused-vars + .catch((_) => false) + if (!isHorizon) { + requiredContracts.push('LegacyServiceRegistry') + } + + const missingContracts = requiredContracts.filter( + (contract) => !(contract in contracts), + ) + if (missingContracts.length > 0) { + logger.fatal(`Missing required contracts`, { + err: indexerError(IndexerErrorCode.IE075), + missingContracts: missingContracts, + }) + process.exit(1) + } + + // Only list contracts that are used by the indexer + logger.info(`Successfully connected to Horizon contracts`, { + epochManager: contracts.EpochManager.target, + rewardsManager: contracts.RewardsManager.target, + staking: contracts.HorizonStaking.target, + graphTallyCollector: contracts.GraphTallyCollector.target, + graphPaymentsEscrow: contracts.PaymentsEscrow.target, + }) + logger.info(`Successfully connected to Subgraph Service contracts`, { + ...(isHorizon + ? {} + : { legacyServiceRegistry: contracts.LegacyServiceRegistry.target }), + subgraphService: contracts.SubgraphService.target, }) return contracts } diff --git a/packages/indexer-common/src/operator.ts b/packages/indexer-common/src/operator.ts index 1d97904c4..f85905aaf 100644 --- a/packages/indexer-common/src/operator.ts +++ b/packages/indexer-common/src/operator.ts @@ -16,16 +16,17 @@ import { specification as spec, Action, POIDisputeAttributes, + DipsManager, } from '@graphprotocol/indexer-common' import { Logger, formatGRT } from '@graphprotocol/common-ts' -import { BigNumber, utils } from 'ethers' +import { hexlify } from 'ethers' import gql from 'graphql-tag' import pMap from 'p-map' import { CombinedError } from '@urql/core' const POI_DISPUTES_CONVERTERS_FROM_GRAPHQL: Record< keyof POIDisputeAttributes, - (x: never) => string | BigNumber | number | null + (x: never) => string | bigint | number | null > = { allocationID: (x) => x, subgraphDeploymentID: (x) => x, @@ -82,6 +83,13 @@ export class Operator { this.specification = specification } + get dipsManager(): DipsManager | null { + const network = this.specification.networkIdentifier + const allocationManager = + this.indexerManagement.actionManager?.allocationManagers[network] + return allocationManager?.dipsManager ?? null + } + // -------------------------------------------------------------------------------- // * Indexing Rules // -------------------------------------------------------------------------------- @@ -244,6 +252,8 @@ export class Operator { transaction status failureReason + protocolNetwork + isLegacy } } `, @@ -258,16 +268,26 @@ export class Operator { return result.data.actions } - async queueAction(action: ActionItem): Promise { + async queueAction(action: ActionItem, forceAction: boolean = false): Promise { let status = ActionStatus.QUEUED switch (this.specification.indexerOptions.allocationManagementMode) { case AllocationManagementMode.MANUAL: - throw Error(`Cannot queue actions when AllocationManagementMode = 'MANUAL'`) + if (forceAction) { + status = ActionStatus.APPROVED + } else { + throw Error(`Cannot queue actions when AllocationManagementMode = 'MANUAL'`) + } + break case AllocationManagementMode.AUTO: status = ActionStatus.APPROVED break case AllocationManagementMode.OVERSIGHT: - status = ActionStatus.QUEUED + if (forceAction) { + status = ActionStatus.APPROVED + } else { + status = ActionStatus.QUEUED + } + break } const actionInput = { @@ -278,6 +298,7 @@ export class Operator { reason: action.reason, priority: 0, protocolNetwork: action.protocolNetwork, + isLegacy: action.isLegacy, } this.logger.trace(`Queueing action input`, { actionInput, @@ -295,6 +316,7 @@ export class Operator { priority status protocolNetwork + isLegacy } } `, @@ -314,6 +336,11 @@ export class Operator { `Action not queued: A recently executed action was found targeting ${actionInput.deploymentID}`, { action }, ) + } else { + this.logger.warn('Action not queued', { + action, + error: actionResult.error, + }) } return [] } @@ -336,21 +363,24 @@ export class Operator { logger: Logger, deploymentAllocationDecision: AllocationDecision, mostRecentlyClosedAllocation: Allocation | undefined, + isHorizon: boolean, + forceAction: boolean = false, ): Promise { const desiredAllocationAmount = deploymentAllocationDecision.ruleMatch.rule ?.allocationAmount - ? BigNumber.from(deploymentAllocationDecision.ruleMatch.rule.allocationAmount) + ? BigInt(deploymentAllocationDecision.ruleMatch.rule.allocationAmount) : this.specification.indexerOptions.defaultAllocationAmount logger.info(`No active allocation for deployment, creating one now`, { allocationAmount: formatGRT(desiredAllocationAmount), + isHorizon, }) // Skip allocating if the previous allocation for this deployment was closed with 0x00 POI but rules set to un-safe if ( deploymentAllocationDecision.ruleMatch.rule?.safety && mostRecentlyClosedAllocation && - mostRecentlyClosedAllocation.poi === utils.hexlify(Array(32).fill(0)) + mostRecentlyClosedAllocation.poi === hexlify(new Uint8Array(32).fill(0)) ) { logger.warn( `Skipping allocation to this deployment as the last allocation to it was closed with a zero POI`, @@ -363,16 +393,20 @@ export class Operator { return } - // Send AllocateAction to the queue - await this.queueAction({ - params: { - deploymentID: deploymentAllocationDecision.deployment.ipfsHash, - amount: formatGRT(desiredAllocationAmount), + // Send AllocateAction to the queue - isLegacy value depends on the horizon upgrade + await this.queueAction( + { + params: { + deploymentID: deploymentAllocationDecision.deployment.ipfsHash, + amount: formatGRT(desiredAllocationAmount), + }, + type: ActionType.ALLOCATE, + reason: deploymentAllocationDecision.reasonString(), + protocolNetwork: deploymentAllocationDecision.protocolNetwork, + isLegacy: !isHorizon, }, - type: ActionType.ALLOCATE, - reason: deploymentAllocationDecision.reasonString(), - protocolNetwork: deploymentAllocationDecision.protocolNetwork, - }) + forceAction, + ) return } @@ -381,36 +415,38 @@ export class Operator { logger: Logger, deploymentAllocationDecision: AllocationDecision, activeDeploymentAllocations: Allocation[], + forceAction: boolean = false, ): Promise { - const activeDeploymentAllocationsEligibleForClose = activeDeploymentAllocations.map( - (allocation) => allocation.id, - ) // Make sure to close all active allocations on the way out - if (activeDeploymentAllocationsEligibleForClose.length > 0) { + if (activeDeploymentAllocations.length > 0) { logger.info( `Deployment is not (or no longer) worth allocating towards, close allocations`, { - eligibleForClose: activeDeploymentAllocationsEligibleForClose, + eligibleForClose: activeDeploymentAllocations, reason: deploymentAllocationDecision.reasonString(), }, ) await pMap( // We can only close allocations from a previous epoch; // try the others again later - activeDeploymentAllocationsEligibleForClose, + activeDeploymentAllocations, async (allocation) => { - // Send unallocate action to the queue - await this.queueAction({ - params: { - allocationID: allocation, - deploymentID: deploymentAllocationDecision.deployment.ipfsHash, - poi: undefined, - force: false, - }, - type: ActionType.UNALLOCATE, - reason: deploymentAllocationDecision.reasonString(), - protocolNetwork: deploymentAllocationDecision.protocolNetwork, - } as ActionItem) + // Send unallocate action to the queue - isLegacy value depends on the allocation being closed + await this.queueAction( + { + params: { + allocationID: allocation.id, + deploymentID: deploymentAllocationDecision.deployment.ipfsHash, + poi: undefined, + force: false, + }, + type: ActionType.UNALLOCATE, + reason: deploymentAllocationDecision.reasonString(), + protocolNetwork: deploymentAllocationDecision.protocolNetwork, + isLegacy: allocation.isLegacy, + } as ActionItem, + forceAction, + ) }, { concurrency: 1 }, ) @@ -421,6 +457,7 @@ export class Operator { logger: Logger, deploymentAllocationDecision: AllocationDecision, expiredAllocations: Allocation[], + forceAction: boolean = false, ): Promise { if (deploymentAllocationDecision.ruleMatch.rule?.autoRenewal) { logger.info(`Reallocating expired allocations`, { @@ -430,23 +467,28 @@ export class Operator { const desiredAllocationAmount = deploymentAllocationDecision.ruleMatch.rule ?.allocationAmount - ? BigNumber.from(deploymentAllocationDecision.ruleMatch.rule.allocationAmount) + ? BigInt(deploymentAllocationDecision.ruleMatch.rule.allocationAmount) : this.specification.indexerOptions.defaultAllocationAmount // Queue reallocate actions to be picked up by the worker + // isLegacy value depends on the allocation being reallocated, the switch to horizon is done by changing the allocation type elsewhere await pMap( expiredAllocations, async (allocation) => { - await this.queueAction({ - params: { - allocationID: allocation.id, - deploymentID: deploymentAllocationDecision.deployment.ipfsHash, - amount: formatGRT(desiredAllocationAmount), + await this.queueAction( + { + params: { + allocationID: allocation.id, + deploymentID: deploymentAllocationDecision.deployment.ipfsHash, + amount: formatGRT(desiredAllocationAmount), + }, + type: ActionType.REALLOCATE, + reason: `${deploymentAllocationDecision.reasonString()}:allocationExpiring`, // Need to update to include 'ExpiringSoon' + protocolNetwork: deploymentAllocationDecision.protocolNetwork, + isLegacy: allocation.isLegacy, }, - type: ActionType.REALLOCATE, - reason: `${deploymentAllocationDecision.reasonString()}:allocationExpiring`, // Need to update to include 'ExpiringSoon' - protocolNetwork: deploymentAllocationDecision.protocolNetwork, - }) + forceAction, + ) }, { stopOnError: false, diff --git a/packages/indexer-common/src/parsers/test-utils.ts b/packages/indexer-common/src/parsers/test-utils.ts index 3463cbdec..e1bc167ad 100644 --- a/packages/indexer-common/src/parsers/test-utils.ts +++ b/packages/indexer-common/src/parsers/test-utils.ts @@ -6,7 +6,7 @@ import { displayZodParsingError } from './error-handling' import path from 'path' export function loadTestYamlConfig() { - const PUBLIC_JSON_RPC_ENDPOINT = 'https://ethereum-sepolia.publicnode.com' + const PUBLIC_JSON_RPC_ENDPOINT = 'https://sepolia-rollup.arbitrum.io/rpc' const testProviderUrl = process.env.INDEXER_TEST_JRPC_PROVIDER_URL ?? PUBLIC_JSON_RPC_ENDPOINT const INDEXER_TEST_API_KEY: string = process.env['INDEXER_TEST_API_KEY'] || '' diff --git a/packages/indexer-common/src/query-fees/models.ts b/packages/indexer-common/src/query-fees/models.ts index 095d60fe0..e3c9c328c 100644 --- a/packages/indexer-common/src/query-fees/models.ts +++ b/packages/indexer-common/src/query-fees/models.ts @@ -2,22 +2,33 @@ import { DataTypes, Sequelize, Model, Association, CreationOptional } from 'sequ import { Address, toAddress } from '@graphprotocol/common-ts' import { caip2IdRegex } from '../parsers' import { TAPVerifier } from '@semiotic-labs/tap-contracts-bindings' +import { RAV as RAVv2 } from '@graphprotocol/toolshed' +import { BytesLike } from 'ethers' export interface ScalarTapReceiptsAttributes { id: number - allocation_id: Address - signer_address: Address + allocation_id: string + signer_address: string signature: Uint8Array timestamp_ns: bigint nonce: bigint value: bigint error_log?: string } +export interface ScalarTapReceiptsCreationAttributes { + allocation_id: string + signer_address: string + signature: Uint8Array + timestamp_ns: bigint + nonce: bigint + value: bigint +} + export class ScalarTapReceipts - extends Model + extends Model implements ScalarTapReceiptsAttributes { - public id!: number + public id!: CreationOptional public allocation_id!: Address public signer_address!: Address public signature!: Uint8Array @@ -29,6 +40,41 @@ export class ScalarTapReceipts declare updatedAt: CreationOptional } +export interface TapHorizonReceiptsAttributes { + id: number + signer_address: Address + + signature: Uint8Array + collection_id: string + payer: Address + data_service: Address + service_provider: Address + timestamp_ns: bigint + nonce: bigint + value: bigint + + error_log?: string +} +export class TapHorizonReceipts + extends Model + implements TapHorizonReceiptsAttributes +{ + public id!: number + public signer_address!: Address + + public signature!: Uint8Array + public collection_id!: string + public payer!: Address + public data_service!: Address + public service_provider!: Address + public timestamp_ns!: bigint + public nonce!: bigint + public value!: bigint + + declare createdAt: CreationOptional + declare updatedAt: CreationOptional +} + export class ScalarTapReceiptsInvalid extends Model implements ScalarTapReceiptsAttributes @@ -45,6 +91,29 @@ export class ScalarTapReceiptsInvalid declare createdAt: CreationOptional declare updatedAt: CreationOptional } + +export class TapHorizonReceiptsInvalid + extends Model + implements TapHorizonReceiptsAttributes +{ + public id!: number + public signer_address!: Address + + public signature!: Uint8Array + public collection_id!: string + public payer!: Address + public data_service!: Address + public service_provider!: Address + public timestamp_ns!: bigint + public nonce!: bigint + public value!: bigint + + public error_log!: string + + declare createdAt: CreationOptional + declare updatedAt: CreationOptional +} + export interface AllocationReceiptAttributes { id: string allocation: Address @@ -100,6 +169,22 @@ export interface ReceiptAggregateVoucherAttributes { redeemedAt: Date | null final: boolean } + +export interface ReceiptAggregateVoucherV2Attributes { + signature: Uint8Array + collectionId: string + payer: string + dataService: string + serviceProvider: string + timestampNs: bigint + valueAggregate: bigint + metadata: string + + last: boolean + final: boolean + redeemedAt: Date | null +} + export interface FailedReceiptAggregateVoucherAttributes { allocationId: string senderAddress: string @@ -108,6 +193,16 @@ export interface FailedReceiptAggregateVoucherAttributes { reason: string } +export interface FailedReceiptAggregateVoucherV2Attributes { + collectionId: string + payer: string + dataService: string + serviceProvider: string + expectedRav: JSON + rav_response: JSON + reason: string +} + export class ReceiptAggregateVoucher extends Model implements ReceiptAggregateVoucherAttributes @@ -142,6 +237,54 @@ export class ReceiptAggregateVoucher } } +// TODO HORIZON: move this to the toolshed package +export type SignedRAVv2 = { + rav: RAVv2 + signature: BytesLike +} + +export class ReceiptAggregateVoucherV2 + extends Model + implements ReceiptAggregateVoucherV2Attributes +{ + public signature!: Uint8Array + public collectionId!: string + public payer!: Address + public dataService!: Address + public serviceProvider!: Address + public timestampNs!: bigint + public valueAggregate!: bigint + public metadata!: string + + public final!: boolean + public last!: boolean + + public redeemedAt!: Date | null + declare createdAt: CreationOptional + declare updatedAt: CreationOptional + + public readonly allocationSummary?: AllocationSummary + + public static associations: { + allocationSummary: Association + } + + getSignedRAV(): SignedRAVv2 { + return { + rav: { + collectionId: this.collectionId, + payer: this.payer, + dataService: this.dataService, + serviceProvider: this.serviceProvider, + timestampNs: Number(this.timestampNs), + valueAggregate: this.valueAggregate, + metadata: this.metadata, + }, + signature: this.signature, + } + } +} + export type SignedRAV = TAPVerifier.SignedRAVStruct export class FailedReceiptAggregateVoucher @@ -155,6 +298,19 @@ export class FailedReceiptAggregateVoucher public reason!: string } +export class FailedReceiptAggregateVoucherV2 + extends Model + implements FailedReceiptAggregateVoucherV2Attributes +{ + public collectionId!: string + public payer!: Address + public dataService!: Address + public serviceProvider!: Address + public expectedRav!: JSON + public rav_response!: JSON + public reason!: string +} + export interface TransferReceiptAttributes { id: number signer: Address @@ -250,14 +406,16 @@ export class AllocationSummary public readonly allocationReceipts?: AllocationReceipt[] public readonly voucher?: Voucher public readonly receiptAggregateVoucher?: ReceiptAggregateVoucher + public readonly receiptAggregateVoucherV2?: ReceiptAggregateVoucherV2 - public voucherType?: 'Voucher' | 'ReceiptAggregateVoucher' + public voucherType?: 'Voucher' | 'ReceiptAggregateVoucher' | 'ReceiptAggregateVoucherV2' public static associations: { transfers: Association allocationReceipts: Association voucher: Association receiptAggregateVoucher: Association + receiptAggregateVoucherV2: Association } } @@ -265,12 +423,14 @@ export interface QueryFeeModels { allocationReceipts: typeof AllocationReceipt vouchers: typeof Voucher receiptAggregateVouchers: typeof ReceiptAggregateVoucher + receiptAggregateVouchersV2: typeof ReceiptAggregateVoucherV2 transferReceipts: typeof TransferReceipt transfers: typeof Transfer allocationSummaries: typeof AllocationSummary scalarTapReceipts: typeof ScalarTapReceipts scalarTapReceiptsInvalid: typeof ScalarTapReceiptsInvalid failedReceiptAggregateVouchers: typeof FailedReceiptAggregateVoucher + failedReceiptAggregateVouchersV2: typeof FailedReceiptAggregateVoucherV2 } export function defineQueryFeeModels(sequelize: Sequelize): QueryFeeModels { @@ -416,6 +576,109 @@ export function defineQueryFeeModels(sequelize: Sequelize): QueryFeeModels { }, ) + ReceiptAggregateVoucherV2.init( + { + collectionId: { + type: DataTypes.CHAR(64), // 64 because prefix '0x' gets removed by GraphTally agent + allowNull: false, + primaryKey: true, + get() { + const rawValue = this.getDataValue('collectionId') + return toAddress(rawValue) + }, + set(value: string) { + const addressWithoutPrefix = value.toLowerCase().replace('0x', '') + this.setDataValue('collectionId', addressWithoutPrefix) + }, + }, + payer: { + type: DataTypes.CHAR(40), // 40 because prefix '0x' gets removed by TAP agent + allowNull: false, + primaryKey: true, + get() { + const rawValue = this.getDataValue('payer') + return toAddress(rawValue) + }, + set(value: string) { + const addressWithoutPrefix = value.toLowerCase().replace('0x', '') + this.setDataValue('payer', addressWithoutPrefix) + }, + }, + serviceProvider: { + type: DataTypes.CHAR(40), // 40 because prefix '0x' gets removed by TAP agent + allowNull: false, + primaryKey: true, + get() { + const rawValue = this.getDataValue('serviceProvider') + return toAddress(rawValue) + }, + set(value: string) { + const addressWithoutPrefix = value.toLowerCase().replace('0x', '') + this.setDataValue('serviceProvider', addressWithoutPrefix) + }, + }, + dataService: { + type: DataTypes.CHAR(40), // 40 because prefix '0x' gets removed by TAP agent + allowNull: false, + primaryKey: true, + get() { + const rawValue = this.getDataValue('dataService') + return toAddress(rawValue) + }, + set(value: string) { + const addressWithoutPrefix = value.toLowerCase().replace('0x', '') + this.setDataValue('dataService', addressWithoutPrefix) + }, + }, + metadata: { + type: DataTypes.BLOB, + allowNull: false, + }, + signature: { + type: DataTypes.BLOB, + allowNull: false, + }, + // ternary operator added to timestampNs and valueAggregate + // due to sequelize UPDATE + // calls the getters with undefined data + // 0 is returned since no real data is being requested + timestampNs: { + type: DataTypes.DECIMAL, + allowNull: false, + get() { + return BigInt(this.getDataValue('timestampNs')) + }, + }, + valueAggregate: { + type: DataTypes.DECIMAL, + allowNull: false, + get() { + return BigInt(this.getDataValue('valueAggregate')) + }, + }, + last: { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: false, + }, + final: { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: false, + }, + redeemedAt: { + type: DataTypes.DATE, + allowNull: true, + defaultValue: null, + }, + }, + { + underscored: true, + sequelize, + tableName: 'tap_horizon_ravs', + }, + ) + TransferReceipt.init( { id: { @@ -587,6 +850,80 @@ export function defineQueryFeeModels(sequelize: Sequelize): QueryFeeModels { }, ) + FailedReceiptAggregateVoucherV2.init( + { + collectionId: { + type: DataTypes.CHAR(64), + allowNull: false, + primaryKey: true, + get() { + const rawValue = this.getDataValue('collectionId') + return toAddress(rawValue) + }, + set(value: string) { + const addressWithoutPrefix = value.toLowerCase().replace('0x', '') + this.setDataValue('collectionId', addressWithoutPrefix) + }, + }, + payer: { + type: DataTypes.CHAR(40), // 40 because prefix '0x' gets removed by TAP agent + allowNull: false, + primaryKey: true, + get() { + const rawValue = this.getDataValue('payer') + return toAddress(rawValue) + }, + set(value: string) { + const addressWithoutPrefix = value.toLowerCase().replace('0x', '') + this.setDataValue('payer', addressWithoutPrefix) + }, + }, + serviceProvider: { + type: DataTypes.CHAR(40), // 40 because prefix '0x' gets removed by TAP agent + allowNull: false, + primaryKey: true, + get() { + const rawValue = this.getDataValue('serviceProvider') + return toAddress(rawValue) + }, + set(value: string) { + const addressWithoutPrefix = value.toLowerCase().replace('0x', '') + this.setDataValue('serviceProvider', addressWithoutPrefix) + }, + }, + dataService: { + type: DataTypes.CHAR(40), // 40 because prefix '0x' gets removed by TAP agent + allowNull: false, + primaryKey: true, + get() { + const rawValue = this.getDataValue('dataService') + return toAddress(rawValue) + }, + set(value: string) { + const addressWithoutPrefix = value.toLowerCase().replace('0x', '') + this.setDataValue('dataService', addressWithoutPrefix) + }, + }, + expectedRav: { + type: DataTypes.JSON, + allowNull: false, + }, + rav_response: { + type: DataTypes.JSON, + allowNull: false, + }, + reason: { + type: DataTypes.STRING, + allowNull: false, + }, + }, + { + underscored: true, + sequelize, + tableName: 'failed_receipt_aggregate_vouchers_v2', + }, + ) + ScalarTapReceipts.init( { id: { @@ -598,10 +935,26 @@ export function defineQueryFeeModels(sequelize: Sequelize): QueryFeeModels { allocation_id: { type: DataTypes.CHAR(40), allowNull: false, + get() { + const rawValue = this.getDataValue('allocation_id') + return toAddress(rawValue) + }, + set(value: Address) { + const addressWithoutPrefix = value.toLowerCase().replace('0x', '') + this.setDataValue('allocation_id', addressWithoutPrefix) + }, }, signer_address: { type: DataTypes.CHAR(40), allowNull: false, + get() { + const rawValue = this.getDataValue('signer_address') + return toAddress(rawValue) + }, + set(value: Address) { + const addressWithoutPrefix = value.toLowerCase().replace('0x', '') + this.setDataValue('signer_address', addressWithoutPrefix) + }, }, signature: { type: DataTypes.BLOB, @@ -627,6 +980,58 @@ export function defineQueryFeeModels(sequelize: Sequelize): QueryFeeModels { }, ) + TapHorizonReceipts.init( + { + id: { + type: DataTypes.INTEGER, + allowNull: false, + primaryKey: true, + autoIncrement: true, + }, + collection_id: { + type: DataTypes.CHAR(40), + allowNull: false, + }, + signer_address: { + type: DataTypes.CHAR(40), + allowNull: false, + }, + payer: { + type: DataTypes.CHAR(40), + allowNull: false, + }, + data_service: { + type: DataTypes.CHAR(40), + allowNull: false, + }, + service_provider: { + type: DataTypes.CHAR(40), + allowNull: false, + }, + signature: { + type: DataTypes.BLOB, + allowNull: false, + }, + timestamp_ns: { + type: DataTypes.BIGINT, + allowNull: false, + }, + nonce: { + type: DataTypes.BIGINT, + allowNull: false, + }, + value: { + type: DataTypes.BIGINT, + allowNull: false, + }, + }, + { + underscored: true, + sequelize, + tableName: 'tap_horizon_receipts', + }, + ) + ScalarTapReceiptsInvalid.init( { id: { @@ -672,6 +1077,63 @@ export function defineQueryFeeModels(sequelize: Sequelize): QueryFeeModels { }, ) + TapHorizonReceiptsInvalid.init( + { + id: { + type: DataTypes.INTEGER, + allowNull: false, + primaryKey: true, + autoIncrement: true, + }, + collection_id: { + type: DataTypes.CHAR(64), + allowNull: false, + }, + payer: { + type: DataTypes.CHAR(40), + allowNull: false, + }, + data_service: { + type: DataTypes.CHAR(40), + allowNull: false, + }, + service_provider: { + type: DataTypes.CHAR(40), + allowNull: false, + }, + signer_address: { + type: DataTypes.CHAR(40), + allowNull: false, + }, + timestamp_ns: { + type: DataTypes.BIGINT, + allowNull: false, + }, + nonce: { + type: DataTypes.BIGINT, + allowNull: false, + }, + value: { + type: DataTypes.BIGINT, + allowNull: false, + }, + signature: { + type: DataTypes.BLOB, + allowNull: false, + }, + error_log: { + type: DataTypes.TEXT, + allowNull: false, + defaultValue: '', + }, + }, + { + underscored: true, + sequelize, + tableName: 'tap_horizon_receipts_invalid', + }, + ) + Transfer.hasMany(TransferReceipt, { sourceKey: 'signer', foreignKey: 'signer', @@ -718,11 +1180,13 @@ export function defineQueryFeeModels(sequelize: Sequelize): QueryFeeModels { allocationReceipts: AllocationReceipt, vouchers: Voucher, receiptAggregateVouchers: ReceiptAggregateVoucher, + receiptAggregateVouchersV2: ReceiptAggregateVoucherV2, transferReceipts: TransferReceipt, transfers: Transfer, allocationSummaries: AllocationSummary, scalarTapReceipts: ScalarTapReceipts, scalarTapReceiptsInvalid: ScalarTapReceiptsInvalid, failedReceiptAggregateVouchers: FailedReceiptAggregateVoucher, + failedReceiptAggregateVouchersV2: FailedReceiptAggregateVoucherV2, } } diff --git a/packages/indexer-common/src/rules.ts b/packages/indexer-common/src/rules.ts index e03bfd40e..0d91f8f24 100644 --- a/packages/indexer-common/src/rules.ts +++ b/packages/indexer-common/src/rules.ts @@ -4,9 +4,9 @@ import { parseGRT } from '@graphprotocol/common-ts' import { validateNetworkIdentifier } from './parsers' export const parseDecisionBasis = (s: string): IndexingDecisionBasis => { - if (!['always', 'never', 'rules', 'offchain'].includes(s)) { + if (!['always', 'never', 'rules', 'offchain', 'dips'].includes(s)) { throw new Error( - `Unknown decision basis "${s}". Supported: always, never, rules, offchain`, + `Unknown decision basis "${s}". Supported: always, never, rules, offchain, dips`, ) } else { return s as IndexingDecisionBasis diff --git a/packages/indexer-common/src/subgraphs.ts b/packages/indexer-common/src/subgraphs.ts index 9ffb3fb06..9c8fb29a1 100644 --- a/packages/indexer-common/src/subgraphs.ts +++ b/packages/indexer-common/src/subgraphs.ts @@ -1,5 +1,4 @@ -import { base58 } from 'ethers/lib/utils' -import { BigNumber, utils } from 'ethers' +import { decodeBase58, isHexString } from 'ethers' import { Logger, SubgraphDeploymentID } from '@graphprotocol/common-ts' import { SubgraphDeployment } from './types' import { @@ -32,11 +31,7 @@ export async function validateSubgraphID( } const values = s.split('-') - if ( - values.length == 2 && - utils.isHexString(values[0], 20) && - !isNaN(parseInt(values[1])) - ) { + if (values.length == 2 && isHexString(values[0], 20) && !isNaN(parseInt(values[1]))) { return type } @@ -57,7 +52,7 @@ export async function validateDeploymentID( // Case 4: 'Qm...' try { // This will throw if it's not valid - base58.decode(s) + decodeBase58(s) if (s.length === 46) { return type @@ -68,7 +63,7 @@ export async function validateDeploymentID( // Case 5: '0x...' (32 bytes) try { - if (utils.isHexString(s, 32)) { + if (isHexString(s, 32)) { return type } } catch { @@ -157,6 +152,7 @@ export enum ActivationCriteria { OFFCHAIN = 'offchain', INVALID_ALLOCATION_AMOUNT = 'invalid_allocation_amount', L2_TRANSFER_SUPPORT = 'l2_transfer_support', + DIPS = 'dips', } interface RuleMatch { @@ -256,6 +252,14 @@ export function isDeploymentWorthAllocatingTowards( deployment.protocolNetwork, ) + case IndexingDecisionBasis.DIPS: + return new AllocationDecision( + deployment.id, + deploymentRule, + true, + ActivationCriteria.DIPS, + deployment.protocolNetwork, + ) case IndexingDecisionBasis.ALWAYS: return new AllocationDecision( deployment.id, @@ -281,11 +285,11 @@ export function isDeploymentWorthAllocatingTowards( deployment.protocolNetwork, ) case IndexingDecisionBasis.RULES: { - const stakedTokens = BigNumber.from(deployment.stakedTokens) - const signalledTokens = BigNumber.from(deployment.signalledTokens) - const avgQueryFees = BigNumber.from(deployment.queryFeesAmount) + const stakedTokens = deployment.stakedTokens + const signalledTokens = deployment.signalledTokens + const avgQueryFees = deployment.queryFeesAmount - if (deploymentRule.minStake && stakedTokens.gte(deploymentRule.minStake)) { + if (deploymentRule.minStake && stakedTokens >= BigInt(deploymentRule.minStake)) { return new AllocationDecision( deployment.id, deploymentRule, @@ -295,7 +299,7 @@ export function isDeploymentWorthAllocatingTowards( ) } else if ( deploymentRule.minSignal && - signalledTokens.gte(deploymentRule.minSignal) + signalledTokens >= BigInt(deploymentRule.minSignal) ) { return new AllocationDecision( deployment.id, @@ -306,7 +310,7 @@ export function isDeploymentWorthAllocatingTowards( ) } else if ( deploymentRule.minAverageQueryFees && - avgQueryFees.gte(deploymentRule.minAverageQueryFees) + avgQueryFees >= BigInt(deploymentRule.minAverageQueryFees) ) { return new AllocationDecision( deployment.id, diff --git a/packages/indexer-common/src/transactions.ts b/packages/indexer-common/src/transactions.ts index ba3db3309..fc99bbf20 100644 --- a/packages/indexer-common/src/transactions.ts +++ b/packages/indexer-common/src/transactions.ts @@ -1,20 +1,18 @@ import { - BigNumber, BigNumberish, - ContractReceipt, - ContractTransaction, - providers, - utils, - Wallet, + HDNodeWallet, + parseUnits, + Provider, + TransactionReceipt, + TransactionRequest, + ContractTransactionResponse, + TransactionResponse, + toUtf8String, + FeeData, + Interface, + Result, } from 'ethers' -import { - Address, - Eventual, - Logger, - mutable, - NetworkContracts, - toAddress, -} from '@graphprotocol/common-ts' +import { Eventual, Logger } from '@graphprotocol/common-ts' import delay from 'delay' import { TransactionMonitoring } from './network-specification' import { IndexerError, indexerError, IndexerErrorCode } from './errors' @@ -22,19 +20,23 @@ import { TransactionConfig, TransactionType } from './types' import { SubgraphClient } from './subgraph-client' import gql from 'graphql-tag' import { sequentialTimerReduce } from './sequential-timer' +import { + GraphHorizonContracts, + SubgraphServiceContracts, +} from '@graphprotocol/toolshed/deployments' export class TransactionManager { - ethereum: providers.BaseProvider - wallet: Wallet + ethereum: Provider + wallet: HDNodeWallet paused: Eventual isOperator: Eventual specification: TransactionMonitoring - adjustedGasIncreaseFactor: BigNumber + adjustedGasIncreaseFactor: bigint adjustedBaseFeePerGasMax: number constructor( - ethereum: providers.BaseProvider, - wallet: Wallet, + ethereum: Provider, + wallet: HDNodeWallet, paused: Eventual, isOperator: Eventual, specification: TransactionMonitoring, @@ -44,7 +46,7 @@ export class TransactionManager { this.paused = paused this.isOperator = isOperator this.specification = specification - this.adjustedGasIncreaseFactor = utils.parseUnits( + this.adjustedGasIncreaseFactor = parseUnits( specification.gasIncreaseFactor.toString(), 3, ) @@ -53,10 +55,10 @@ export class TransactionManager { } async executeTransaction( - gasEstimation: () => Promise, - transaction: (gasLimit: BigNumberish) => Promise, + gasEstimation: () => Promise, + transaction: (gasLimit: BigNumberish) => Promise, logger: Logger, - ): Promise { + ): Promise { if (await this.paused.value()) { logger.info(`Network is paused, skipping this action`) return 'paused' @@ -68,14 +70,14 @@ export class TransactionManager { } let pending = true - let output: providers.TransactionReceipt | undefined = undefined + let output: TransactionReceipt | undefined = undefined const feeData = await this.waitForGasPricesBelowThreshold(logger) - const paddedGasLimit = Math.ceil((await gasEstimation()).toNumber() * 1.5) + const paddedGasLimit = Math.ceil(Number(await gasEstimation()) * 1.5) const txPromise = transaction(paddedGasLimit) - let tx = await txPromise - let txRequest: providers.TransactionRequest | undefined = undefined + let tx: TransactionResponse = await txPromise + let txRequest: TransactionRequest | undefined = undefined let txConfig: TransactionConfig = { attempt: 1, @@ -122,18 +124,25 @@ export class TransactionManager { tx = await this.wallet.sendTransaction(txRequest) } - logger.info(`Transaction pending`, { tx: tx }) + logger.info(`Transaction pending`, { + tx: tx, + confirmationBlocks: this.specification.confirmationBlocks, + }) const receipt = await this.ethereum.waitForTransaction( tx.hash, - 3, + this.specification.confirmationBlocks, this.specification.gasIncreaseTimeout, ) + if (receipt === null) { + throw indexerError(IndexerErrorCode.IE057) + } + if (receipt.status == 0) { const revertReason = await this.getRevertReason( logger, - txRequest as providers.TransactionRequest, + txRequest as TransactionRequest, ) if (revertReason === 'out of gas') { throw indexerError(IndexerErrorCode.IE050) @@ -159,14 +168,11 @@ export class TransactionManager { return output! } - async getRevertReason( - logger: Logger, - txRequest: providers.TransactionRequest, - ): Promise { + async getRevertReason(logger: Logger, txRequest: TransactionRequest): Promise { let revertReason = 'unknown' try { const code = await this.ethereum.call(txRequest) - revertReason = utils.toUtf8String(`0x${code.substr(138)}`) + revertReason = toUtf8String(`0x${code.substr(138)}`) } catch (e) { if (e.body.includes('out of gas')) { revertReason = 'out of gas' @@ -188,10 +194,12 @@ export class TransactionManager { }) if (error instanceof IndexerError) { if (error.code == IndexerErrorCode.IE050) { - txConfig.gasLimit = BigNumber.from(txConfig.gasLimit) - .mul(txConfig.gasBump) - .div(1000) - txConfig.nonce = BigNumber.from(txConfig.nonce).add(1) + if (txConfig.gasLimit) { + txConfig.gasLimit = (BigInt(txConfig.gasLimit) * txConfig.gasBump) / 1000n + } + if (txConfig.nonce) { + txConfig.nonce = txConfig.nonce + 1 + } } else if (error.code == IndexerErrorCode.IE051) { throw error } @@ -213,7 +221,9 @@ export class TransactionManager { 'Transaction nonce is too low. Try incrementing the nonce.', ) ) { - txConfig.nonce = BigNumber.from(txConfig.nonce).add(1) + if (txConfig.nonce) { + txConfig.nonce = txConfig.nonce + 1 + } } else if ( error.message.includes('Try increasing the fee') || error.message.includes('gas price supplied is too low') || @@ -221,24 +231,26 @@ export class TransactionManager { ) { // Transaction timed out or failed due to a low gas price estimation, bump gas price and retry if (txConfig.type === TransactionType.ZERO) { - txConfig.gasPrice = BigNumber.from(txConfig.gasPrice) - .mul(txConfig.gasBump) - .div(1000) + if (txConfig.gasPrice) { + txConfig.gasPrice = (BigInt(txConfig.gasPrice) * txConfig.gasBump) / 1000n + } } else if (txConfig.type == TransactionType.TWO) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - txConfig.maxFeePerGas = BigNumber.from(txConfig.maxFeePerGas) - .mul(txConfig.gasBump) - .div(1000) - txConfig.maxPriorityFeePerGas = BigNumber.from(txConfig.maxPriorityFeePerGas) - .mul(txConfig.gasBump) - .div(1000) + if (txConfig.maxFeePerGas) { + txConfig.maxFeePerGas = + (BigInt(txConfig.maxFeePerGas) * txConfig.gasBump) / 1000n + } + if (txConfig.maxPriorityFeePerGas) { + txConfig.maxPriorityFeePerGas = + (BigInt(txConfig.maxPriorityFeePerGas) * txConfig.gasBump) / 1000n + } } } } txConfig.attempt += 1 return txConfig } - async transactionType(data: providers.FeeData): Promise { + async transactionType(data: FeeData): Promise { if (data.maxPriorityFeePerGas && data.maxFeePerGas) { return TransactionType.TWO } else if (data.gasPrice) { @@ -249,28 +261,37 @@ export class TransactionManager { ) } } - async waitForGasPricesBelowThreshold(logger: Logger): Promise { + async waitForGasPricesBelowThreshold(logger: Logger): Promise { let attempt = 1 let aboveThreshold = true let feeData = { gasPrice: null, maxFeePerGas: null, maxPriorityFeePerGas: null, - } as providers.FeeData + } as { + gasPrice: bigint | null + maxFeePerGas: bigint | null + maxPriorityFeePerGas: bigint | null + } while (aboveThreshold) { - feeData = await this.ethereum.getFeeData() - const type = await this.transactionType(feeData) + const providerFeeData = await this.ethereum.getFeeData() + feeData = { + gasPrice: providerFeeData.gasPrice, + maxFeePerGas: providerFeeData.maxFeePerGas, + maxPriorityFeePerGas: providerFeeData.maxPriorityFeePerGas, + } + const type = await this.transactionType(providerFeeData) if (type === TransactionType.TWO) { // Type 0x02 transaction // This baseFeePerGas calculation is based off how maxFeePerGas is calculated in getFeeData() // https://github.com/ethers-io/ethers.js/blob/68229ac0aff790b083717dc73cd84f38d32a3926/packages/abstract-provider/src.ts/index.ts#L247 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const baseFeePerGas = feeData - .maxFeePerGas! // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - .sub(feeData.maxPriorityFeePerGas!) - .div(2) - if (baseFeePerGas.toNumber() >= this.adjustedBaseFeePerGasMax) { + const baseFeePerGas = + (feeData.maxFeePerGas! - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + feeData.maxPriorityFeePerGas!) / + 2n + if (Number(baseFeePerGas) >= this.adjustedBaseFeePerGasMax) { if (attempt === 1) { logger.warning( `Max base fee per gas has been reached, waiting until the base fee falls below to resume transaction execution.`, @@ -279,7 +300,7 @@ export class TransactionManager { } else { logger.info(`Base gas fee per gas estimation still above max threshold`, { maxBaseFeePerGas: this.specification.baseFeePerGasMax, - baseFeePerGas: baseFeePerGas.toNumber(), + baseFeePerGas: Number(baseFeePerGas), priceEstimateAttempt: attempt, }) } @@ -292,19 +313,19 @@ export class TransactionManager { } else if (type === TransactionType.ZERO) { // Legacy transaction type // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - if (feeData.gasPrice!.toNumber() >= this.adjustedBaseFeePerGasMax) { + if (Number(feeData.gasPrice!) >= this.adjustedBaseFeePerGasMax) { if (attempt === 1) { logger.warning( `Max gas price has been reached, waiting until gas price estimates fall below to resume transaction execution.`, { baseFeePerGasMax: this.specification.baseFeePerGasMax, - currentGasPriceEstimate: feeData.gasPrice!.toNumber(), + currentGasPriceEstimate: Number(feeData.gasPrice!), }, ) } else { logger.info(`Gas price estimation still above max threshold`, { baseFeePerGasMax: this.specification.baseFeePerGasMax, - currentGasPriceEstimate: feeData.gasPrice!.toNumber(), + currentGasPriceEstimate: Number(feeData.gasPrice!), priceEstimateAttempt: attempt, }) } @@ -315,12 +336,12 @@ export class TransactionManager { } } } - return feeData + return feeData as FeeData } async monitorNetworkPauses( logger: Logger, - contracts: NetworkContracts, + contracts: GraphHorizonContracts & SubgraphServiceContracts, networkSubgraph: SubgraphClient, ): Promise> { return sequentialTimerReduce( @@ -355,84 +376,52 @@ export class TransactionManager { return currentlyPaused } }, - await contracts.controller.paused(), + await contracts.Controller.paused(), ).map((paused) => { logger.info(paused ? `Network paused` : `Network active`) return paused }) } - async monitorIsOperator( - logger: Logger, - contracts: NetworkContracts, - indexerAddress: Address, - wallet: Wallet, - ): Promise> { - // If indexer and operator address are identical, operator status is - // implicitly granted => we'll never have to check again - if (indexerAddress === toAddress(wallet.address)) { - logger.info(`Indexer and operator are identical, operator status granted`) - return mutable(true) - } - - return sequentialTimerReduce( - { - logger, - milliseconds: 60_000, - }, - async (isOperator) => { - try { - return await contracts.staking.isOperator(wallet.address, indexerAddress) - } catch (err) { - logger.warn( - `Failed to check operator status for indexer, assuming it has not changed`, - { err: indexerError(IndexerErrorCode.IE008, err), isOperator }, - ) - return isOperator - } - }, - await contracts.staking.isOperator(wallet.address, indexerAddress), - ).map((isOperator) => { - logger.info( - isOperator - ? `Have operator status for indexer` - : `No operator status for indexer`, - ) - return isOperator - }) - } - findEvent( eventType: string, - contractInterface: utils.Interface, + contractInterface: Interface, logKey: string, logValue: string, - receipt: ContractReceipt, + receipt: TransactionReceipt, logger: Logger, - ): utils.Result | undefined { - const events: Event[] | providers.Log[] = receipt.events || receipt.logs - const decodedEvents: utils.Result[] = [] - const expectedTopic = contractInterface.getEventTopic(eventType) + ): Result | undefined { + const events = receipt.logs + const decodedEvents: Result[] = [] + const expectedEvent = contractInterface.getEvent(eventType) + const expectedTopicHash = expectedEvent?.topicHash + + if (!expectedTopicHash) { + throw new Error(`Event type ${eventType} not found in contract interface`) + } const result = events - .filter((event) => event.topics.includes(expectedTopic)) + .filter((event) => event.topics.includes(expectedTopicHash)) .map((event) => { const decoded = contractInterface.decodeEventLog( - eventType, + expectedEvent, event.data, event.topics, ) decodedEvents.push(decoded) return decoded }) - .find( - (eventLogs) => - eventLogs[logKey].toLocaleLowerCase() === logValue.toLocaleLowerCase(), - ) + .find((eventLogs) => { + return ( + eventLogs[logKey] && + eventLogs[logKey].toString().toLocaleLowerCase() === + logValue.toLocaleLowerCase() + ) + }) logger.trace('Searched for event logs', { function: 'findEvent', - expectedTopic, + expectedTopicHash, events, decodedEvents, eventType, diff --git a/packages/indexer-common/src/types.ts b/packages/indexer-common/src/types.ts index cfd62747a..7b3f5039f 100644 --- a/packages/indexer-common/src/types.ts +++ b/packages/indexer-common/src/types.ts @@ -1,5 +1,5 @@ import { SubgraphDeploymentID } from '@graphprotocol/common-ts' -import { BigNumber, providers } from 'ethers' +import { TransactionRequest } from 'ethers' export enum AllocationManagementMode { AUTO = 'auto', @@ -60,9 +60,9 @@ export interface Subgraph { export interface SubgraphDeployment { id: SubgraphDeploymentID deniedAt: number - stakedTokens: BigNumber - signalledTokens: BigNumber - queryFeesAmount: BigNumber + stakedTokens: bigint + signalledTokens: bigint + queryFeesAmount: bigint protocolNetwork: string } @@ -73,13 +73,13 @@ export interface TransferredSubgraphDeployment { idOnL1: string idOnL2: string startedTransferToL2L: boolean - startedTransferToL2At: BigNumber - startedTransferToL2AtBlockNumber: BigNumber + startedTransferToL2At: bigint + startedTransferToL2AtBlockNumber: bigint startedTransferToL2AtTx: string transferredToL2: boolean | null - transferredToL2At: BigNumber | null + transferredToL2At: bigint | null transferredToL2AtTx: string | null - transferredToL2AtBlockNumber: BigNumber | null + transferredToL2AtBlockNumber: bigint | null ipfsHash: string protocolNetwork: string ready: boolean | null @@ -90,9 +90,9 @@ export enum TransactionType { TWO, } -export interface TransactionConfig extends providers.TransactionRequest { +export interface TransactionConfig extends TransactionRequest { attempt: number - gasBump: BigNumber + gasBump: bigint type: TransactionType } @@ -106,3 +106,8 @@ export function parseDeploymentManagementMode(input: string): DeploymentManageme throw new Error(`Invalid value for deployment management mode: ${input}`) } } + +export type HorizonTransitionValue = { + legacy: U + horizon: V +} diff --git a/packages/indexer-common/src/utils.ts b/packages/indexer-common/src/utils.ts index f9c4b014d..42ed703ff 100644 --- a/packages/indexer-common/src/utils.ts +++ b/packages/indexer-common/src/utils.ts @@ -1,9 +1,10 @@ -import { Wallet, utils } from 'ethers' import { - BaseProvider, + Provider, JsonRpcProvider, getDefaultProvider, -} from '@ethersproject/providers' + formatEther, + HDNodeWallet, +} from 'ethers' import { Logger, Metrics } from '@graphprotocol/common-ts' import { indexerError, IndexerErrorCode } from './errors' import { DocumentNode, SelectionSetNode, Kind } from 'graphql' @@ -21,7 +22,7 @@ export function nullPassThrough(fn: (x: T) => U): (x: T | null) => U | nul return (x: T | null) => (x === null ? null : fn(x)) } -export function getTestProvider(network: string): BaseProvider { +export function getTestProvider(network: string): Provider { const testJsonRpcProviderUrl = process.env.INDEXER_TEST_JRPC_PROVIDER_URL if (testJsonRpcProviderUrl) { return new JsonRpcProvider(testJsonRpcProviderUrl) @@ -40,7 +41,7 @@ const registerMetrics = (metrics: Metrics, networkIdentifier: string) => ({ export async function monitorEthBalance( logger: Logger, - wallet: Wallet, + wallet: HDNodeWallet, metrics: Metrics, networkIdentifier: string, ): Promise { @@ -52,8 +53,8 @@ export async function monitorEthBalance( sequentialTimerMap({ logger, milliseconds: 120_000 }, async () => { try { - const balance = await wallet.getBalance() - const eth = parseFloat(utils.formatEther(balance)) + const balance = await wallet.provider!.getBalance(wallet.address) + const eth = parseFloat(formatEther(balance)) balanceMetrics.operatorEthBalance.set(eth) logger.info('Current operator ETH balance', { balance: eth, diff --git a/scripts/run-tests.sh b/scripts/run-tests.sh old mode 100644 new mode 100755 diff --git a/yarn.lock b/yarn.lock index 1536852f1..64f1325e7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,11 @@ # yarn lockfile v1 +"@adraffy/ens-normalize@1.10.1": + version "1.10.1" + resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz#63430d04bd8c5e74f8d7d049338f1cd9d4f02069" + integrity sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw== + "@ampproject/remapping@^2.2.0": version "2.3.0" resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4" @@ -10,178 +15,114 @@ "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.24" -"@babel/code-frame@^7.0.0": - version "7.22.13" - resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz" - integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w== - dependencies: - "@babel/highlight" "^7.22.13" - chalk "^2.4.2" - -"@babel/code-frame@^7.12.13", "@babel/code-frame@^7.23.5", "@babel/code-frame@^7.24.2": - version "7.24.2" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.2.tgz#718b4b19841809a58b29b68cde80bc5e1aa6d9ae" - integrity sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.27.1.tgz#200f715e66d52a23b221a9435534a91cc13ad5be" + integrity sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg== dependencies: - "@babel/highlight" "^7.24.2" - picocolors "^1.0.0" + "@babel/helper-validator-identifier" "^7.27.1" + js-tokens "^4.0.0" + picocolors "^1.1.1" -"@babel/compat-data@^7.23.5": - version "7.24.4" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.24.4.tgz#6f102372e9094f25d908ca0d34fc74c74606059a" - integrity sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ== +"@babel/compat-data@^7.27.2": + version "7.27.2" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.27.2.tgz#4183f9e642fd84e74e3eea7ffa93a412e3b102c9" + integrity sha512-TUtMJYRPyUb/9aU8f3K0mjmjf6M9N5Woshn2CS6nqJSeJtTtQcpLUXjGt9vbF8ZGff0El99sWkLgzwW3VXnxZQ== "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.23.9": - version "7.24.5" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.24.5.tgz#15ab5b98e101972d171aeef92ac70d8d6718f06a" - integrity sha512-tVQRucExLQ02Boi4vdPp49svNGcfL2GhdTCT9aldhXgCJVAI21EtRfBettiuLUwce/7r6bFdgs6JFkcdTiFttA== + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.27.1.tgz#89de51e86bd12246003e3524704c49541b16c3e6" + integrity sha512-IaaGWsQqfsQWVLqMn9OB92MNN7zukfVA4s7KKAI0KfrrDsZ0yhi5uV4baBuLuN7n3vsZpwP8asPPcVwApxvjBQ== dependencies: "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.24.2" - "@babel/generator" "^7.24.5" - "@babel/helper-compilation-targets" "^7.23.6" - "@babel/helper-module-transforms" "^7.24.5" - "@babel/helpers" "^7.24.5" - "@babel/parser" "^7.24.5" - "@babel/template" "^7.24.0" - "@babel/traverse" "^7.24.5" - "@babel/types" "^7.24.5" + "@babel/code-frame" "^7.27.1" + "@babel/generator" "^7.27.1" + "@babel/helper-compilation-targets" "^7.27.1" + "@babel/helper-module-transforms" "^7.27.1" + "@babel/helpers" "^7.27.1" + "@babel/parser" "^7.27.1" + "@babel/template" "^7.27.1" + "@babel/traverse" "^7.27.1" + "@babel/types" "^7.27.1" convert-source-map "^2.0.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.2.3" semver "^6.3.1" -"@babel/generator@^7.24.5", "@babel/generator@^7.7.2": - version "7.24.5" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.24.5.tgz#e5afc068f932f05616b66713e28d0f04e99daeb3" - integrity sha512-x32i4hEXvr+iI0NEoEfDKzlemF8AmtOP8CcrRaEcpzysWuoEb1KknpcvMsHKPONoKZiDuItklgWhB18xEhr9PA== +"@babel/generator@^7.27.1", "@babel/generator@^7.7.2": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.27.1.tgz#862d4fad858f7208edd487c28b58144036b76230" + integrity sha512-UnJfnIpc/+JO0/+KRVQNGU+y5taA5vCbwN8+azkX6beii/ZF+enZJSOKo11ZSzGJjlNfJHfQtmQT8H+9TXPG2w== dependencies: - "@babel/types" "^7.24.5" + "@babel/parser" "^7.27.1" + "@babel/types" "^7.27.1" "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.25" - jsesc "^2.5.1" + jsesc "^3.0.2" -"@babel/helper-compilation-targets@^7.23.6": - version "7.23.6" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz#4d79069b16cbcf1461289eccfbbd81501ae39991" - integrity sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ== +"@babel/helper-compilation-targets@^7.27.1": + version "7.27.2" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz#46a0f6efab808d51d29ce96858dd10ce8732733d" + integrity sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ== dependencies: - "@babel/compat-data" "^7.23.5" - "@babel/helper-validator-option" "^7.23.5" - browserslist "^4.22.2" + "@babel/compat-data" "^7.27.2" + "@babel/helper-validator-option" "^7.27.1" + browserslist "^4.24.0" lru-cache "^5.1.1" semver "^6.3.1" -"@babel/helper-environment-visitor@^7.22.20": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" - integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== - -"@babel/helper-function-name@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" - integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== - dependencies: - "@babel/template" "^7.22.15" - "@babel/types" "^7.23.0" - -"@babel/helper-hoist-variables@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" - integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== - dependencies: - "@babel/types" "^7.22.5" - -"@babel/helper-module-imports@^7.24.3": - version "7.24.3" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz#6ac476e6d168c7c23ff3ba3cf4f7841d46ac8128" - integrity sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg== - dependencies: - "@babel/types" "^7.24.0" - -"@babel/helper-module-transforms@^7.23.3", "@babel/helper-module-transforms@^7.24.5": - version "7.24.5" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.24.5.tgz#ea6c5e33f7b262a0ae762fd5986355c45f54a545" - integrity sha512-9GxeY8c2d2mdQUP1Dye0ks3VDyIMS98kt/llQ2nUId8IsWqTF0l1LkSX0/uP7l7MCDrzXS009Hyhe2gzTiGW8A== - dependencies: - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-module-imports" "^7.24.3" - "@babel/helper-simple-access" "^7.24.5" - "@babel/helper-split-export-declaration" "^7.24.5" - "@babel/helper-validator-identifier" "^7.24.5" - -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.24.0", "@babel/helper-plugin-utils@^7.8.0": - version "7.24.5" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.5.tgz#a924607dd254a65695e5bd209b98b902b3b2f11a" - integrity sha512-xjNLDopRzW2o6ba0gKbkZq5YWEBaK3PCyTOY1K2P/O07LGMhMqlMXPxwN4S5/RhWuCobT8z0jrlKGlYmeR1OhQ== - -"@babel/helper-simple-access@^7.22.5", "@babel/helper-simple-access@^7.24.5": - version "7.24.5" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.24.5.tgz#50da5b72f58c16b07fbd992810be6049478e85ba" - integrity sha512-uH3Hmf5q5n7n8mz7arjUlDOCbttY/DW4DYhE6FUsjKJ/oYC1kQQUvwEQWxRwUpX9qQKRXeqLwWxrqilMrf32sQ== - dependencies: - "@babel/types" "^7.24.5" - -"@babel/helper-split-export-declaration@^7.24.5": - version "7.24.5" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.5.tgz#b9a67f06a46b0b339323617c8c6213b9055a78b6" - integrity sha512-5CHncttXohrHk8GWOFCcCl4oRD9fKosWlIRgWm4ql9VYioKm52Mk2xsmoohvm7f3JoiLSM5ZgJuRaf5QZZYd3Q== - dependencies: - "@babel/types" "^7.24.5" - -"@babel/helper-string-parser@^7.24.1": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz#f99c36d3593db9540705d0739a1f10b5e20c696e" - integrity sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ== - -"@babel/helper-validator-identifier@^7.22.20": - version "7.22.20" - resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz" - integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== - -"@babel/helper-validator-identifier@^7.24.5": - version "7.24.5" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.5.tgz#918b1a7fa23056603506370089bd990d8720db62" - integrity sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA== - -"@babel/helper-validator-option@^7.23.5": - version "7.23.5" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz#907a3fbd4523426285365d1206c423c4c5520307" - integrity sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw== - -"@babel/helpers@^7.24.5": - version "7.24.5" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.24.5.tgz#fedeb87eeafa62b621160402181ad8585a22a40a" - integrity sha512-CiQmBMMpMQHwM5m01YnrM6imUG1ebgYJ+fAIW4FZe6m4qHTPaRHti+R8cggAwkdz4oXhtO4/K9JWlh+8hIfR2Q== - dependencies: - "@babel/template" "^7.24.0" - "@babel/traverse" "^7.24.5" - "@babel/types" "^7.24.5" - -"@babel/highlight@^7.22.13": - version "7.22.20" - resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz" - integrity sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg== - dependencies: - "@babel/helper-validator-identifier" "^7.22.20" - chalk "^2.4.2" - js-tokens "^4.0.0" +"@babel/helper-module-imports@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz#7ef769a323e2655e126673bb6d2d6913bbead204" + integrity sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w== + dependencies: + "@babel/traverse" "^7.27.1" + "@babel/types" "^7.27.1" -"@babel/highlight@^7.24.2": - version "7.24.5" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.5.tgz#bc0613f98e1dd0720e99b2a9ee3760194a704b6e" - integrity sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw== +"@babel/helper-module-transforms@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.27.1.tgz#e1663b8b71d2de948da5c4fb2a20ca4f3ec27a6f" + integrity sha512-9yHn519/8KvTU5BjTVEEeIM3w9/2yXNKoD82JifINImhpKkARMJKPP59kLo+BafpdN5zgNeIcS4jsGDmd3l58g== dependencies: - "@babel/helper-validator-identifier" "^7.24.5" - chalk "^2.4.2" - js-tokens "^4.0.0" - picocolors "^1.0.0" + "@babel/helper-module-imports" "^7.27.1" + "@babel/helper-validator-identifier" "^7.27.1" + "@babel/traverse" "^7.27.1" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.24.0", "@babel/parser@^7.24.5": - version "7.24.5" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.5.tgz#4a4d5ab4315579e5398a82dcf636ca80c3392790" - integrity sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg== +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.27.1", "@babel/helper-plugin-utils@^7.8.0": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz#ddb2f876534ff8013e6c2b299bf4d39b3c51d44c" + integrity sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw== + +"@babel/helper-string-parser@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz#54da796097ab19ce67ed9f88b47bb2ec49367687" + integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA== + +"@babel/helper-validator-identifier@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz#a7054dcc145a967dd4dc8fee845a57c1316c9df8" + integrity sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow== + +"@babel/helper-validator-option@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz#fa52f5b1e7db1ab049445b421c4471303897702f" + integrity sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg== + +"@babel/helpers@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.27.1.tgz#ffc27013038607cdba3288e692c3611c06a18aa4" + integrity sha512-FCvFTm0sWV8Fxhpp2McP5/W53GPllQ9QeQ7SiqGWjMf/LVG07lFa5+pgK05IRhVwtvafT22KF+ZSnM9I545CvQ== + dependencies: + "@babel/template" "^7.27.1" + "@babel/types" "^7.27.1" + +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.27.1", "@babel/parser@^7.27.2": + version "7.27.2" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.27.2.tgz#577518bedb17a2ce4212afd052e01f7df0941127" + integrity sha512-QYLs8299NA7WM/bZAdp+CviYYkVoYXlDW2rzliy3chxd1PQjej7JORuMJDJXJUb9g0TT+B99EwaVLKmX+sPXWw== + dependencies: + "@babel/types" "^7.27.1" "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" @@ -197,14 +138,28 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-class-properties@^7.8.3": +"@babel/plugin-syntax-class-properties@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-syntax-import-meta@^7.8.3": +"@babel/plugin-syntax-class-static-block@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" + integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-import-attributes@^7.24.7": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz#34c017d54496f9b11b61474e7ea3dfd5563ffe07" + integrity sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-syntax-import-meta@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== @@ -219,13 +174,13 @@ "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-jsx@^7.7.2": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.1.tgz#3f6ca04b8c841811dbc3c5c5f837934e0d626c10" - integrity sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA== + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz#2f9beb5eff30fa507c5532d107daac7b888fa34c" + integrity sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w== dependencies: - "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-syntax-logical-assignment-operators@^7.8.3": +"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== @@ -239,7 +194,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-numeric-separator@^7.8.3": +"@babel/plugin-syntax-numeric-separator@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== @@ -267,7 +222,14 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-top-level-await@^7.8.3": +"@babel/plugin-syntax-private-property-in-object@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" + integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-top-level-await@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== @@ -275,60 +237,60 @@ "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-typescript@^7.7.2": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.1.tgz#b3bcc51f396d15f3591683f90239de143c076844" - integrity sha512-Yhnmvy5HZEnHUty6i++gcfH1/l68AHnItFHnaCv6hn9dNh0hQvvQJsxpi4BMBFN5DLeHBuucT/0DgzXif/OyRw== + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz#5147d29066a793450f220c63fa3a9431b7e6dd18" + integrity sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ== dependencies: - "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-modules-commonjs@^7.23.3": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.1.tgz#e71ba1d0d69e049a22bf90b3867e263823d3f1b9" - integrity sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw== - dependencies: - "@babel/helper-module-transforms" "^7.23.3" - "@babel/helper-plugin-utils" "^7.24.0" - "@babel/helper-simple-access" "^7.22.5" - -"@babel/template@^7.22.15", "@babel/template@^7.24.0", "@babel/template@^7.3.3": - version "7.24.0" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.24.0.tgz#c6a524aa93a4a05d66aaf31654258fae69d87d50" - integrity sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA== - dependencies: - "@babel/code-frame" "^7.23.5" - "@babel/parser" "^7.24.0" - "@babel/types" "^7.24.0" - -"@babel/traverse@^7.24.5": - version "7.24.5" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.24.5.tgz#972aa0bc45f16983bf64aa1f877b2dd0eea7e6f8" - integrity sha512-7aaBLeDQ4zYcUFDUD41lJc1fG8+5IU9DaNSJAgal866FGvmD5EbWQgnEC6kO1gGLsX0esNkfnJSndbTXA3r7UA== - dependencies: - "@babel/code-frame" "^7.24.2" - "@babel/generator" "^7.24.5" - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-function-name" "^7.23.0" - "@babel/helper-hoist-variables" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.24.5" - "@babel/parser" "^7.24.5" - "@babel/types" "^7.24.5" + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz#8e44ed37c2787ecc23bdc367f49977476614e832" + integrity sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw== + dependencies: + "@babel/helper-module-transforms" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/template@^7.27.1", "@babel/template@^7.3.3": + version "7.27.2" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.27.2.tgz#fa78ceed3c4e7b63ebf6cb39e5852fca45f6809d" + integrity sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw== + dependencies: + "@babel/code-frame" "^7.27.1" + "@babel/parser" "^7.27.2" + "@babel/types" "^7.27.1" + +"@babel/traverse@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.27.1.tgz#4db772902b133bbddd1c4f7a7ee47761c1b9f291" + integrity sha512-ZCYtZciz1IWJB4U61UPu4KEaqyfj+r5T1Q5mqPo+IBpcG9kHv30Z0aD8LXPgC1trYa6rK0orRyAhqUgk4MjmEg== + dependencies: + "@babel/code-frame" "^7.27.1" + "@babel/generator" "^7.27.1" + "@babel/parser" "^7.27.1" + "@babel/template" "^7.27.1" + "@babel/types" "^7.27.1" debug "^4.3.1" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.24.0", "@babel/types@^7.24.5", "@babel/types@^7.3.3": - version "7.24.5" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.24.5.tgz#7661930afc638a5383eb0c4aee59b74f38db84d7" - integrity sha512-6mQNsaLeXTw0nxYUYu+NSa4Hx4BlF1x1x8/PMFbiR+GBSr+2DkECc69b8hgy2frEodNcvPffeH8YfWd3LI6jhQ== +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.27.1", "@babel/types@^7.3.3": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.27.1.tgz#9defc53c16fc899e46941fc6901a9eea1c9d8560" + integrity sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q== dependencies: - "@babel/helper-string-parser" "^7.24.1" - "@babel/helper-validator-identifier" "^7.24.5" - to-fast-properties "^2.0.0" + "@babel/helper-string-parser" "^7.27.1" + "@babel/helper-validator-identifier" "^7.27.1" "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@bufbuild/protobuf@2.2.3", "@bufbuild/protobuf@^2.2.3": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@bufbuild/protobuf/-/protobuf-2.2.3.tgz#9cd136f6b687e63e9b517b3a54211ece942897ee" + integrity sha512-tFQoXHJdkEOSwj5tRIZSPNUuXK3RaR7T1nUrPgbYX1pUbvqqaaZAsfo+NXBPsz5rZMSKVFrgK1WL8Q/MSLvprg== + "@cspotcode/source-map-consumer@0.8.0": version "0.8.0" resolved "https://registry.yarnpkg.com/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz#33bf4b7b39c178821606f669bbc447a6a629786b" @@ -342,16 +304,16 @@ "@cspotcode/source-map-consumer" "0.8.0" "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.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== + version "4.7.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz#607084630c6c033992a082de6e6fbc1a8b52175a" + integrity sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw== dependencies: - eslint-visitor-keys "^3.3.0" + eslint-visitor-keys "^3.4.3" "@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1": - version "4.10.0" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63" - integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA== + version "4.12.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.1.tgz#cfc6cffe39df390a3841cde2abccf92eaa7ae0e0" + integrity sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ== "@eslint/eslintrc@^2.1.2", "@eslint/eslintrc@^2.1.4": version "2.1.4" @@ -378,384 +340,218 @@ resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.55.0.tgz#b721d52060f369aa259cf97392403cb9ce892ec6" integrity sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA== -"@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz" - integrity sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA== - dependencies: - "@ethersproject/address" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/hash" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@ethersproject/abstract-provider@5.7.0", "@ethersproject/abstract-provider@^5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz" - integrity sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/networks" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - "@ethersproject/web" "^5.7.0" - -"@ethersproject/abstract-signer@5.7.0", "@ethersproject/abstract-signer@^5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz" - integrity sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ== - dependencies: - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - -"@ethersproject/address@5.7.0", "@ethersproject/address@^5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz" - integrity sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/rlp" "^5.7.0" - -"@ethersproject/base64@5.7.0", "@ethersproject/base64@^5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz" - integrity sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ== - dependencies: - "@ethersproject/bytes" "^5.7.0" - -"@ethersproject/basex@5.7.0", "@ethersproject/basex@^5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz" - integrity sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - -"@ethersproject/bignumber@5.7.0", "@ethersproject/bignumber@^5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz" - integrity sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" +"@ethereumjs/rlp@^5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@ethereumjs/rlp/-/rlp-5.0.2.tgz#c89bd82f2f3bec248ab2d517ae25f5bbc4aac842" + integrity sha512-DziebCdg4JpGlEqEdGgXmjqcFoJi+JGulUXwEjsZGAscAQ7MyD/7LE/GVCP29vEQxKc7AAwjT3A2ywHp2xfoCA== + +"@ethereumjs/util@^9.1.0": + version "9.1.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/util/-/util-9.1.0.tgz#75e3898a3116d21c135fa9e29886565609129bce" + integrity sha512-XBEKsYqLGXLah9PNJbgdkigthkG7TAGvlD/sH12beMXEyHDyigfcbdvHhmLyDWgDyOJn4QwiQUaF7yeuhnjdog== + dependencies: + "@ethereumjs/rlp" "^5.0.2" + ethereum-cryptography "^2.2.1" + +"@ethersproject/abi@^5.1.2": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.8.0.tgz#e79bb51940ac35fe6f3262d7fe2cdb25ad5f07d9" + integrity sha512-b9YS/43ObplgyV6SlyQsG53/vkSal0MNA1fskSC4mbnCMi8R+NkcH8K9FPYNESf6jUefBUniE4SOKms0E/KK1Q== + dependencies: + "@ethersproject/address" "^5.8.0" + "@ethersproject/bignumber" "^5.8.0" + "@ethersproject/bytes" "^5.8.0" + "@ethersproject/constants" "^5.8.0" + "@ethersproject/hash" "^5.8.0" + "@ethersproject/keccak256" "^5.8.0" + "@ethersproject/logger" "^5.8.0" + "@ethersproject/properties" "^5.8.0" + "@ethersproject/strings" "^5.8.0" + +"@ethersproject/abstract-provider@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.8.0.tgz#7581f9be601afa1d02b95d26b9d9840926a35b0c" + integrity sha512-wC9SFcmh4UK0oKuLJQItoQdzS/qZ51EJegK6EmAWlh+OptpQ/npECOR3QqECd8iGHC0RJb4WKbVdSfif4ammrg== + dependencies: + "@ethersproject/bignumber" "^5.8.0" + "@ethersproject/bytes" "^5.8.0" + "@ethersproject/logger" "^5.8.0" + "@ethersproject/networks" "^5.8.0" + "@ethersproject/properties" "^5.8.0" + "@ethersproject/transactions" "^5.8.0" + "@ethersproject/web" "^5.8.0" + +"@ethersproject/abstract-signer@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.8.0.tgz#8d7417e95e4094c1797a9762e6789c7356db0754" + integrity sha512-N0XhZTswXcmIZQdYtUnd79VJzvEwXQw6PK0dTl9VoYrEBxxCPXqS0Eod7q5TNKRxe1/5WUMuR0u0nqTF/avdCA== + dependencies: + "@ethersproject/abstract-provider" "^5.8.0" + "@ethersproject/bignumber" "^5.8.0" + "@ethersproject/bytes" "^5.8.0" + "@ethersproject/logger" "^5.8.0" + "@ethersproject/properties" "^5.8.0" + +"@ethersproject/address@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.8.0.tgz#3007a2c352eee566ad745dca1dbbebdb50a6a983" + integrity sha512-GhH/abcC46LJwshoN+uBNoKVFPxUuZm6dA257z0vZkKmU1+t8xTn8oK7B9qrj8W2rFRMch4gbJl6PmVxjxBEBA== + dependencies: + "@ethersproject/bignumber" "^5.8.0" + "@ethersproject/bytes" "^5.8.0" + "@ethersproject/keccak256" "^5.8.0" + "@ethersproject/logger" "^5.8.0" + "@ethersproject/rlp" "^5.8.0" + +"@ethersproject/base64@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.8.0.tgz#61c669c648f6e6aad002c228465d52ac93ee83eb" + integrity sha512-lN0oIwfkYj9LbPx4xEkie6rAMJtySbpOAFXSDVQaBnAzYfB4X2Qr+FXJGxMoc3Bxp2Sm8OwvzMrywxyw0gLjIQ== + dependencies: + "@ethersproject/bytes" "^5.8.0" + +"@ethersproject/bignumber@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.8.0.tgz#c381d178f9eeb370923d389284efa19f69efa5d7" + integrity sha512-ZyaT24bHaSeJon2tGPKIiHszWjD/54Sz8t57Toch475lCLljC6MgPmxk7Gtzz+ddNN5LuHea9qhAe0x3D+uYPA== + dependencies: + "@ethersproject/bytes" "^5.8.0" + "@ethersproject/logger" "^5.8.0" bn.js "^5.2.1" -"@ethersproject/bytes@5.7.0", "@ethersproject/bytes@^5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz" - integrity sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A== - dependencies: - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/constants@5.7.0", "@ethersproject/constants@^5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz" - integrity sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - -"@ethersproject/contracts@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz" - integrity sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg== - dependencies: - "@ethersproject/abi" "^5.7.0" - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - -"@ethersproject/hash@5.7.0", "@ethersproject/hash@^5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz" - integrity sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g== - dependencies: - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/base64" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@ethersproject/hdnode@5.7.0", "@ethersproject/hdnode@^5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz" - integrity sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg== - dependencies: - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/basex" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/pbkdf2" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/sha2" "^5.7.0" - "@ethersproject/signing-key" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - "@ethersproject/wordlists" "^5.7.0" - -"@ethersproject/json-wallets@5.7.0", "@ethersproject/json-wallets@^5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz" - integrity sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g== - dependencies: - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/hdnode" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/pbkdf2" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/random" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - aes-js "3.0.0" - scrypt-js "3.0.1" - -"@ethersproject/keccak256@5.7.0", "@ethersproject/keccak256@^5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz" - integrity sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg== - dependencies: - "@ethersproject/bytes" "^5.7.0" +"@ethersproject/bytes@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.8.0.tgz#9074820e1cac7507a34372cadeb035461463be34" + integrity sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A== + dependencies: + "@ethersproject/logger" "^5.8.0" + +"@ethersproject/constants@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.8.0.tgz#12f31c2f4317b113a4c19de94e50933648c90704" + integrity sha512-wigX4lrf5Vu+axVTIvNsuL6YrV4O5AXl5ubcURKMEME5TnWBouUh0CDTWxZ2GpnRn1kcCgE7l8O5+VbV9QTTcg== + dependencies: + "@ethersproject/bignumber" "^5.8.0" + +"@ethersproject/hash@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.8.0.tgz#b8893d4629b7f8462a90102572f8cd65a0192b4c" + integrity sha512-ac/lBcTbEWW/VGJij0CNSw/wPcw9bSRgCB0AIBz8CvED/jfvDoV9hsIIiWfvWmFEi8RcXtlNwp2jv6ozWOsooA== + dependencies: + "@ethersproject/abstract-signer" "^5.8.0" + "@ethersproject/address" "^5.8.0" + "@ethersproject/base64" "^5.8.0" + "@ethersproject/bignumber" "^5.8.0" + "@ethersproject/bytes" "^5.8.0" + "@ethersproject/keccak256" "^5.8.0" + "@ethersproject/logger" "^5.8.0" + "@ethersproject/properties" "^5.8.0" + "@ethersproject/strings" "^5.8.0" + +"@ethersproject/keccak256@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.8.0.tgz#d2123a379567faf2d75d2aaea074ffd4df349e6a" + integrity sha512-A1pkKLZSz8pDaQ1ftutZoaN46I6+jvuqugx5KYNeQOPqq+JZ0Txm7dlWesCHB5cndJSu5vP2VKptKf7cksERng== + dependencies: + "@ethersproject/bytes" "^5.8.0" js-sha3 "0.8.0" -"@ethersproject/logger@5.7.0", "@ethersproject/logger@^5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz" - integrity sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig== +"@ethersproject/logger@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.8.0.tgz#f0232968a4f87d29623a0481690a2732662713d6" + integrity sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA== -"@ethersproject/networks@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.0.tgz" - integrity sha512-MG6oHSQHd4ebvJrleEQQ4HhVu8Ichr0RDYEfHzsVAVjHNM+w36x9wp9r+hf1JstMXtseXDtkiVoARAG6M959AA== +"@ethersproject/networks@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.8.0.tgz#8b4517a3139380cba9fb00b63ffad0a979671fde" + integrity sha512-egPJh3aPVAzbHwq8DD7Po53J4OUSsA1MjQp8Vf/OZPav5rlmWUaFLiq8cvQiGK0Z5K6LYzm29+VA/p4RL1FzNg== dependencies: - "@ethersproject/logger" "^5.7.0" + "@ethersproject/logger" "^5.8.0" -"@ethersproject/networks@^5.7.0": - version "5.7.1" - resolved "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz" - integrity sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ== - dependencies: - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/pbkdf2@5.7.0", "@ethersproject/pbkdf2@^5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz" - integrity sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/sha2" "^5.7.0" - -"@ethersproject/properties@5.7.0", "@ethersproject/properties@^5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz" - integrity sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw== - dependencies: - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/providers@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.0.tgz" - integrity sha512-+TTrrINMzZ0aXtlwO/95uhAggKm4USLm1PbeCBR/3XZ7+Oey+3pMyddzZEyRhizHpy1HXV0FRWRMI1O3EGYibA== - dependencies: - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/base64" "^5.7.0" - "@ethersproject/basex" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/hash" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/networks" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/random" "^5.7.0" - "@ethersproject/rlp" "^5.7.0" - "@ethersproject/sha2" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - "@ethersproject/web" "^5.7.0" - bech32 "1.1.4" - ws "7.4.6" - -"@ethersproject/random@5.7.0", "@ethersproject/random@^5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz" - integrity sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/rlp@5.7.0", "@ethersproject/rlp@^5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz" - integrity sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/sha2@5.7.0", "@ethersproject/sha2@^5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz" - integrity sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - hash.js "1.1.7" +"@ethersproject/properties@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.8.0.tgz#405a8affb6311a49a91dabd96aeeae24f477020e" + integrity sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw== + dependencies: + "@ethersproject/logger" "^5.8.0" + +"@ethersproject/rlp@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.8.0.tgz#5a0d49f61bc53e051532a5179472779141451de5" + integrity sha512-LqZgAznqDbiEunaUvykH2JAoXTT9NV0Atqk8rQN9nx9SEgThA/WMx5DnW8a9FOufo//6FZOCHZ+XiClzgbqV9Q== + dependencies: + "@ethersproject/bytes" "^5.8.0" + "@ethersproject/logger" "^5.8.0" -"@ethersproject/signing-key@5.7.0", "@ethersproject/signing-key@^5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz" - integrity sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q== +"@ethersproject/signing-key@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.8.0.tgz#9797e02c717b68239c6349394ea85febf8893119" + integrity sha512-LrPW2ZxoigFi6U6aVkFN/fa9Yx/+4AtIUe4/HACTvKJdhm0eeb107EVCIQcrLZkxaSIgc/eCrX8Q1GtbH+9n3w== dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" + "@ethersproject/bytes" "^5.8.0" + "@ethersproject/logger" "^5.8.0" + "@ethersproject/properties" "^5.8.0" bn.js "^5.2.1" - elliptic "6.5.4" + elliptic "6.6.1" hash.js "1.1.7" -"@ethersproject/solidity@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz" - integrity sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/sha2" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@ethersproject/strings@5.7.0", "@ethersproject/strings@^5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz" - integrity sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/transactions@5.7.0", "@ethersproject/transactions@^5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz" - integrity sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ== - dependencies: - "@ethersproject/address" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/rlp" "^5.7.0" - "@ethersproject/signing-key" "^5.7.0" - -"@ethersproject/units@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz" - integrity sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/wallet@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz" - integrity sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA== - dependencies: - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/hash" "^5.7.0" - "@ethersproject/hdnode" "^5.7.0" - "@ethersproject/json-wallets" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/random" "^5.7.0" - "@ethersproject/signing-key" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - "@ethersproject/wordlists" "^5.7.0" - -"@ethersproject/web@5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.0.tgz" - integrity sha512-ApHcbbj+muRASVDSCl/tgxaH2LBkRMEYfLOLVa0COipx0+nlu0QKet7U2lEg0vdkh8XRSLf2nd1f1Uk9SrVSGA== - dependencies: - "@ethersproject/base64" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@ethersproject/web@^5.7.0": - version "5.7.1" - resolved "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz" - integrity sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w== - dependencies: - "@ethersproject/base64" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@ethersproject/wordlists@5.7.0", "@ethersproject/wordlists@^5.7.0": - version "5.7.0" - resolved "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz" - integrity sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/hash" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/strings" "^5.7.0" +"@ethersproject/strings@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.8.0.tgz#ad79fafbf0bd272d9765603215ac74fd7953908f" + integrity sha512-qWEAk0MAvl0LszjdfnZ2uC8xbR2wdv4cDabyHiBh3Cldq/T8dPH3V4BbBsAYJUeonwD+8afVXld274Ls+Y1xXg== + dependencies: + "@ethersproject/bytes" "^5.8.0" + "@ethersproject/constants" "^5.8.0" + "@ethersproject/logger" "^5.8.0" + +"@ethersproject/transactions@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.8.0.tgz#1e518822403abc99def5a043d1c6f6fe0007e46b" + integrity sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg== + dependencies: + "@ethersproject/address" "^5.8.0" + "@ethersproject/bignumber" "^5.8.0" + "@ethersproject/bytes" "^5.8.0" + "@ethersproject/constants" "^5.8.0" + "@ethersproject/keccak256" "^5.8.0" + "@ethersproject/logger" "^5.8.0" + "@ethersproject/properties" "^5.8.0" + "@ethersproject/rlp" "^5.8.0" + "@ethersproject/signing-key" "^5.8.0" + +"@ethersproject/web@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.8.0.tgz#3e54badc0013b7a801463a7008a87988efce8a37" + integrity sha512-j7+Ksi/9KfGviws6Qtf9Q7KCqRhpwrYKQPs+JBA/rKVFF/yaWLHJEH3zfVP2plVu+eys0d2DlFmhoQJayFewcw== + dependencies: + "@ethersproject/base64" "^5.8.0" + "@ethersproject/bytes" "^5.8.0" + "@ethersproject/logger" "^5.8.0" + "@ethersproject/properties" "^5.8.0" + "@ethersproject/strings" "^5.8.0" "@fastify/ajv-compiler@^1.0.0": version "1.1.0" - resolved "https://registry.npmjs.org/@fastify/ajv-compiler/-/ajv-compiler-1.1.0.tgz" + resolved "https://registry.yarnpkg.com/@fastify/ajv-compiler/-/ajv-compiler-1.1.0.tgz#5ce80b1fc8bebffc8c5ba428d5e392d0f9ed10a1" integrity sha512-gvCOUNpXsWrIQ3A4aXCLIdblL0tDq42BG/2Xw7oxbil9h11uow10ztS2GuFazNBfjbrsZ5nl+nPl5jDSjj5TSg== dependencies: ajv "^6.12.6" +"@fastify/busboy@^2.0.0": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.1.1.tgz#b9da6a878a371829a0502c9b6c1c143ef6663f4d" + integrity sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA== + "@gar/promisify@^1.1.3": version "1.1.3" - resolved "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz" + resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== -"@graphprotocol/common-ts@2.0.11": - version "2.0.11" - resolved "https://registry.yarnpkg.com/@graphprotocol/common-ts/-/common-ts-2.0.11.tgz#29f92e7a9666a6b8baccd15e51281d87658978c9" - integrity sha512-WtQGYMGVwaXDIli+OCAZUSqh8+ql9THzjztqvLGeSbAIPKxysvej9vua0voMguqEkI/RyEEMBajelodMzzZlEw== +"@graphprotocol/common-ts@3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@graphprotocol/common-ts/-/common-ts-3.0.1.tgz#c20428a5c2c7cf8f6631fea9fc304e203b0e7483" + integrity sha512-VtNFdTaZsS9vR/IX3aav7Dk6FUT+Lplmfp3d00ErjNf87kj2whT2LMG3tcZta/czcTi42Z9SOX95GsPJSxbM7Q== dependencies: - "@graphprotocol/contracts" "5.3.3" "@graphprotocol/pino-sentry-simple" "0.7.1" "@urql/core" "3.1.0" "@urql/exchange-execute" "2.1.0" @@ -763,7 +559,7 @@ bs58 "5.0.0" cors "2.8.5" cross-fetch "4.0.0" - ethers "5.7.0" + ethers "6.13.7" express "4.18.2" graphql "16.8.0" graphql-tag "2.12.6" @@ -777,17 +573,26 @@ prom-client "14.2.0" sequelize "6.33.0" -"@graphprotocol/contracts@5.3.3": - version "5.3.3" - resolved "https://registry.npmjs.org/@graphprotocol/contracts/-/contracts-5.3.3.tgz" - integrity sha512-fmFSKr+VDinWWotj2q/Ztn92PppcRrYXeO/62gLgkLos/DcYa7bGWKbcOWyMUw0vsUvXxk6QAtr5o/LG3yQ1WQ== +"@graphprotocol/dips-proto@0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@graphprotocol/dips-proto/-/dips-proto-0.3.0.tgz#97eccaabdf449479fb083865d4697e3c0725f870" + integrity sha512-zZ6mqG/OKe21PxOunnhWkz2qq5zZl+JD0n7PSFgVNq61J8lZs22Jal78utvOSsJd/E5vyNoSxELGCOyZmc4QJw== dependencies: - console-table-printer "^2.11.1" - ethers "^5.6.0" + "@bufbuild/protobuf" "^2.2.3" + +"@graphprotocol/horizon@0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@graphprotocol/horizon/-/horizon-0.4.1.tgz#b29f0944eeb9d4b50fc586e533904b9e51f18ade" + integrity sha512-YC/HVmWuCkfembwVQbPEY9NEDNsPsuHxnBMCThB1nAyai9I0Ad/nKnHZ+9baFmq5Sg1YwXxDG7Nc4SQJlgZD2g== + +"@graphprotocol/interfaces@^0.2.5": + version "0.2.5" + resolved "https://registry.yarnpkg.com/@graphprotocol/interfaces/-/interfaces-0.2.5.tgz#b628b198f4f2c6118d6acbf29f70c2de3ba61211" + integrity sha512-z2Worw4OzMs9aDup8MkkoNk/QmJFKhPIfQrYnbu0FKImyi72z1JVQXfaH8ypH3QO4/Lpc3PrK81cJFxqdWNExQ== "@graphprotocol/pino-sentry-simple@0.7.1": version "0.7.1" - resolved "https://registry.npmjs.org/@graphprotocol/pino-sentry-simple/-/pino-sentry-simple-0.7.1.tgz" + resolved "https://registry.yarnpkg.com/@graphprotocol/pino-sentry-simple/-/pino-sentry-simple-0.7.1.tgz#ac08b978bfa33178b9e809f53ae0983ff5f724d8" integrity sha512-iccKFdFBjarSp8/liXuK1EtGq8Vwn118tqymbOJBxblecRsi4rOebk63qnL+dK/a0IvxH6h2+RjjWDbRt7UsUA== dependencies: "@sentry/node" "^5.21.1" @@ -795,6 +600,42 @@ split2 "^3.1.1" through2 "^3.0.1" +"@graphprotocol/subgraph-service@0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@graphprotocol/subgraph-service/-/subgraph-service-0.4.1.tgz#31a76c10031aa118960a1fa0d7ba955cac123f32" + integrity sha512-vJA9lzlNQr4IRDPAbUiXM1ybizB4GzI0B1bndvB2X00ecTOWQQCiDl0W/qlApQ86+YXMjU2g90Db23ldqVOvyQ== + +"@graphprotocol/toolshed@0.6.5": + version "0.6.5" + resolved "https://registry.yarnpkg.com/@graphprotocol/toolshed/-/toolshed-0.6.5.tgz#42fd39d1a5b9a41002c81feaecfa574f9e2dbe46" + integrity sha512-yVyFX2rVYzgUUUcuyLCctItNXEQFeNYi739/kZupf3I/FHevaFpIvB4ZFn/Kg9SAi7556Vv3JfAPO6jkJ/xypg== + dependencies: + "@graphprotocol/interfaces" "^0.2.5" + "@nomicfoundation/hardhat-ethers" "3.0.8" + debug "^4.4.0" + ethers "6.13.7" + glob "^11.0.1" + hardhat "^2.22.16" + json5 "^2.2.3" + +"@grpc/grpc-js@^1.12.6": + version "1.12.6" + resolved "https://registry.yarnpkg.com/@grpc/grpc-js/-/grpc-js-1.12.6.tgz#a3586ffdfb6a1f5cd5b4866dec9074c4a1e65472" + integrity sha512-JXUj6PI0oqqzTGvKtzOkxtpsyPRNsrmhh41TtIz/zEB6J+AUiZZ0dxWzcMwO9Ns5rmSPuMdghlTbUuqIM48d3Q== + dependencies: + "@grpc/proto-loader" "^0.7.13" + "@js-sdsl/ordered-map" "^4.4.2" + +"@grpc/proto-loader@^0.7.13": + version "0.7.13" + resolved "https://registry.yarnpkg.com/@grpc/proto-loader/-/proto-loader-0.7.13.tgz#f6a44b2b7c9f7b609f5748c6eac2d420e37670cf" + integrity sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw== + dependencies: + lodash.camelcase "^4.3.0" + long "^5.0.0" + protobufjs "^7.2.5" + yargs "^17.7.2" + "@humanwhocodes/config-array@^0.11.11", "@humanwhocodes/config-array@^0.11.13": version "0.11.14" resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.14.tgz#d78e481a039f7566ecc9660b4ea7fe6b1fec442b" @@ -816,17 +657,17 @@ "@hutson/parse-repository-url@^3.0.0": version "3.0.2" - resolved "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz" + resolved "https://registry.yarnpkg.com/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz#98c23c950a3d9b6c8f0daed06da6c3af06981340" integrity sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q== "@iarna/toml@2.2.5": version "2.2.5" - resolved "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz" + resolved "https://registry.yarnpkg.com/@iarna/toml/-/toml-2.2.5.tgz#b32366c89b43c6f8cefbdefac778b9c828e3ba8c" integrity sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg== "@isaacs/cliui@^8.0.2": version "8.0.2" - resolved "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== dependencies: string-width "^5.1.2" @@ -838,7 +679,7 @@ "@isaacs/string-locale-compare@^1.1.0": version "1.1.0" - resolved "https://registry.npmjs.org/@isaacs/string-locale-compare/-/string-locale-compare-1.1.0.tgz" + resolved "https://registry.yarnpkg.com/@isaacs/string-locale-compare/-/string-locale-compare-1.1.0.tgz#291c227e93fd407a96ecd59879a35809120e432b" integrity sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ== "@istanbuljs/load-nyc-config@^1.0.0": @@ -1050,9 +891,9 @@ chalk "^4.0.0" "@jridgewell/gen-mapping@^0.3.5": - version "0.3.5" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" - integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg== + version "0.3.8" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz#4f0e06362e01362f823d348f1872b08f666d8142" + integrity sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA== dependencies: "@jridgewell/set-array" "^1.2.1" "@jridgewell/sourcemap-codec" "^1.4.10" @@ -1069,9 +910,9 @@ integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== "@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": - version "1.4.15" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" - integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + version "1.5.0" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" + integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== "@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": version "0.3.25" @@ -1081,9 +922,14 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" +"@js-sdsl/ordered-map@^4.4.2": + version "4.4.2" + resolved "https://registry.yarnpkg.com/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz#9299f82874bab9e4c7f9c48d865becbfe8d6907c" + integrity sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw== + "@lerna/add@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/add/-/add-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/add/-/add-6.1.0.tgz#0f09495c5e1af4c4f316344af34b6d1a91b15b19" integrity sha512-f2cAeS1mE/p7QvSRn5TCgdUXw6QVbu8PeRxaTOxTThhTdJIWdXZfY00QjAsU6jw1PdYXK1qGUSwWOPkdR16mBg== dependencies: "@lerna/bootstrap" "6.1.0" @@ -1099,7 +945,7 @@ "@lerna/bootstrap@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/bootstrap/-/bootstrap-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/bootstrap/-/bootstrap-6.1.0.tgz#81738f32cd431814c9943dfffe28752587d90830" integrity sha512-aDxKqgxexVj/Z0B1aPu7P1iPbPqhk1FPkl/iayCmPlkAh90pYEH0uVytGzi1hFB5iXEfG7Pa6azGQywUodx/1g== dependencies: "@lerna/command" "6.1.0" @@ -1127,7 +973,7 @@ "@lerna/changed@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/changed/-/changed-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/changed/-/changed-6.1.0.tgz#4fa480cbb0e7106ea9dad30d315e953975118d06" integrity sha512-p7C2tf1scmvoUC1Osck/XIKVKXAQ8m8neL8/rfgKSYsvUVjsOB1LbF5HH1VUZntE6S4OxkRxUQGkAHVf5xrGqw== dependencies: "@lerna/collect-updates" "6.1.0" @@ -1137,7 +983,7 @@ "@lerna/check-working-tree@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/check-working-tree/-/check-working-tree-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/check-working-tree/-/check-working-tree-6.1.0.tgz#b8970fd27a26449b12456d5d0ece60477aa54e15" integrity sha512-hSciDmRqsNPevMhAD+SYbnhjatdb7UUu9W8vTyGtUXkrq2xtRZU0vAOgqovV8meirRkbC41pZePYKqyQtF0y3w== dependencies: "@lerna/collect-uncommitted" "6.1.0" @@ -1146,7 +992,7 @@ "@lerna/child-process@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/child-process/-/child-process-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/child-process/-/child-process-6.1.0.tgz#6361f7945cd5b36e983f819de3cd91c315707302" integrity sha512-jhr3sCFeps6Y15SCrWEPvqE64i+QLOTSh+OzxlziCBf7ZEUu7sF0yA4n5bAqw8j43yCKhhjkf/ZLYxZe+pnl3Q== dependencies: chalk "^4.1.0" @@ -1155,7 +1001,7 @@ "@lerna/clean@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/clean/-/clean-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/clean/-/clean-6.1.0.tgz#1114fd90ad82438123726e2493d3550e73abebbc" integrity sha512-LRK2hiNUiBhPe5tmJiefOVpkaX2Yob0rp15IFNIbuteRWUJg0oERFQo62WvnxwElfzKSOhr8OGuEq/vN4bMrRA== dependencies: "@lerna/command" "6.1.0" @@ -1169,7 +1015,7 @@ "@lerna/cli@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/cli/-/cli-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/cli/-/cli-6.1.0.tgz#41214331fa4c1ea5f41125befdd81b009fe12640" integrity sha512-p4G/OSPIrHiNkEl8bXrQdFOh4ORAZp2+ljvbXmAxpdf2qmopaUdr+bZYtIAxd+Z42SxRnDNz9IEyR0kOsARRQQ== dependencies: "@lerna/global-options" "6.1.0" @@ -1179,7 +1025,7 @@ "@lerna/collect-uncommitted@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/collect-uncommitted/-/collect-uncommitted-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/collect-uncommitted/-/collect-uncommitted-6.1.0.tgz#b6ffd7adda24d73b70304210967d3518caa3529d" integrity sha512-VvWvqDZG+OiF4PwV4Ro695r3+8ty4w+11Bnq8tbsbu5gq8qZiam8Fkc/TQLuNNqP0SPi4qmMPaIzWvSze3SmDg== dependencies: "@lerna/child-process" "6.1.0" @@ -1188,7 +1034,7 @@ "@lerna/collect-updates@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/collect-updates/-/collect-updates-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/collect-updates/-/collect-updates-6.1.0.tgz#75fcc0733b5a9ac318a6484b890aa4061b7859c2" integrity sha512-dgH7kgstwCXFctylQ4cxuCmhwSIE6VJZfHdh2bOaLuncs6ATMErKWN/mVuFHuUWEqPDRyy5Ky40Cu9S40nUq5w== dependencies: "@lerna/child-process" "6.1.0" @@ -1199,7 +1045,7 @@ "@lerna/command@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/command/-/command-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/command/-/command-6.1.0.tgz#bcb12516f2c181822b3b5be46c18eadc9b61e885" integrity sha512-OnMqBDaEBY0C8v9CXIWFbGGKgsiUtZrnKVvQRbupMSZDKMpVGWIUd3X98Is9j9MAmk1ynhBMWE9Fwai5ML/mcA== dependencies: "@lerna/child-process" "6.1.0" @@ -1215,7 +1061,7 @@ "@lerna/conventional-commits@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/conventional-commits/-/conventional-commits-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/conventional-commits/-/conventional-commits-6.1.0.tgz#1157bb66d84d48880dc5c5026d743cedf0f47094" integrity sha512-Tipo3cVr8mNVca4btzrCIzct59ZJWERT8/ZCZ/TQWuI4huUJZs6LRofLtB0xsGJAVZ7Vz2WRXAeH4XYgeUxutQ== dependencies: "@lerna/validation-error" "6.1.0" @@ -1231,7 +1077,7 @@ "@lerna/create-symlink@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/create-symlink/-/create-symlink-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/create-symlink/-/create-symlink-6.1.0.tgz#d4260831f5d10abc0c70f0a8f39bea91db87e640" integrity sha512-ulMa5OUJEwEWBHSgCUNGxrcsJllq1YMYWqhufvIigmMPJ0Zv3TV1Hha5i2MsqLJAakxtW0pNuwdutkUTtUdgxQ== dependencies: cmd-shim "^5.0.0" @@ -1240,7 +1086,7 @@ "@lerna/create@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/create/-/create-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/create/-/create-6.1.0.tgz#cde219da46a7c5062c558366b4ffce2134f13845" integrity sha512-ZqlknXu0L29cV5mcfNgBLl+1RbKTWmNk8mj545zgXc7qQDgmrY+EVvrs8Cirey8C7bBpVkzP7Brzze0MSoB4rQ== dependencies: "@lerna/child-process" "6.1.0" @@ -1262,7 +1108,7 @@ "@lerna/describe-ref@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/describe-ref/-/describe-ref-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/describe-ref/-/describe-ref-6.1.0.tgz#60f0b8297b912aa5fe5e6ab8ef6c4127813681a7" integrity sha512-0RQAYnxBaMz1SrEb/rhfR+8VeZx5tvCNYKRee5oXIDZdQ2c6/EPyrKCp3WcqiuOWY50SfGOVfxJEcxpK8Y3FNA== dependencies: "@lerna/child-process" "6.1.0" @@ -1270,7 +1116,7 @@ "@lerna/diff@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/diff/-/diff-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/diff/-/diff-6.1.0.tgz#bfa9bc35894d88a33fa0a3a5787082dea45d8cb2" integrity sha512-GhP+jPDbcp9QcAMSAjFn4lzM8MKpLR1yt5jll+zUD831U1sL0I5t8HUosFroe5MoRNffEL/jHuI3SbC3jjqWjQ== dependencies: "@lerna/child-process" "6.1.0" @@ -1280,7 +1126,7 @@ "@lerna/exec@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/exec/-/exec-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/exec/-/exec-6.1.0.tgz#a2d165576471ff61e33c49952d40a5dbc36fc78f" integrity sha512-Ej6WlPHXLF6hZHsfD+J/dxeuTrnc0HIfIXR1DU//msHW5RNCdi9+I7StwreCAQH/dLEsdBjPg5chNmuj2JLQRg== dependencies: "@lerna/child-process" "6.1.0" @@ -1293,7 +1139,7 @@ "@lerna/filter-options@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/filter-options/-/filter-options-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/filter-options/-/filter-options-6.1.0.tgz#f4ee65d0db0273ce490ce6c72c9dbb1d23268ca6" integrity sha512-kPf92Z7uLsR6MUiXnyXWebaUWArLa15wLfpfTwIp5H3MNk1lTbuG7QnrxE7OxQj+ozFmBvXeV9fuwfLsYTfmOw== dependencies: "@lerna/collect-updates" "6.1.0" @@ -1303,7 +1149,7 @@ "@lerna/filter-packages@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/filter-packages/-/filter-packages-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/filter-packages/-/filter-packages-6.1.0.tgz#1ddac63a6ffdf5f058d206be5adfb39ad7aaf4f9" integrity sha512-zW2avsZHs/ITE/37AEMhegGVHjiD0rgNk9bguNDfz6zaPa90UaW6PWDH6Tf4ThPRlbkl2Go48N3bFYHYSJKbcw== dependencies: "@lerna/validation-error" "6.1.0" @@ -1312,14 +1158,14 @@ "@lerna/get-npm-exec-opts@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/get-npm-exec-opts/-/get-npm-exec-opts-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/get-npm-exec-opts/-/get-npm-exec-opts-6.1.0.tgz#22351e2ebc4adbef21ca4b86187278e15e4cb38a" integrity sha512-10Pdf+W0z7RT34o0SWlf+WVzz2/WbnTIJ1tQqXvXx6soj2L/xGLhOPvhJiKNtl4WlvUiO/zQ91yb83ESP4TZaA== dependencies: npmlog "^6.0.2" "@lerna/get-packed@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/get-packed/-/get-packed-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/get-packed/-/get-packed-6.1.0.tgz#b6d1c1dd1e068212e784b8dfc2e5fe64741ea8db" integrity sha512-lg0wPpV0wPekcD0mebJp619hMxsOgbZDOH5AkL/bCR217391eha0iPhQ0dU/G0Smd2vv6Cg443+J5QdI4LGRTg== dependencies: fs-extra "^9.1.0" @@ -1328,7 +1174,7 @@ "@lerna/github-client@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/github-client/-/github-client-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/github-client/-/github-client-6.1.0.tgz#cd33743e4529a0b822ae6716cb4b981e1d8ffe8f" integrity sha512-+/4PtDgsjt0VRRZtOCN2Piyu0asU/16gSZZy/opVb8dlT44lTrH/ZghrJLE4tSL8Nuv688kx0kSgbUG8BY54jQ== dependencies: "@lerna/child-process" "6.1.0" @@ -1339,7 +1185,7 @@ "@lerna/gitlab-client@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/gitlab-client/-/gitlab-client-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/gitlab-client/-/gitlab-client-6.1.0.tgz#bbcbf80d937e5980798ac1e0edd1f769101057d8" integrity sha512-fUI/ppXzxJafN9ceSl+FDgsYvu3iTsO6UW0WTD63pS32CfM+PiCryLQHzuc4RkyVW8WQH3aCR/GbaKCqbu52bw== dependencies: node-fetch "^2.6.1" @@ -1347,12 +1193,12 @@ "@lerna/global-options@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/global-options/-/global-options-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/global-options/-/global-options-6.1.0.tgz#268e1de924369102e47babd9288086764ec6f9e6" integrity sha512-1OyJ/N1XJh3ZAy8S20c6th9C4yBm/k3bRIdC+z0XxpDaHwfNt8mT9kUIDt6AIFCUvVKjSwnIsMHwhzXqBnwYSA== "@lerna/has-npm-version@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/has-npm-version/-/has-npm-version-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/has-npm-version/-/has-npm-version-6.1.0.tgz#a5d960213d1a7ca5374eb3c551a17b322b9a9e62" integrity sha512-up5PVuP6BmKQ5/UgH/t2c5B1q4HhjwW3/bqbNayX6V0qNz8OijnMYvEUbxFk8fOdeN41qVnhAk0Tb5kbdtYh2A== dependencies: "@lerna/child-process" "6.1.0" @@ -1360,7 +1206,7 @@ "@lerna/import@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/import/-/import-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/import/-/import-6.1.0.tgz#1c64281e3431c43c9cd140b66a6a51427afe7095" integrity sha512-xsBhiKLUavATR32dAFL+WFY0yuab0hsM1eztKtRKk4wy7lSyxRfA5EIUcNCsLXx2xaDOKoMncCTXgNcpeYuqcQ== dependencies: "@lerna/child-process" "6.1.0" @@ -1374,7 +1220,7 @@ "@lerna/info@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/info/-/info-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/info/-/info-6.1.0.tgz#a5d66a9c1f18398dc020a6f6073c399013081587" integrity sha512-CsrWdW/Wyb4kcvHSnrsm7KYWFvjUNItu+ryeyWBZJtWYQOv45jNmWix6j2L4/w1+mMlWMjsfLmBscg82UBrF5w== dependencies: "@lerna/command" "6.1.0" @@ -1383,7 +1229,7 @@ "@lerna/init@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/init/-/init-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/init/-/init-6.1.0.tgz#b178775693b9c38c0f3fe3300eeb574cf76e0297" integrity sha512-z8oUeVjn+FQYAtepAw6G47cGodLyBAyNoEjO3IsJjQLWE1yH3r83L2sjyD/EckgR3o2VTEzrKo4ArhxLp2mNmg== dependencies: "@lerna/child-process" "6.1.0" @@ -1395,7 +1241,7 @@ "@lerna/link@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/link/-/link-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/link/-/link-6.1.0.tgz#f6f0cfd0b02aecdeb304ce614e4e4e89fe0a3ad5" integrity sha512-7OD2lYNQHl6Kl1KYmplt8KoWjVHdiaqpYqwD38AwcB09YN58nGmo4aJgC12Fdx8DSNjkumgM0ROg/JOjMCTIzQ== dependencies: "@lerna/command" "6.1.0" @@ -1407,7 +1253,7 @@ "@lerna/list@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/list/-/list-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/list/-/list-6.1.0.tgz#a7625bceb5224c4bf1154e715c07ea29f9698bac" integrity sha512-7/g2hjizkvVnBGpVm+qC7lUFGhZ/0GIMUbGQwnE6yXDGm8yP9aEcNVkU4JGrDWW+uIklf9oodnMHaLXd/FJe6Q== dependencies: "@lerna/command" "6.1.0" @@ -1417,7 +1263,7 @@ "@lerna/listable@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/listable/-/listable-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/listable/-/listable-6.1.0.tgz#2510045fde7bc568b18172a5d24372a719bb5c4c" integrity sha512-3KZ9lQ9AtNfGNH/mYJYaMKCiF2EQvLLBGYkWHeIzIs6foegcZNXe0Cyv3LNXuo5WslMNr5RT4wIgy3BOoAxdtg== dependencies: "@lerna/query-graph" "6.1.0" @@ -1426,7 +1272,7 @@ "@lerna/log-packed@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/log-packed/-/log-packed-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/log-packed/-/log-packed-6.1.0.tgz#18ae946e8b7881f2fc5b973cc6682cc599b1759b" integrity sha512-Sq2HZJAcPuoNeEHeIutcPYQCyWBxLyVGvEhgsP3xTe6XkBGQCG8piCp9wX+sc2zT+idPdpI6qLqdh85yYIMMhA== dependencies: byte-size "^7.0.0" @@ -1436,7 +1282,7 @@ "@lerna/npm-conf@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/npm-conf/-/npm-conf-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/npm-conf/-/npm-conf-6.1.0.tgz#79697260c9d14ffb9d892927f37fcde75b89ec58" integrity sha512-+RD3mmJe9XSQj7Diibs0+UafAHPcrFCd29ODpDI+tzYl4MmYZblfrlL6mbSCiVYCZQneQ8Uku3P0r+DlbYBaFw== dependencies: config-chain "^1.1.12" @@ -1444,7 +1290,7 @@ "@lerna/npm-dist-tag@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/npm-dist-tag/-/npm-dist-tag-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/npm-dist-tag/-/npm-dist-tag-6.1.0.tgz#29f843aa628687a29dc3a9b905dd3002db7a3820" integrity sha512-1zo+Yww/lvWJWZnEXpke9dZSb5poDzhUM/pQNqAQYSlbZ96o18SuCR6TEi5isMPiw63Aq1MMzbUqttQfJ11EOA== dependencies: "@lerna/otplease" "6.1.0" @@ -1454,7 +1300,7 @@ "@lerna/npm-install@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/npm-install/-/npm-install-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/npm-install/-/npm-install-6.1.0.tgz#b75d1f152540a144bd6c81586a9f6010ed7f3046" integrity sha512-1SHmOHZA1YJuUctLQBRjA2+yMp+UNYdOBsFb3xUVT7MjWnd1Zl0toT3jxGu96RNErD9JKkk/cGo/Aq+DU3s9pg== dependencies: "@lerna/child-process" "6.1.0" @@ -1467,7 +1313,7 @@ "@lerna/npm-publish@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/npm-publish/-/npm-publish-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/npm-publish/-/npm-publish-6.1.0.tgz#8fe561e639e6a06380354271aeca7cbc39acf7dd" integrity sha512-N0LdR1ImZQw1r4cYaKtVbBhBPtj4Zu9NbvygzizEP5HuTfxZmE1Ans3w93Kks9VTXZXob8twNbXnzBwzTyEpEA== dependencies: "@lerna/otplease" "6.1.0" @@ -1481,7 +1327,7 @@ "@lerna/npm-run-script@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/npm-run-script/-/npm-run-script-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/npm-run-script/-/npm-run-script-6.1.0.tgz#bc5bd414ee9696168d88d8ce78f8e8b715967100" integrity sha512-7p13mvdxdY5+VqWvvtMsMDeyCRs0PrrTmSHRO+FKuLQuGhBvUo05vevcMEOQNDvEvl/tXPrOVbeGCiGubYTCLg== dependencies: "@lerna/child-process" "6.1.0" @@ -1490,21 +1336,21 @@ "@lerna/otplease@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/otplease/-/otplease-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/otplease/-/otplease-6.1.0.tgz#d25dbe2d867215b69f06de12ab4ff559d83d1d01" integrity sha512-gqSE6IbaD4IeNJePkaDLaFLoGp0Ceu35sn7z0AHAOoHiQGGorOmvM+h1Md3xZZRSXQmY9LyJVhG5eRa38SoG4g== dependencies: "@lerna/prompt" "6.1.0" "@lerna/output@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/output/-/output-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/output/-/output-6.1.0.tgz#d470146c6ee8ee063fd416081c1ca64fb132c4d8" integrity sha512-mgCIzLKIuroytXuxjTB689ERtpfgyNXW0rMv9WHOa6ufQc+QJPjh3L4jVsOA0l+/OxZyi97PUXotduNj+0cbnA== dependencies: npmlog "^6.0.2" "@lerna/pack-directory@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/pack-directory/-/pack-directory-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/pack-directory/-/pack-directory-6.1.0.tgz#3252ba7250d826b9922238c775abf5004e7580c4" integrity sha512-Xsixqm2nkGXs9hvq08ClbGpRlCYnlBV4TwSrLttIDL712RlyXoPe2maJzTUqo9OXBbOumFSahUEInCMT2OS05g== dependencies: "@lerna/get-packed" "6.1.0" @@ -1517,7 +1363,7 @@ "@lerna/package-graph@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/package-graph/-/package-graph-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/package-graph/-/package-graph-6.1.0.tgz#2373617605f48f53b5fa9d13188838b6c09022b0" integrity sha512-yGyxd/eHTDjkpnBbDhTV0hwKF+i01qZc+6/ko65wOsh8xtgqpQeE6mtdgbvsLKcuMcIQ7PDy1ntyIv9phg14gQ== dependencies: "@lerna/prerelease-id-from-version" "6.1.0" @@ -1528,7 +1374,7 @@ "@lerna/package@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/package/-/package-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/package/-/package-6.1.0.tgz#e9e33876c0509a86c1b676045b19fd3f7f1c77e2" integrity sha512-PyNFtdH2IcLasp/nyMDshmeXotriOSlhbeFIxhdl1XuGj5v1so3utMSOrJMO5kzZJQg5zyx8qQoxL+WH/hkrVQ== dependencies: load-json-file "^6.2.0" @@ -1537,14 +1383,14 @@ "@lerna/prerelease-id-from-version@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/prerelease-id-from-version/-/prerelease-id-from-version-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/prerelease-id-from-version/-/prerelease-id-from-version-6.1.0.tgz#4ee5beeef4e81d77001e94ec5613c140b6615616" integrity sha512-ngC4I6evvZztB6aOaSDEnhUgRTlqX3TyBXwWwLGTOXCPaCQBTPaLNokhmRdJ+ZVdZ4iHFbzEDSL07ubZrYUcmQ== dependencies: semver "^7.3.4" "@lerna/profiler@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/profiler/-/profiler-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/profiler/-/profiler-6.1.0.tgz#aae2249f1a39c79db72a548ce50bf32f86a0f3a5" integrity sha512-WFDQNpuqPqMJLg8llvrBHF8Ib5Asgp23lMeNUe89T62NUX6gkjVBTYdjsduxM0tZH6Pa0GAGaQcha97P6fxfdQ== dependencies: fs-extra "^9.1.0" @@ -1553,7 +1399,7 @@ "@lerna/project@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/project/-/project-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/project/-/project-6.1.0.tgz#605afe28fb15d8b8b890fafe0ec1da2700964056" integrity sha512-EOkfjjrTM16c3GUxGqcfYD2stV35p9mBEmkF41NPmyjfbzjol/irDF1r6Q7BsQSRsdClMJRCeZ168xdSxC2X0A== dependencies: "@lerna/package" "6.1.0" @@ -1572,7 +1418,7 @@ "@lerna/prompt@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/prompt/-/prompt-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/prompt/-/prompt-6.1.0.tgz#98e228220428d33620822f77e39f592ce29c776c" integrity sha512-981J/C53TZ2l2mFVlWJN7zynSzf5GEHKvKQa12Td9iknhASZOuwTAWb6eq46246Ant6W5tWwb0NSPu3I5qtcrA== dependencies: inquirer "^8.2.4" @@ -1580,7 +1426,7 @@ "@lerna/publish@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/publish/-/publish-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/publish/-/publish-6.1.0.tgz#9d62c327bc3541a0430951d726b39a2fb17b7925" integrity sha512-XtvuydtU0IptbAapLRgoN1AZj/WJR+e3UKnx9BQ1Dwc+Fpg2oqPxR/vi+6hxAsr95pdQ5CnWBdgS+dg2wEUJ7Q== dependencies: "@lerna/check-working-tree" "6.1.0" @@ -1614,21 +1460,21 @@ "@lerna/pulse-till-done@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/pulse-till-done/-/pulse-till-done-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/pulse-till-done/-/pulse-till-done-6.1.0.tgz#df0112a9a5b8547b53d18742ce21104eb360d731" integrity sha512-a2RVT82E4R9nVXtehzp2TQL6iXp0QfEM3bu8tBAR/SfI1A9ggZWQhuuUqtRyhhVCajdQDOo7rS0UG7R5JzK58w== dependencies: npmlog "^6.0.2" "@lerna/query-graph@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/query-graph/-/query-graph-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/query-graph/-/query-graph-6.1.0.tgz#e78c47c78d4691231fc379570e036bc2753cf6fa" integrity sha512-YkyCc+6aR7GlCOcZXEKPcl5o5L2v+0YUNs59JrfAS0mctFosZ/2tP7pkdu2SI4qXIi5D0PMNsh/0fRni56znsQ== dependencies: "@lerna/package-graph" "6.1.0" "@lerna/resolve-symlink@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/resolve-symlink/-/resolve-symlink-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/resolve-symlink/-/resolve-symlink-6.1.0.tgz#5a8686b99c838bc6e869930e5b5fd582607ebbe7" integrity sha512-8ILO+h5fsE0q8MSLfdL+MT1GEsNhAB1fDyMkSsYgLRCsssN/cViZbffpclZyT/EfAhpyKfBCHZ0CmT1ZGofU1A== dependencies: fs-extra "^9.1.0" @@ -1637,7 +1483,7 @@ "@lerna/rimraf-dir@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/rimraf-dir/-/rimraf-dir-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/rimraf-dir/-/rimraf-dir-6.1.0.tgz#75559585d5921563eff0e206bb9ec8ab0cc967c6" integrity sha512-J9YeGHkCCeAIzsnKURYeGECBexiIii6HA+Bbd+rAgoKPsNCOj6ql4+qJE8Jbd7fQEFNDPQeBCYvM7JcdMc0WSA== dependencies: "@lerna/child-process" "6.1.0" @@ -1647,7 +1493,7 @@ "@lerna/run-lifecycle@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/run-lifecycle/-/run-lifecycle-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/run-lifecycle/-/run-lifecycle-6.1.0.tgz#e1fa6cd300842ef1d688af77648fed05ec2d5345" integrity sha512-GbTdKxL+hWHEPgyBEKtqY9Nf+jFlt6YLtP5VjEVc5SdLkm+FeRquar9/YcZVUbzr3c+NJwWNgVjHuePfowdpUA== dependencies: "@lerna/npm-conf" "6.1.0" @@ -1657,7 +1503,7 @@ "@lerna/run-topologically@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/run-topologically/-/run-topologically-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/run-topologically/-/run-topologically-6.1.0.tgz#8f1a428b5d4b800bced178edabfa2262b328572f" integrity sha512-kpTaSBKdKjtf61be8Z1e7TIaMt/aksfxswQtpFxEuKDsPsdHfR8htSkADO4d/3SZFtmcAHIHNCQj9CaNj4O4Xw== dependencies: "@lerna/query-graph" "6.1.0" @@ -1665,7 +1511,7 @@ "@lerna/run@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/run/-/run-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/run/-/run-6.1.0.tgz#efaea1acc78cb7fc73b4906be70002e118628d64" integrity sha512-vlEEKPcTloiob6EK7gxrjEdB6fQQ/LNfWhSJCGxJlvNVbrMpoWIu0Kpp20b0nE+lzX7rRJ4seWr7Wdo/Fjub4Q== dependencies: "@lerna/command" "6.1.0" @@ -1681,7 +1527,7 @@ "@lerna/symlink-binary@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/symlink-binary/-/symlink-binary-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/symlink-binary/-/symlink-binary-6.1.0.tgz#7d476499b86ae5fcb853c510603cff9a27acf105" integrity sha512-DaiRNZk/dvomNxgEaTW145PyL7vIGP7rvnfXV2FO+rjX8UUSNUOjmVmHlYfs64gV9Eqx/dLfQClIbKcwYMD83A== dependencies: "@lerna/create-symlink" "6.1.0" @@ -1691,7 +1537,7 @@ "@lerna/symlink-dependencies@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/symlink-dependencies/-/symlink-dependencies-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/symlink-dependencies/-/symlink-dependencies-6.1.0.tgz#f44d33e043fed21a366c4ced2cbde8fa8be0c5fc" integrity sha512-hrTvtY1Ek+fLA4JjXsKsvwPjuJD0rwB/+K4WY57t00owj//BpCsJ37w3kkkS7f/PcW/5uRjCuHcY67LOEwsRxw== dependencies: "@lerna/create-symlink" "6.1.0" @@ -1703,7 +1549,7 @@ "@lerna/temp-write@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/temp-write/-/temp-write-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/temp-write/-/temp-write-6.1.0.tgz#a5d532090dd7b2d4f8965fbb475376aae06b9242" integrity sha512-ZcQl88H9HbQ/TeWUOVt+vDYwptm7kwprGvj9KkZXr9S5Bn6SiKRQOeydCCfCrQT+9Q3dm7QZXV6rWzLsACcAlQ== dependencies: graceful-fs "^4.1.15" @@ -1714,19 +1560,19 @@ "@lerna/timer@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/timer/-/timer-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/timer/-/timer-6.1.0.tgz#245b02c05b2dec6d2aed2da8a0962cf0343d83d5" integrity sha512-du+NQ9q7uO4d2nVU4AD2DSPuAZqUapA/bZKuVpFVxvY9Qhzb8dQKLsFISe4A9TjyoNAk8ZeWK0aBc/6N+Qer9A== "@lerna/validation-error@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/validation-error/-/validation-error-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/validation-error/-/validation-error-6.1.0.tgz#03bd46f6219b6db7c4420528d5aaf047f92693e3" integrity sha512-q0c3XCi5OpyTr8AcfbisS6e3svZaJF/riCvBDqRMaQUT4A8QOPzB4fVF3/+J2u54nidBuTlIk0JZu9aOdWTUkQ== dependencies: npmlog "^6.0.2" "@lerna/version@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/version/-/version-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/version/-/version-6.1.0.tgz#44d8649e978df9d6a14d97c9d7631a7dcd4a9cbf" integrity sha512-RUxVFdzHt0739lRNMrAbo6HWcFrcyG7atM1pn+Eo61fUoA5R/9N4bCk4m9xUGkJ/mOcROjuwAGe+wT1uOs58Bg== dependencies: "@lerna/check-working-tree" "6.1.0" @@ -1759,15 +1605,66 @@ "@lerna/write-log-file@6.1.0": version "6.1.0" - resolved "https://registry.npmjs.org/@lerna/write-log-file/-/write-log-file-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@lerna/write-log-file/-/write-log-file-6.1.0.tgz#b811cffd2ea2b3be6239a756c64dac9a3795707a" integrity sha512-09omu2w4NCt8mJH/X9ZMuToQQ3xu/KpC7EU4yDl2Qy8nxKf8HiG8Oe+YYNprngmkdsq60F5eUZvoiFDZ5JeGIg== dependencies: npmlog "^6.0.2" write-file-atomic "^4.0.1" +"@noble/curves@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.2.0.tgz#92d7e12e4e49b23105a2555c6984d41733d65c35" + integrity sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw== + dependencies: + "@noble/hashes" "1.3.2" + +"@noble/curves@1.4.2", "@noble/curves@~1.4.0": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.4.2.tgz#40309198c76ed71bc6dbf7ba24e81ceb4d0d1fe9" + integrity sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw== + dependencies: + "@noble/hashes" "1.4.0" + +"@noble/curves@~1.8.1": + version "1.8.2" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.8.2.tgz#8f24c037795e22b90ae29e222a856294c1d9ffc7" + integrity sha512-vnI7V6lFNe0tLAuJMu+2sX+FcL14TaCWy1qiczg1VwRmPrpQCdq5ESXQMqUc2tluRNf6irBXrWbl1mGN8uaU/g== + dependencies: + "@noble/hashes" "1.7.2" + +"@noble/hashes@1.2.0", "@noble/hashes@~1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.2.0.tgz#a3150eeb09cc7ab207ebf6d7b9ad311a9bdbed12" + integrity sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ== + +"@noble/hashes@1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" + integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== + +"@noble/hashes@1.4.0", "@noble/hashes@~1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.4.0.tgz#45814aa329f30e4fe0ba49426f49dfccdd066426" + integrity sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg== + +"@noble/hashes@1.7.2", "@noble/hashes@~1.7.1": + version "1.7.2" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.7.2.tgz#d53c65a21658fb02f3303e7ee3ba89d6754c64b4" + integrity sha512-biZ0NUSxyjLLqo6KxEJ1b+C2NAx0wtDoFvCaXHGgUkeHzf3Xc1xKumFKREuT7f7DARNZ/slvYUwFG6B0f2b6hQ== + +"@noble/secp256k1@1.7.1": + version "1.7.1" + resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c" + integrity sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw== + +"@noble/secp256k1@~1.7.0": + version "1.7.2" + resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.2.tgz#c2c3343e2dce80e15a914d7442147507f8a98e7f" + integrity sha512-/qzwYl5eFLH8OWIecQWM31qld2g1NfjgylK+TNhqtaUKP37Nm+Y+z30Fjhw0Ct8p9yCQEm2N3W/AckdIb3SMcQ== + "@nodelib/fs.scandir@2.1.5": version "2.1.5" - resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" + 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" @@ -1775,20 +1672,124 @@ "@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": version "2.0.5" - resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" + 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", "@nodelib/fs.walk@^1.2.8": version "1.2.8" - resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" + 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" +"@nomicfoundation/edr-darwin-arm64@0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.11.0.tgz#fa791451c5ce2acf6634143bca9fe8f1b5c66603" + integrity sha512-aYTVdcSs27XG7ayTzvZ4Yn9z/ABSaUwicrtrYK2NR8IH0ik4N4bWzo/qH8rax6rewVLbHUkGyGYnsy5ZN4iiMw== + +"@nomicfoundation/edr-darwin-x64@0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.11.0.tgz#b1aaf0bfb331f6d136a92cbe31f184e2209e7a4f" + integrity sha512-RxX7UYgvJrfcyT/uHUn44Nsy1XaoW+Q1khKMdHKxeW7BrgIi+Lz+siz3bX5vhSoAnKilDPhIVLrnC8zxQhjR2A== + +"@nomicfoundation/edr-linux-arm64-gnu@0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.11.0.tgz#fef6763c5d42bb68b4fc95df45c4745a0e31df93" + integrity sha512-J0j+rs0s11FuSipt/ymqrFmpJ7c0FSz1/+FohCIlUXDxFv//+1R/8lkGPjEYFmy8DPpk/iO8mcpqHTGckREbqA== + +"@nomicfoundation/edr-linux-arm64-musl@0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.11.0.tgz#ef89d5d2aefc1f8d4f7c699c59b8897a645d33eb" + integrity sha512-4r32zkGMN7WT/CMEuW0VjbuEdIeCskHNDMW4SSgQSJOE/N9L1KSLJCSsAbPD3aYE+e4WRDTyOwmuLjeUTcLZKQ== + +"@nomicfoundation/edr-linux-x64-gnu@0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.11.0.tgz#97432126110aa805b761d4743ab158698cae6d66" + integrity sha512-SmdncQHLYtVNWLIMyGaY6LpAfamzTDe3fxjkirmJv3CWR5tcEyC6LMui/GsIVnJzXeNJBXAzwl8hTUAxHTM6kQ== + +"@nomicfoundation/edr-linux-x64-musl@0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.11.0.tgz#7605fddbada22dfdd14b15f4ac562014d9c82332" + integrity sha512-w6hUqpn/trwiH6SRuRGysj37LsQVCX5XDCA3Xi81sbOaLhbHrNvK9TXWyZmcuzbdTKQQW6VNywcSxDdOiChcJg== + +"@nomicfoundation/edr-win32-x64-msvc@0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.11.0.tgz#6766175f3ec47bfbda0429ca00fed4ae5632a3c4" + integrity sha512-BLmULjRKoH9BsX+c4Na2ypV7NGeJ+M6Zpqj/faPOwleVscDdSr/IhriyPaXCe8dyfwbge7lWsbekiADtPSnB2Q== + +"@nomicfoundation/edr@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr/-/edr-0.11.0.tgz#d8b0ba4dfd7d93b9c54762e72eb9cd4e8244ce46" + integrity sha512-36WERf8ldvyHR6UAbcYsa+vpbW7tCrJGBwF4gXSsb8+STj1n66Hz85Y/O7B9+8AauX3PhglvV5dKl91tk43mWw== + dependencies: + "@nomicfoundation/edr-darwin-arm64" "0.11.0" + "@nomicfoundation/edr-darwin-x64" "0.11.0" + "@nomicfoundation/edr-linux-arm64-gnu" "0.11.0" + "@nomicfoundation/edr-linux-arm64-musl" "0.11.0" + "@nomicfoundation/edr-linux-x64-gnu" "0.11.0" + "@nomicfoundation/edr-linux-x64-musl" "0.11.0" + "@nomicfoundation/edr-win32-x64-msvc" "0.11.0" + +"@nomicfoundation/hardhat-ethers@3.0.8": + version "3.0.8" + resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-3.0.8.tgz#af078f566373abeb77e11cbe69fe3dd47f8bfc27" + integrity sha512-zhOZ4hdRORls31DTOqg+GmEZM0ujly8GGIuRY7t7szEk2zW/arY1qDug/py8AEktT00v5K+b6RvbVog+va51IA== + dependencies: + debug "^4.1.1" + lodash.isequal "^4.5.0" + +"@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.2.tgz#3a9c3b20d51360b20affb8f753e756d553d49557" + integrity sha512-JaqcWPDZENCvm++lFFGjrDd8mxtf+CtLd2MiXvMNTBD33dContTZ9TWETwNFwg7JTJT5Q9HEecH7FA+HTSsIUw== + +"@nomicfoundation/solidity-analyzer-darwin-x64@0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.2.tgz#74dcfabeb4ca373d95bd0d13692f44fcef133c28" + integrity sha512-fZNmVztrSXC03e9RONBT+CiksSeYcxI1wlzqyr0L7hsQlK1fzV+f04g2JtQ1c/Fe74ZwdV6aQBdd6Uwl1052sw== + +"@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.2.tgz#4af5849a89e5a8f511acc04f28eb5d4460ba2b6a" + integrity sha512-3d54oc+9ZVBuB6nbp8wHylk4xh0N0Gc+bk+/uJae+rUgbOBwQSfuGIbAZt1wBXs5REkSmynEGcqx6DutoK0tPA== + +"@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.2.tgz#54036808a9a327b2ff84446c130a6687ee702a8e" + integrity sha512-iDJfR2qf55vgsg7BtJa7iPiFAsYf2d0Tv/0B+vhtnI16+wfQeTbP7teookbGvAo0eJo7aLLm0xfS/GTkvHIucA== + +"@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.2.tgz#466cda0d6e43691986c944b909fc6dbb8cfc594e" + integrity sha512-9dlHMAt5/2cpWyuJ9fQNOUXFB/vgSFORg1jpjX1Mh9hJ/MfZXlDdHQ+DpFCs32Zk5pxRBb07yGvSHk9/fezL+g== + +"@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.2.tgz#2b35826987a6e94444140ac92310baa088ee7f94" + integrity sha512-GzzVeeJob3lfrSlDKQw2bRJ8rBf6mEYaWY+gW0JnTDHINA0s2gPR4km5RLIj1xeZZOYz4zRw+AEeYgLRqB2NXg== + +"@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.2.tgz#e6363d13b8709ca66f330562337dbc01ce8bbbd9" + integrity sha512-Fdjli4DCcFHb4Zgsz0uEJXZ2K7VEO+w5KVv7HmT7WO10iODdU9csC2az4jrhEsRtiR9Gfd74FlG0NYlw1BMdyA== + +"@nomicfoundation/solidity-analyzer@^0.1.0": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.2.tgz#8bcea7d300157bf3a770a851d9f5c5e2db34ac55" + integrity sha512-q4n32/FNKIhQ3zQGGw5CvPF6GTvDCpYwIf7bEY/dZTZbgfDsHyjJwURxUJf3VQuuJj+fDIFl4+KkBVbw4Ef6jA== + optionalDependencies: + "@nomicfoundation/solidity-analyzer-darwin-arm64" "0.1.2" + "@nomicfoundation/solidity-analyzer-darwin-x64" "0.1.2" + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu" "0.1.2" + "@nomicfoundation/solidity-analyzer-linux-arm64-musl" "0.1.2" + "@nomicfoundation/solidity-analyzer-linux-x64-gnu" "0.1.2" + "@nomicfoundation/solidity-analyzer-linux-x64-musl" "0.1.2" + "@nomicfoundation/solidity-analyzer-win32-x64-msvc" "0.1.2" + "@npmcli/arborist@5.3.0": version "5.3.0" - resolved "https://registry.npmjs.org/@npmcli/arborist/-/arborist-5.3.0.tgz" + resolved "https://registry.yarnpkg.com/@npmcli/arborist/-/arborist-5.3.0.tgz#321d9424677bfc08569e98a5ac445ee781f32053" integrity sha512-+rZ9zgL1lnbl8Xbb1NQdMjveOMwj4lIYfcDtyJHHi5x4X8jtR6m8SXooJMZy5vmFVZ8w7A2Bnd/oX9eTuU8w5A== dependencies: "@isaacs/string-locale-compare" "^1.1.0" @@ -1828,22 +1829,15 @@ "@npmcli/fs@^2.1.0": version "2.1.2" - resolved "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz" + resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-2.1.2.tgz#a9e2541a4a2fec2e69c29b35e6060973da79b865" integrity sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ== dependencies: "@gar/promisify" "^1.1.3" semver "^7.3.5" -"@npmcli/fs@^3.1.0": - version "3.1.0" - resolved "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.0.tgz" - integrity sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w== - dependencies: - semver "^7.3.5" - "@npmcli/git@^3.0.0": version "3.0.2" - resolved "https://registry.npmjs.org/@npmcli/git/-/git-3.0.2.tgz" + resolved "https://registry.yarnpkg.com/@npmcli/git/-/git-3.0.2.tgz#5c5de6b4d70474cf2d09af149ce42e4e1dacb931" integrity sha512-CAcd08y3DWBJqJDpfuVL0uijlq5oaXaOJEKHKc4wqrjd00gkvTZB+nFuLn+doOOKddaQS9JfqtNoFCO2LCvA3w== dependencies: "@npmcli/promise-spawn" "^3.0.0" @@ -1858,7 +1852,7 @@ "@npmcli/installed-package-contents@^1.0.7": version "1.0.7" - resolved "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-1.0.7.tgz" + resolved "https://registry.yarnpkg.com/@npmcli/installed-package-contents/-/installed-package-contents-1.0.7.tgz#ab7408c6147911b970a8abe261ce512232a3f4fa" integrity sha512-9rufe0wnJusCQoLpV9ZPKIVP55itrM5BxOXs10DmdbRfgWtHy1LDyskbwRnBghuB0PrF7pNPOqREVtpz4HqzKw== dependencies: npm-bundled "^1.1.1" @@ -1866,7 +1860,7 @@ "@npmcli/map-workspaces@^2.0.3": version "2.0.4" - resolved "https://registry.npmjs.org/@npmcli/map-workspaces/-/map-workspaces-2.0.4.tgz" + resolved "https://registry.yarnpkg.com/@npmcli/map-workspaces/-/map-workspaces-2.0.4.tgz#9e5e8ab655215a262aefabf139782b894e0504fc" integrity sha512-bMo0aAfwhVwqoVM5UzX1DJnlvVvzDCHae821jv48L1EsrYwfOZChlqWYXEtto/+BkBXetPbEWgau++/brh4oVg== dependencies: "@npmcli/name-from-folder" "^1.0.1" @@ -1876,7 +1870,7 @@ "@npmcli/metavuln-calculator@^3.0.1": version "3.1.1" - resolved "https://registry.npmjs.org/@npmcli/metavuln-calculator/-/metavuln-calculator-3.1.1.tgz" + resolved "https://registry.yarnpkg.com/@npmcli/metavuln-calculator/-/metavuln-calculator-3.1.1.tgz#9359bd72b400f8353f6a28a25c8457b562602622" integrity sha512-n69ygIaqAedecLeVH3KnO39M6ZHiJ2dEv5A7DGvcqCB8q17BGUgW8QaanIkbWUo2aYGZqJaOORTLAlIvKjNDKA== dependencies: cacache "^16.0.0" @@ -1886,7 +1880,7 @@ "@npmcli/move-file@^2.0.0": version "2.0.1" - resolved "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-2.0.1.tgz#26f6bdc379d87f75e55739bab89db525b06100e4" integrity sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ== dependencies: mkdirp "^1.0.4" @@ -1894,31 +1888,31 @@ "@npmcli/name-from-folder@^1.0.1": version "1.0.1" - resolved "https://registry.npmjs.org/@npmcli/name-from-folder/-/name-from-folder-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/@npmcli/name-from-folder/-/name-from-folder-1.0.1.tgz#77ecd0a4fcb772ba6fe927e2e2e155fbec2e6b1a" integrity sha512-qq3oEfcLFwNfEYOQ8HLimRGKlD8WSeGEdtUa7hmzpR8Sa7haL1KVQrvgO6wqMjhWFFVjgtrh1gIxDz+P8sjUaA== "@npmcli/node-gyp@^2.0.0": version "2.0.0" - resolved "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/@npmcli/node-gyp/-/node-gyp-2.0.0.tgz#8c20e53e34e9078d18815c1d2dda6f2420d75e35" integrity sha512-doNI35wIe3bBaEgrlPfdJPaCpUR89pJWep4Hq3aRdh6gKazIVWfs0jHttvSSoq47ZXgC7h73kDsUl8AoIQUB+A== "@npmcli/package-json@^2.0.0": version "2.0.0" - resolved "https://registry.npmjs.org/@npmcli/package-json/-/package-json-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/@npmcli/package-json/-/package-json-2.0.0.tgz#3bbcf4677e21055adbe673d9f08c9f9cde942e4a" integrity sha512-42jnZ6yl16GzjWSH7vtrmWyJDGVa/LXPdpN2rcUWolFjc9ON2N3uz0qdBbQACfmhuJZ2lbKYtmK5qx68ZPLHMA== dependencies: json-parse-even-better-errors "^2.3.1" "@npmcli/promise-spawn@^3.0.0": version "3.0.0" - resolved "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/@npmcli/promise-spawn/-/promise-spawn-3.0.0.tgz#53283b5f18f855c6925f23c24e67c911501ef573" integrity sha512-s9SgS+p3a9Eohe68cSI3fi+hpcZUmXq5P7w0kMlAsWVtR7XbK3ptkZqKT2cK1zLDObJ3sR+8P59sJE0w/KTL1g== dependencies: infer-owner "^1.0.4" "@npmcli/run-script@^4.1.0", "@npmcli/run-script@^4.1.3", "@npmcli/run-script@^4.1.7": version "4.2.1" - resolved "https://registry.npmjs.org/@npmcli/run-script/-/run-script-4.2.1.tgz" + resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-4.2.1.tgz#c07c5c71bc1c70a5f2a06b0d4da976641609b946" integrity sha512-7dqywvVudPSrRCW5nTHpHgeWnbBtz8cFkOuKrecm6ih+oO9ciydhWt6OF7HlqupRRmB8Q/gECVdB9LMfToJbRg== dependencies: "@npmcli/node-gyp" "^2.0.0" @@ -1929,14 +1923,14 @@ "@nrwl/cli@15.9.7": version "15.9.7" - resolved "https://registry.npmjs.org/@nrwl/cli/-/cli-15.9.7.tgz" + resolved "https://registry.yarnpkg.com/@nrwl/cli/-/cli-15.9.7.tgz#1db113f5cb1cfe63213097be1ece041eef33da1f" integrity sha512-1jtHBDuJzA57My5nLzYiM372mJW0NY6rFKxlWt5a0RLsAZdPTHsd8lE3Gs9XinGC1jhXbruWmhhnKyYtZvX/zA== dependencies: nx "15.9.7" "@nrwl/devkit@>=14.8.6 < 16": version "15.9.7" - resolved "https://registry.npmjs.org/@nrwl/devkit/-/devkit-15.9.7.tgz" + resolved "https://registry.yarnpkg.com/@nrwl/devkit/-/devkit-15.9.7.tgz#14d19ec82ff4209c12147a97f1cdea05d8f6c087" integrity sha512-Sb7Am2TMT8AVq8e+vxOlk3AtOA2M0qCmhBzoM1OJbdHaPKc0g0UgSnWRml1kPGg5qfPk72tWclLoZJ5/ut0vTg== dependencies: ejs "^3.1.7" @@ -1947,71 +1941,71 @@ "@nrwl/nx-darwin-arm64@15.9.7": version "15.9.7" - resolved "https://registry.npmjs.org/@nrwl/nx-darwin-arm64/-/nx-darwin-arm64-15.9.7.tgz#a2cb7390c782b8acf3bb8806a3002620226a933d" + resolved "https://registry.yarnpkg.com/@nrwl/nx-darwin-arm64/-/nx-darwin-arm64-15.9.7.tgz#a2cb7390c782b8acf3bb8806a3002620226a933d" integrity sha512-aBUgnhlkrgC0vu0fK6eb9Vob7eFnkuknrK+YzTjmLrrZwj7FGNAeyGXSlyo1dVokIzjVKjJg2saZZ0WQbfuCJw== "@nrwl/nx-darwin-x64@15.9.7": version "15.9.7" - resolved "https://registry.npmjs.org/@nrwl/nx-darwin-x64/-/nx-darwin-x64-15.9.7.tgz" + resolved "https://registry.yarnpkg.com/@nrwl/nx-darwin-x64/-/nx-darwin-x64-15.9.7.tgz#af0437e726aeb97eb660646bfd9a7da5ba7a0a6f" integrity sha512-L+elVa34jhGf1cmn38Z0sotQatmLovxoASCIw5r1CBZZeJ5Tg7Y9nOwjRiDixZxNN56hPKXm6xl9EKlVHVeKlg== "@nrwl/nx-linux-arm-gnueabihf@15.9.7": version "15.9.7" - resolved "https://registry.npmjs.org/@nrwl/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-15.9.7.tgz#e29f4d31afa903bfb4d0fd7421e19be1086eae87" + resolved "https://registry.yarnpkg.com/@nrwl/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-15.9.7.tgz#e29f4d31afa903bfb4d0fd7421e19be1086eae87" integrity sha512-pqmfqqEUGFu6PmmHKyXyUw1Al0Ki8PSaR0+ndgCAb1qrekVDGDfznJfaqxN0JSLeolPD6+PFtLyXNr9ZyPFlFg== "@nrwl/nx-linux-arm64-gnu@15.9.7": version "15.9.7" - resolved "https://registry.npmjs.org/@nrwl/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-15.9.7.tgz#eb2880a24d3268dd93583d21a6a0b9ff96bb23b4" + resolved "https://registry.yarnpkg.com/@nrwl/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-15.9.7.tgz#eb2880a24d3268dd93583d21a6a0b9ff96bb23b4" integrity sha512-NYOa/eRrqmM+In5g3M0rrPVIS9Z+q6fvwXJYf/KrjOHqqan/KL+2TOfroA30UhcBrwghZvib7O++7gZ2hzwOnA== "@nrwl/nx-linux-arm64-musl@15.9.7": version "15.9.7" - resolved "https://registry.npmjs.org/@nrwl/nx-linux-arm64-musl/-/nx-linux-arm64-musl-15.9.7.tgz#5d04913c4672a96cefa78491824620d8a8bcfd7f" + resolved "https://registry.yarnpkg.com/@nrwl/nx-linux-arm64-musl/-/nx-linux-arm64-musl-15.9.7.tgz#5d04913c4672a96cefa78491824620d8a8bcfd7f" integrity sha512-zyStqjEcmbvLbejdTOrLUSEdhnxNtdQXlmOuymznCzYUEGRv+4f7OAepD3yRoR0a/57SSORZmmGQB7XHZoYZJA== "@nrwl/nx-linux-x64-gnu@15.9.7": version "15.9.7" - resolved "https://registry.npmjs.org/@nrwl/nx-linux-x64-gnu/-/nx-linux-x64-gnu-15.9.7.tgz#cf7f61fd87f35a793e6824952a6eb12242fe43fd" + resolved "https://registry.yarnpkg.com/@nrwl/nx-linux-x64-gnu/-/nx-linux-x64-gnu-15.9.7.tgz#cf7f61fd87f35a793e6824952a6eb12242fe43fd" integrity sha512-saNK5i2A8pKO3Il+Ejk/KStTApUpWgCxjeUz9G+T8A+QHeDloZYH2c7pU/P3jA9QoNeKwjVO9wYQllPL9loeVg== "@nrwl/nx-linux-x64-musl@15.9.7": version "15.9.7" - resolved "https://registry.npmjs.org/@nrwl/nx-linux-x64-musl/-/nx-linux-x64-musl-15.9.7.tgz#2bec23c3696780540eb47fa1358dda780c84697f" + resolved "https://registry.yarnpkg.com/@nrwl/nx-linux-x64-musl/-/nx-linux-x64-musl-15.9.7.tgz#2bec23c3696780540eb47fa1358dda780c84697f" integrity sha512-extIUThYN94m4Vj4iZggt6hhMZWQSukBCo8pp91JHnDcryBg7SnYmnikwtY1ZAFyyRiNFBLCKNIDFGkKkSrZ9Q== "@nrwl/nx-win32-arm64-msvc@15.9.7": version "15.9.7" - resolved "https://registry.npmjs.org/@nrwl/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-15.9.7.tgz#21b56ef3ab4190370effea71bd83fdc3e47ec69c" + resolved "https://registry.yarnpkg.com/@nrwl/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-15.9.7.tgz#21b56ef3ab4190370effea71bd83fdc3e47ec69c" integrity sha512-GSQ54hJ5AAnKZb4KP4cmBnJ1oC4ILxnrG1mekxeM65c1RtWg9NpBwZ8E0gU3xNrTv8ZNsBeKi/9UhXBxhsIh8A== "@nrwl/nx-win32-x64-msvc@15.9.7": version "15.9.7" - resolved "https://registry.npmjs.org/@nrwl/nx-win32-x64-msvc/-/nx-win32-x64-msvc-15.9.7.tgz#1677ab1dcce921706b5677dc2844e3e0027f8bd5" + resolved "https://registry.yarnpkg.com/@nrwl/nx-win32-x64-msvc/-/nx-win32-x64-msvc-15.9.7.tgz#1677ab1dcce921706b5677dc2844e3e0027f8bd5" integrity sha512-x6URof79RPd8AlapVbPefUD3ynJZpmah3tYaYZ9xZRMXojVtEHV8Qh5vysKXQ1rNYJiiB8Ah6evSKWLbAH60tw== "@nrwl/tao@15.9.7": version "15.9.7" - resolved "https://registry.npmjs.org/@nrwl/tao/-/tao-15.9.7.tgz" + resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-15.9.7.tgz#c0e78c99caa6742762f7558f20d8524bc9015e97" integrity sha512-OBnHNvQf3vBH0qh9YnvBQQWyyFZ+PWguF6dJ8+1vyQYlrLVk/XZ8nJ4ukWFb+QfPv/O8VBmqaofaOI9aFC4yTw== dependencies: nx "15.9.7" "@octokit/auth-token@^2.4.0": version "2.5.0" - resolved "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz" + resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-2.5.0.tgz#27c37ea26c205f28443402477ffd261311f21e36" integrity sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g== dependencies: "@octokit/types" "^6.0.3" "@octokit/auth-token@^3.0.0": version "3.0.4" - resolved "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.4.tgz" + resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-3.0.4.tgz#70e941ba742bdd2b49bdb7393e821dea8520a3db" integrity sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ== "@octokit/core@3.2.0": version "3.2.0" - resolved "https://registry.npmjs.org/@octokit/core/-/core-3.2.0.tgz" + resolved "https://registry.yarnpkg.com/@octokit/core/-/core-3.2.0.tgz#7a872ad4cb8d8d2f417dd7fe1aaff3919c09dc04" integrity sha512-42jzu1GWlCr4KUo52X4hD3if2AwjNJLzsS8mqUs9JkJbsM3vzvSx8AqTnVBQjOM0hQMYBqR7/7SAUTfH7IZqIg== dependencies: "@octokit/auth-token" "^2.4.0" @@ -2023,7 +2017,7 @@ "@octokit/core@^4.2.1": version "4.2.4" - resolved "https://registry.npmjs.org/@octokit/core/-/core-4.2.4.tgz" + resolved "https://registry.yarnpkg.com/@octokit/core/-/core-4.2.4.tgz#d8769ec2b43ff37cc3ea89ec4681a20ba58ef907" integrity sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ== dependencies: "@octokit/auth-token" "^3.0.0" @@ -2036,7 +2030,7 @@ "@octokit/endpoint@^6.0.1": version "6.0.12" - resolved "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz" + resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-6.0.12.tgz#3b4d47a4b0e79b1027fb8d75d4221928b2d05658" integrity sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA== dependencies: "@octokit/types" "^6.0.3" @@ -2045,7 +2039,7 @@ "@octokit/endpoint@^7.0.0": version "7.0.6" - resolved "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.6.tgz" + resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-7.0.6.tgz#791f65d3937555141fb6c08f91d618a7d645f1e2" integrity sha512-5L4fseVRUsDFGR00tMWD/Trdeeihn999rTMGRMC1G/Ldi1uWlWJzI98H4Iak5DB/RVvQuyMYKqSK/R6mbSOQyg== dependencies: "@octokit/types" "^9.0.0" @@ -2054,7 +2048,7 @@ "@octokit/graphql@^4.3.1": version "4.8.0" - resolved "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz" + resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-4.8.0.tgz#664d9b11c0e12112cbf78e10f49a05959aa22cc3" integrity sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg== dependencies: "@octokit/request" "^5.6.0" @@ -2063,7 +2057,7 @@ "@octokit/graphql@^5.0.0": version "5.0.6" - resolved "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.6.tgz" + resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-5.0.6.tgz#9eac411ac4353ccc5d3fca7d76736e6888c5d248" integrity sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw== dependencies: "@octokit/request" "^6.0.0" @@ -2072,22 +2066,22 @@ "@octokit/openapi-types@^12.11.0": version "12.11.0" - resolved "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz" + resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-12.11.0.tgz#da5638d64f2b919bca89ce6602d059f1b52d3ef0" integrity sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ== "@octokit/openapi-types@^18.0.0": - version "18.0.0" - resolved "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.0.0.tgz" - integrity sha512-V8GImKs3TeQRxRtXFpG2wl19V7444NIOTDF24AWuIbmNaNYOQMWRbjcGDXV5B+0n887fgDcuMNOmlul+k+oJtw== + version "18.1.1" + resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-18.1.1.tgz#09bdfdabfd8e16d16324326da5148010d765f009" + integrity sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw== "@octokit/plugin-enterprise-rest@^6.0.1": version "6.0.1" - resolved "https://registry.npmjs.org/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-6.0.1.tgz" + resolved "https://registry.yarnpkg.com/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-6.0.1.tgz#e07896739618dab8da7d4077c658003775f95437" integrity sha512-93uGjlhUD+iNg1iWhUENAtJata6w5nE+V4urXOAlIXdco6xNZtUSfYY8dzp3Udy74aqO/B5UZL80x/YMa5PKRw== "@octokit/plugin-paginate-rest@^6.1.2": version "6.1.2" - resolved "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz" + resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz#f86456a7a1fe9e58fec6385a85cf1b34072341f8" integrity sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ== dependencies: "@octokit/tsconfig" "^1.0.2" @@ -2095,19 +2089,19 @@ "@octokit/plugin-request-log@^1.0.4": version "1.0.4" - resolved "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz" + resolved "https://registry.yarnpkg.com/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz#5e50ed7083a613816b1e4a28aeec5fb7f1462e85" integrity sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA== "@octokit/plugin-rest-endpoint-methods@^7.1.2": version "7.2.3" - resolved "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.2.3.tgz" + resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.2.3.tgz#37a84b171a6cb6658816c82c4082ac3512021797" integrity sha512-I5Gml6kTAkzVlN7KCtjOM+Ruwe/rQppp0QU372K1GP7kNOYEKe8Xn5BW4sE62JAHdwpq95OQK/qGNyKQMUzVgA== dependencies: "@octokit/types" "^10.0.0" "@octokit/request-error@^2.1.0": version "2.1.0" - resolved "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-2.1.0.tgz#9e150357831bfc788d13a4fd4b1913d60c74d677" integrity sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg== dependencies: "@octokit/types" "^6.0.3" @@ -2116,7 +2110,7 @@ "@octokit/request-error@^3.0.0": version "3.0.3" - resolved "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.3.tgz" + resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-3.0.3.tgz#ef3dd08b8e964e53e55d471acfe00baa892b9c69" integrity sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ== dependencies: "@octokit/types" "^9.0.0" @@ -2125,7 +2119,7 @@ "@octokit/request@^5.4.0", "@octokit/request@^5.6.0": version "5.6.3" - resolved "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz" + resolved "https://registry.yarnpkg.com/@octokit/request/-/request-5.6.3.tgz#19a022515a5bba965ac06c9d1334514eb50c48b0" integrity sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A== dependencies: "@octokit/endpoint" "^6.0.1" @@ -2137,7 +2131,7 @@ "@octokit/request@^6.0.0": version "6.2.8" - resolved "https://registry.npmjs.org/@octokit/request/-/request-6.2.8.tgz" + resolved "https://registry.yarnpkg.com/@octokit/request/-/request-6.2.8.tgz#aaf480b32ab2b210e9dadd8271d187c93171d8eb" integrity sha512-ow4+pkVQ+6XVVsekSYBzJC0VTVvh/FCTUUgTsboGq+DTeWdyIFV8WSCdo0RIxk6wSkBTHqIK1mYuY7nOBXOchw== dependencies: "@octokit/endpoint" "^7.0.0" @@ -2149,7 +2143,7 @@ "@octokit/rest@^19.0.3": version "19.0.13" - resolved "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.13.tgz" + resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-19.0.13.tgz#e799393264edc6d3c67eeda9e5bd7832dcf974e4" integrity sha512-/EzVox5V9gYGdbAI+ovYj3nXQT1TtTHRT+0eZPcuC05UFSWO3mdO9UY1C0i2eLF9Un1ONJkAk+IEtYGAC+TahA== dependencies: "@octokit/core" "^4.2.1" @@ -2159,40 +2153,40 @@ "@octokit/tsconfig@^1.0.2": version "1.0.2" - resolved "https://registry.npmjs.org/@octokit/tsconfig/-/tsconfig-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/@octokit/tsconfig/-/tsconfig-1.0.2.tgz#59b024d6f3c0ed82f00d08ead5b3750469125af7" integrity sha512-I0vDR0rdtP8p2lGMzvsJzbhdOWy405HcGovrspJ8RRibHnyRgggUSNO5AIox5LmqiwmatHKYsvj6VGFHkqS7lA== "@octokit/types@^10.0.0": version "10.0.0" - resolved "https://registry.npmjs.org/@octokit/types/-/types-10.0.0.tgz" + resolved "https://registry.yarnpkg.com/@octokit/types/-/types-10.0.0.tgz#7ee19c464ea4ada306c43f1a45d444000f419a4a" integrity sha512-Vm8IddVmhCgU1fxC1eyinpwqzXPEYu0NrYzD3YZjlGjyftdLBTeqNblRC0jmJmgxbJIsQlyogVeGnrNaaMVzIg== dependencies: "@octokit/openapi-types" "^18.0.0" "@octokit/types@^5.0.0": version "5.5.0" - resolved "https://registry.npmjs.org/@octokit/types/-/types-5.5.0.tgz" + resolved "https://registry.yarnpkg.com/@octokit/types/-/types-5.5.0.tgz#e5f06e8db21246ca102aa28444cdb13ae17a139b" integrity sha512-UZ1pErDue6bZNjYOotCNveTXArOMZQFG6hKJfOnGnulVCMcVVi7YIIuuR4WfBhjo7zgpmzn/BkPDnUXtNx+PcQ== dependencies: "@types/node" ">= 8" "@octokit/types@^6.0.3", "@octokit/types@^6.16.1": version "6.41.0" - resolved "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz" + resolved "https://registry.yarnpkg.com/@octokit/types/-/types-6.41.0.tgz#e58ef78d78596d2fb7df9c6259802464b5f84a04" integrity sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg== dependencies: "@octokit/openapi-types" "^12.11.0" "@octokit/types@^9.0.0", "@octokit/types@^9.2.3": version "9.3.2" - resolved "https://registry.npmjs.org/@octokit/types/-/types-9.3.2.tgz" + resolved "https://registry.yarnpkg.com/@octokit/types/-/types-9.3.2.tgz#3f5f89903b69f6a2d196d78ec35f888c0013cac5" integrity sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA== dependencies: "@octokit/openapi-types" "^18.0.0" "@parcel/watcher@2.0.4": version "2.0.4" - resolved "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.0.4.tgz" + resolved "https://registry.yarnpkg.com/@parcel/watcher/-/watcher-2.0.4.tgz#f300fef4cc38008ff4b8c29d92588eced3ce014b" integrity sha512-cTDi+FUDBIUOBKEtj+nhiJ71AZVlkAsQFuGQTun5tV9mwQBQgZvhCzG+URPQc8myeN32yRVZEfVAPCs1RW+Jvg== dependencies: node-addon-api "^3.2.1" @@ -2203,33 +2197,147 @@ resolved "https://registry.yarnpkg.com/@pinax/graph-networks-registry/-/graph-networks-registry-0.6.7.tgz#ceb994f3b31e2943b9c9d9b09dd86eb00d067c0e" integrity sha512-xogeCEZ50XRMxpBwE3TZjJ8RCO8Guv39gDRrrKtlpDEDEMLm0MzD3A0SQObgj7aF7qTZNRTWzsuvQdxgzw25wQ== -"@pkgjs/parseargs@^0.11.0": - version "0.11.0" - resolved "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz" - integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== +"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" + integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ== + +"@protobufjs/base64@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" + integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== + +"@protobufjs/codegen@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" + integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== + +"@protobufjs/eventemitter@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" + integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q== + +"@protobufjs/fetch@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" + integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ== + dependencies: + "@protobufjs/aspromise" "^1.1.1" + "@protobufjs/inquire" "^1.1.0" + +"@protobufjs/float@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" + integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ== + +"@protobufjs/inquire@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" + integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q== + +"@protobufjs/path@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" + integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA== + +"@protobufjs/pool@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" + integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw== + +"@protobufjs/utf8@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== + +"@rushstack/node-core-library@5.13.0": + version "5.13.0" + resolved "https://registry.yarnpkg.com/@rushstack/node-core-library/-/node-core-library-5.13.0.tgz#f79d6868b74be102eee75b93c37be45fb9b47ead" + integrity sha512-IGVhy+JgUacAdCGXKUrRhwHMTzqhWwZUI+qEPcdzsb80heOw0QPbhhoVsoiMF7Klp8eYsp7hzpScMXmOa3Uhfg== + dependencies: + ajv "~8.13.0" + ajv-draft-04 "~1.0.0" + ajv-formats "~3.0.1" + fs-extra "~11.3.0" + import-lazy "~4.0.0" + jju "~1.4.0" + resolve "~1.22.1" + semver "~7.5.4" + +"@rushstack/terminal@0.15.2": + version "0.15.2" + resolved "https://registry.yarnpkg.com/@rushstack/terminal/-/terminal-0.15.2.tgz#8fa030409603a22db606ecb18709050e46517add" + integrity sha512-7Hmc0ysK5077R/IkLS9hYu0QuNafm+TbZbtYVzCMbeOdMjaRboLKrhryjwZSRJGJzu+TV1ON7qZHeqf58XfLpA== + dependencies: + "@rushstack/node-core-library" "5.13.0" + supports-color "~8.1.1" "@rushstack/ts-command-line@^4.7.7": - version "4.16.0" - resolved "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.16.0.tgz" - integrity sha512-WJKhdR9ThK9Iy7t78O3at7I3X4Ssp5RRZay/IQa8NywqkFy/DQbT3iLouodMMdUwLZD9n8n++xLubVd3dkmpkg== + version "4.23.7" + resolved "https://registry.yarnpkg.com/@rushstack/ts-command-line/-/ts-command-line-4.23.7.tgz#9c6f05a00f776c7b8ea3321e2b5a03acc5e9efa8" + integrity sha512-Gr9cB7DGe6uz5vq2wdr89WbVDKz0UeuFEn5H2CfWDe7JvjFFaiV15gi6mqDBTbHhHCWS7w8mF1h3BnIfUndqdA== dependencies: + "@rushstack/terminal" "0.15.2" "@types/argparse" "1.0.38" argparse "~1.0.9" - colors "~1.2.1" string-argv "~0.3.1" -"@semiotic-labs/tap-contracts-bindings@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@semiotic-labs/tap-contracts-bindings/-/tap-contracts-bindings-1.2.1.tgz#4aa0b009b761bbb9aafb1ea0cbd89ccf7a7cb801" - integrity sha512-VwpKOxsJq2mrWZQ9y2kvwxNKqHtigmibH2uXoFxekIO8jfBjC69J8c/avzYNU3YBccAVEbLvfyNoDUs26c0XeQ== +"@scure/base@~1.1.0", "@scure/base@~1.1.6": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.9.tgz#e5e142fbbfe251091f9c5f1dd4c834ac04c3dbd1" + integrity sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg== + +"@scure/base@~1.2.5": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.2.5.tgz#f9d1b232425b367d0dcb81c96611dcc651d58671" + integrity sha512-9rE6EOVeIQzt5TSu4v+K523F8u6DhBsoZWPGKlnCshhlDhy0kJzUX4V+tr2dWmzF1GdekvThABoEQBGBQI7xZw== + +"@scure/bip32@1.1.5": + version "1.1.5" + resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.1.5.tgz#d2ccae16dcc2e75bc1d75f5ef3c66a338d1ba300" + integrity sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw== + dependencies: + "@noble/hashes" "~1.2.0" + "@noble/secp256k1" "~1.7.0" + "@scure/base" "~1.1.0" + +"@scure/bip32@1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.4.0.tgz#4e1f1e196abedcef395b33b9674a042524e20d67" + integrity sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg== dependencies: - "@typechain/ethers-v5" "^11.1.2" + "@noble/curves" "~1.4.0" + "@noble/hashes" "~1.4.0" + "@scure/base" "~1.1.6" + +"@scure/bip39@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.1.1.tgz#b54557b2e86214319405db819c4b6a370cf340c5" + integrity sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg== + dependencies: + "@noble/hashes" "~1.2.0" + "@scure/base" "~1.1.0" + +"@scure/bip39@1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.3.0.tgz#0f258c16823ddd00739461ac31398b4e7d6a18c3" + integrity sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ== + dependencies: + "@noble/hashes" "~1.4.0" + "@scure/base" "~1.1.6" + +"@semiotic-labs/tap-contracts-bindings@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@semiotic-labs/tap-contracts-bindings/-/tap-contracts-bindings-2.0.0.tgz#f0e348fef79e54f36e27502483c02267ebbcaec8" + integrity sha512-CPYsX3DSSPY98VMRDH4xoEZAiQSVVynXssWvbzcj4H1NRfc3O+T/jFxSUQG/1LCAnHanOEhoH9hevfjULGZSgg== + dependencies: + "@typechain/ethers-v6" "^0.5.1" abitype "^0.10.3" - ethers "5.7.0" + ethers "6.13.7" "@sentry/core@5.30.0": version "5.30.0" - resolved "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.30.0.tgz#6b203664f69e75106ee8b5a2fe1d717379b331f3" integrity sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg== dependencies: "@sentry/hub" "5.30.0" @@ -2240,7 +2348,7 @@ "@sentry/hub@5.30.0": version "5.30.0" - resolved "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz" + resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.30.0.tgz#2453be9b9cb903404366e198bd30c7ca74cdc100" integrity sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ== dependencies: "@sentry/types" "5.30.0" @@ -2249,16 +2357,16 @@ "@sentry/minimal@5.30.0": version "5.30.0" - resolved "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz" + resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.30.0.tgz#ce3d3a6a273428e0084adcb800bc12e72d34637b" integrity sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw== dependencies: "@sentry/hub" "5.30.0" "@sentry/types" "5.30.0" tslib "^1.9.3" -"@sentry/node@^5.21.1": +"@sentry/node@^5.18.1", "@sentry/node@^5.21.1": version "5.30.0" - resolved "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz" + resolved "https://registry.yarnpkg.com/@sentry/node/-/node-5.30.0.tgz#4ca479e799b1021285d7fe12ac0858951c11cd48" integrity sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg== dependencies: "@sentry/core" "5.30.0" @@ -2273,7 +2381,7 @@ "@sentry/tracing@5.30.0": version "5.30.0" - resolved "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz" + resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-5.30.0.tgz#501d21f00c3f3be7f7635d8710da70d9419d4e1f" integrity sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw== dependencies: "@sentry/hub" "5.30.0" @@ -2284,12 +2392,12 @@ "@sentry/types@5.30.0": version "5.30.0" - resolved "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.30.0.tgz#19709bbe12a1a0115bc790b8942917da5636f402" integrity sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw== "@sentry/utils@5.30.0": version "5.30.0" - resolved "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.30.0.tgz#9a5bd7ccff85ccfe7856d493bffa64cabc41e980" integrity sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww== dependencies: "@sentry/types" "5.30.0" @@ -2316,12 +2424,12 @@ "@thi.ng/api@^7.1.4", "@thi.ng/api@^7.2.0": version "7.2.0" - resolved "https://registry.npmjs.org/@thi.ng/api/-/api-7.2.0.tgz" + resolved "https://registry.yarnpkg.com/@thi.ng/api/-/api-7.2.0.tgz#ed3d7c70aca157a8f53613f7359be7d2e31d6f18" integrity sha512-4NcwHXxwPF/JgJG/jSFd9rjfQNguF0QrHvd6e+CEf4T0sFChqetW6ZmJ6/a2X+noDVntgulegA+Bx0HHzw+Tyw== "@thi.ng/arrays@^1.0.3": version "1.0.3" - resolved "https://registry.npmjs.org/@thi.ng/arrays/-/arrays-1.0.3.tgz" + resolved "https://registry.yarnpkg.com/@thi.ng/arrays/-/arrays-1.0.3.tgz#f4d26184f6da3ff30beb2488a131e19f187fd920" integrity sha512-ZUB27bdpTwcvxYJTlt/eWKrj98nWXo0lAUPwRwubk4GlH8rTKKkc7qZr9/4LCKPsNjnZdQqbBtNvNf3HjYxCzw== dependencies: "@thi.ng/api" "^7.2.0" @@ -2333,21 +2441,21 @@ "@thi.ng/checks@^2.9.11": version "2.9.11" - resolved "https://registry.npmjs.org/@thi.ng/checks/-/checks-2.9.11.tgz" + resolved "https://registry.yarnpkg.com/@thi.ng/checks/-/checks-2.9.11.tgz#b7e4c78828f553613d2af025ce7ae3f9306f27bb" integrity sha512-fBvWod32w24JlJsrrOdl+tlx+UNehCORi4rHaJ7l7HH+SEhD/lYTCXOBjwu9D/ztIUjMP5Q+n8cAqI5iPhbvAQ== dependencies: tslib "^2.3.1" "@thi.ng/compare@^1.3.28", "@thi.ng/compare@^1.3.34": version "1.3.34" - resolved "https://registry.npmjs.org/@thi.ng/compare/-/compare-1.3.34.tgz" + resolved "https://registry.yarnpkg.com/@thi.ng/compare/-/compare-1.3.34.tgz#321e10780955b18a4bcf7876d0fe0323be9d7be8" integrity sha512-E+UWhmo8l5yeHDuriPUsfrnk/Mj5kSDNRX7lPfv2zNdAQ7N8UDzc0IXu46U6EpqtCReo+2n5N8qzfD3TjerFRw== dependencies: "@thi.ng/api" "^7.2.0" "@thi.ng/compose@^1.4.36": version "1.4.36" - resolved "https://registry.npmjs.org/@thi.ng/compose/-/compose-1.4.36.tgz" + resolved "https://registry.yarnpkg.com/@thi.ng/compose/-/compose-1.4.36.tgz#d9b737d16c80f9355cf598e41f71529acba564aa" integrity sha512-iaij+nAwgeyQTMAiGldAB0dfBBl77kcwJ8HPBFJxDDWsLCS3lIcywTcJPcXxZaL0nw49VJpPrgt0Qw17Q8Y+6g== dependencies: "@thi.ng/api" "^7.2.0" @@ -2355,7 +2463,7 @@ "@thi.ng/dcons@^2.3.34": version "2.3.34" - resolved "https://registry.npmjs.org/@thi.ng/dcons/-/dcons-2.3.34.tgz" + resolved "https://registry.yarnpkg.com/@thi.ng/dcons/-/dcons-2.3.34.tgz#eae63aaa7f2ef981dbf520fa9dc9f11ad4574cd8" integrity sha512-NTgwtZsB+3X4Hh3cp1KyY0GFwi/dMoX1FSpJhOhEiOa2REX33O5cryo8FUgSasGC7TeKBlLB9UADI84g+4mNlQ== dependencies: "@thi.ng/api" "^7.2.0" @@ -2368,17 +2476,17 @@ "@thi.ng/equiv@^1.0.45": version "1.0.45" - resolved "https://registry.npmjs.org/@thi.ng/equiv/-/equiv-1.0.45.tgz" + resolved "https://registry.yarnpkg.com/@thi.ng/equiv/-/equiv-1.0.45.tgz#02bf71a630939c8f61a2a7b9e83cca9569ead7f3" integrity sha512-tdXaJfF0pFvT80Q7BOlhc7H7ja/RbVGzlGpE4LqjDWfXPPbLYwmq6EbQuHWeXuvT0qe+BsGnuO5UXAR5B8oGGQ== "@thi.ng/errors@^1.3.4": version "1.3.4" - resolved "https://registry.npmjs.org/@thi.ng/errors/-/errors-1.3.4.tgz" + resolved "https://registry.yarnpkg.com/@thi.ng/errors/-/errors-1.3.4.tgz#8f7675f7a895a87f0f609d64db69bc04483e0b29" integrity sha512-hTk71OPKnioN349sdj2DAoY+69eSerB3MN4Zwz6mosr1QFzIMkfkNOtBeC+Gm0yi0V0EY5LeBYFgqb3oXbtTbw== "@thi.ng/heaps@1.2.38": version "1.2.38" - resolved "https://registry.npmjs.org/@thi.ng/heaps/-/heaps-1.2.38.tgz" + resolved "https://registry.yarnpkg.com/@thi.ng/heaps/-/heaps-1.2.38.tgz#c5027c02bedb41644fc71d109cd16a878a48ad0b" integrity sha512-lWDQsGmt6YuHgmog4wpSKa7wqawt0JVyCREWc/J2bA9vcg/cYfljda2teVTA3rTUhKWs/S2htorN8On7+Rxt5A== dependencies: "@thi.ng/api" "^7.1.4" @@ -2386,7 +2494,7 @@ "@thi.ng/heaps@^1.3.1": version "1.3.1" - resolved "https://registry.npmjs.org/@thi.ng/heaps/-/heaps-1.3.1.tgz" + resolved "https://registry.yarnpkg.com/@thi.ng/heaps/-/heaps-1.3.1.tgz#307d0673afb0a66362485f2ef639c029ec74d9ed" integrity sha512-0vPYpMTbPlfr1uCp+ebqsUzZkPyKFo1/owqQV2naTYU8dmSJ0wK3uP6aiU/UYrnnb0zVtY6xy72ucGOyapu0Rg== dependencies: "@thi.ng/api" "^7.2.0" @@ -2395,12 +2503,12 @@ "@thi.ng/hex@^1.0.4": version "1.0.4" - resolved "https://registry.npmjs.org/@thi.ng/hex/-/hex-1.0.4.tgz" + resolved "https://registry.yarnpkg.com/@thi.ng/hex/-/hex-1.0.4.tgz#5c5c86d3aef0422709b4aa8cfadd3b3f01a4a808" integrity sha512-9ofIG4nXhEskGeOJthpi/9LXFIPrlZ/MmHpgLWa3wNqTVhODP/o++mu9jDKojHEpKvswkkFCE+mSVmMu8xo4mQ== "@thi.ng/iterators@5.1.74": version "5.1.74" - resolved "https://registry.npmjs.org/@thi.ng/iterators/-/iterators-5.1.74.tgz" + resolved "https://registry.yarnpkg.com/@thi.ng/iterators/-/iterators-5.1.74.tgz#8e42ca092049ae4aa45e24e1a9649149fc5916b3" integrity sha512-dv7ExN1ygkHuPz0f2pFPoE1Ged+B3e3qgQ4n0iHDV386qDkYRgOFMGnSFaBDnNaKNlhyAXT8Kbb+jy/zbV+P4g== dependencies: "@thi.ng/api" "^7.2.0" @@ -2409,14 +2517,14 @@ "@thi.ng/math@^4.0.6": version "4.0.6" - resolved "https://registry.npmjs.org/@thi.ng/math/-/math-4.0.6.tgz" + resolved "https://registry.yarnpkg.com/@thi.ng/math/-/math-4.0.6.tgz#14f57425ceed922a3b22f6fc7b0f90a3a9a12f22" integrity sha512-MCXMW9Bzlgt8uqOkz1UB+gTvnB1viK5R/5c+z/1lmH2/rFa5TY8TKAByCsr1P+Rc+F7AbFoJlefFMSS7f5CDlg== dependencies: "@thi.ng/api" "^7.2.0" "@thi.ng/random@^2.4.8": version "2.4.8" - resolved "https://registry.npmjs.org/@thi.ng/random/-/random-2.4.8.tgz" + resolved "https://registry.yarnpkg.com/@thi.ng/random/-/random-2.4.8.tgz#428950e501c5a76907e3e6cb93985db07322012e" integrity sha512-4JJB8zbaPxjlAp1kCqsBbs6eN4Ivd/5fs1e4GlvmNkyGSucHIDTWvw6NnQWqUx2oPaAEDB9CFCH7SOcGC/cwkw== dependencies: "@thi.ng/api" "^7.2.0" @@ -2425,7 +2533,7 @@ "@thi.ng/transducers@^7.9.2": version "7.9.2" - resolved "https://registry.npmjs.org/@thi.ng/transducers/-/transducers-7.9.2.tgz" + resolved "https://registry.yarnpkg.com/@thi.ng/transducers/-/transducers-7.9.2.tgz#890166abe47dfbbd1497d6da7e2a1b2402bc4616" integrity sha512-FrC0cCdaQZ9di2sbLbwkQaweLUEvpaSVSwdbEhS77Pn/uoyZe+U+SnBAoyxKFgXHImtBpKFxu8Zd0is3ogrKNQ== dependencies: "@thi.ng/api" "^7.2.0" @@ -2439,7 +2547,7 @@ "@tootallnate/once@2": version "2.0.0" - resolved "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== "@tsconfig/node10@^1.0.7": @@ -2462,17 +2570,17 @@ resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== -"@typechain/ethers-v5@^11.1.2": - version "11.1.2" - resolved "https://registry.npmjs.org/@typechain/ethers-v5/-/ethers-v5-11.1.2.tgz" - integrity sha512-ID6pqWkao54EuUQa0P5RgjvfA3MYqxUQKpbGKERbsjBW5Ra7EIXvbMlPp2pcP5IAdUkyMCFYsP2SN5q7mPdLDQ== +"@typechain/ethers-v6@^0.5.1": + version "0.5.1" + resolved "https://registry.yarnpkg.com/@typechain/ethers-v6/-/ethers-v6-0.5.1.tgz#42fe214a19a8b687086c93189b301e2b878797ea" + integrity sha512-F+GklO8jBWlsaVV+9oHaPh5NJdd6rAKN4tklGfInX1Q7h0xPgVLP39Jl3eCulPB5qexI71ZFHwbljx4ZXNfouA== dependencies: lodash "^4.17.15" ts-essentials "^7.0.1" "@types/argparse@1.0.38": version "1.0.38" - resolved "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz" + resolved "https://registry.yarnpkg.com/@types/argparse/-/argparse-1.0.38.tgz#a81fd8606d481f873a3800c6ebae4f1d768a56a9" integrity sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA== "@types/babel__core@^7.1.14": @@ -2487,9 +2595,9 @@ "@types/babel__traverse" "*" "@types/babel__generator@*": - version "7.6.8" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.8.tgz#f836c61f48b1346e7d2b0d93c6dacc5b9535d3ab" - integrity sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw== + version "7.27.0" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.27.0.tgz#b5819294c51179957afaec341442f9341e4108a9" + integrity sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg== dependencies: "@babel/types" "^7.0.0" @@ -2502,9 +2610,9 @@ "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.5.tgz#7b7502be0aa80cc4ef22978846b983edaafcd4dd" - integrity sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ== + version "7.20.7" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.7.tgz#968cdc2366ec3da159f61166428ee40f370e56c2" + integrity sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng== dependencies: "@babel/types" "^7.20.7" @@ -2513,6 +2621,13 @@ resolved "https://registry.yarnpkg.com/@types/bluebird/-/bluebird-3.5.42.tgz#7ec05f1ce9986d920313c1377a5662b1b563d366" integrity sha512-Jhy+MWRlro6UjVi578V/4ZGNfeCOcNCp0YaFNIUGFKlImowqwb1O/22wDVk3FDGMLqxdpOV3qQHD5fPEH4hK6A== +"@types/bn.js@^5.1.0": + version "5.1.6" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.6.tgz#9ba818eec0c85e4d3c679518428afdf611d03203" + integrity sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w== + dependencies: + "@types/node" "*" + "@types/body-parser@*": version "1.19.5" resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.5.tgz#04ce9a3b677dc8bd681a17da1ab9835dc9d3ede4" @@ -2528,20 +2643,13 @@ dependencies: base-x "^3.0.6" -"@types/connect@*": +"@types/connect@*", "@types/connect@^3.4.33": version "3.4.38" resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858" integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== dependencies: "@types/node" "*" -"@types/connect@^3.4.33": - version "3.4.36" - resolved "https://registry.npmjs.org/@types/connect/-/connect-3.4.36.tgz" - integrity sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w== - dependencies: - "@types/node" "*" - "@types/continuation-local-storage@*": version "3.2.7" resolved "https://registry.yarnpkg.com/@types/continuation-local-storage/-/continuation-local-storage-3.2.7.tgz#363bbeb1ef35ee2298cc371e34c74eb1b0a0b52c" @@ -2557,26 +2665,16 @@ "@types/node" "*" "@types/debug@^4.1.8": - version "4.1.8" - resolved "https://registry.npmjs.org/@types/debug/-/debug-4.1.8.tgz" - integrity sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ== + version "4.1.12" + resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.12.tgz#a155f21690871953410df4b6b6f53187f0500917" + integrity sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ== dependencies: "@types/ms" "*" -"@types/express-serve-static-core@^4.17.33": - version "4.19.0" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.19.0.tgz#3ae8ab3767d98d0b682cda063c3339e1e86ccfaa" - integrity sha512-bGyep3JqPCRry1wq+O5n7oiBgGWmeIJXPjXXCo8EK0u8duZGSYar7cGqd3ML2JUsLGeB7fmc06KYo9fLGWqPvQ== - dependencies: - "@types/node" "*" - "@types/qs" "*" - "@types/range-parser" "*" - "@types/send" "*" - -"@types/express-serve-static-core@^4.17.9": - version "4.17.36" - resolved "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.36.tgz" - integrity sha512-zbivROJ0ZqLAtMzgzIUC4oNqDG9iF0lSsAqpOD9kbs5xcIM3dTiyuHvBc7R8MtWBp3AAWGaovJa+wzWPjLYW7Q== +"@types/express-serve-static-core@^4.17.33", "@types/express-serve-static-core@^4.17.9": + version "4.19.6" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz#e01324c2a024ff367d92c66f48553ced0ab50267" + integrity sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A== dependencies: "@types/node" "*" "@types/qs" "*" @@ -2643,9 +2741,9 @@ integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== "@types/lodash.clonedeep@^4.5.7": - version "4.5.7" - resolved "https://registry.npmjs.org/@types/lodash.clonedeep/-/lodash.clonedeep-4.5.7.tgz" - integrity sha512-ccNqkPptFIXrpVqUECi60/DFxjNKsfoQxSQsgcBJCX/fuX1wgyQieojkcWH/KpE3xzLoWN/2k+ZeGqIN3paSvw== + version "4.5.9" + resolved "https://registry.yarnpkg.com/@types/lodash.clonedeep/-/lodash.clonedeep-4.5.9.tgz#ea48276c7cc18d080e00bb56cf965bcceb3f0fc1" + integrity sha512-19429mWC+FyaAhOLzsS8kZUsI+/GmBAQ0HFiCPsKGU+7pBXOQWhyrY6xNNDwUSX8SMZMJvuFVMF9O5dQOlQK9Q== dependencies: "@types/lodash" "*" @@ -2665,7 +2763,7 @@ "@types/lodash.intersection@^4.4.7": version "4.4.9" - resolved "https://registry.npmjs.org/@types/lodash.intersection/-/lodash.intersection-4.4.9.tgz#24afb3177f0100d3772eedd0bdc331510d72d75d" + resolved "https://registry.yarnpkg.com/@types/lodash.intersection/-/lodash.intersection-4.4.9.tgz#24afb3177f0100d3772eedd0bdc331510d72d75d" integrity sha512-AenZXU5mbikacV1LyGTFIP7s94s0UyscACObGMrqDvKjZfRj+PpmAVvhNeLUMCBLi7RMlLgHic53J/LbaciEmg== dependencies: "@types/lodash" "*" @@ -2686,7 +2784,7 @@ "@types/lodash.xor@^4.5.7": version "4.5.9" - resolved "https://registry.npmjs.org/@types/lodash.xor/-/lodash.xor-4.5.9.tgz#8e533b21f7530f134cfffe8e2470127c797d9fa6" + resolved "https://registry.yarnpkg.com/@types/lodash.xor/-/lodash.xor-4.5.9.tgz#8e533b21f7530f134cfffe8e2470127c797d9fa6" integrity sha512-XCuHoMz2zVC8IBTRetsL9XRyy0zpnTtpqioG4nHWwtnt0RLbKjtdpCwU0/BfRszP+sMQkIEy1cDFydMhKOeDlg== dependencies: "@types/lodash" "*" @@ -2699,24 +2797,29 @@ "@types/lodash" "*" "@types/lodash@*", "@types/lodash@^4.14.159": - version "4.14.198" - resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.198.tgz" - integrity sha512-trNJ/vtMZYMLhfN45uLq4ShQSw0/S7xCTLLVM+WM1rmFpba/VS42jVUgaO3w/NOLiWR/09lnYk0yMaA/atdIsg== + version "4.17.16" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.16.tgz#94ae78fab4a38d73086e962d0b65c30d816bfb0a" + integrity sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g== + +"@types/lru-cache@^5.1.0": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@types/lru-cache/-/lru-cache-5.1.1.tgz#c48c2e27b65d2a153b19bfc1a317e30872e01eef" + integrity sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw== "@types/mime@^1": - version "1.3.2" - resolved "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz" - integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" + integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== "@types/minimatch@^3.0.3": version "3.0.5" - resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== "@types/minimist@^1.2.0": - version "1.2.2" - resolved "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz" - integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== + version "1.2.5" + resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.5.tgz#ec10755e871497bcd83efe927e43ec46e8c0747e" + integrity sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag== "@types/morgan@1.9.5": version "1.9.5" @@ -2726,9 +2829,9 @@ "@types/node" "*" "@types/ms@*": - version "0.7.31" - resolved "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz" - integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== + version "2.1.0" + resolved "https://registry.yarnpkg.com/@types/ms/-/ms-2.1.0.tgz#052aa67a48eccc4309d7f0191b7e41434b90bb78" + integrity sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA== "@types/ngeohash@0.6.4": version "0.6.4" @@ -2736,29 +2839,45 @@ integrity sha512-rr20mmx41OkWx4q5du2dv2sESR/6xH2tzScUQXwO8SiaQWa6PYTuan1nqBtA76FR9qkVfZY7nwQwZNC9StX/Ww== "@types/node@*", "@types/node@>= 8": - version "20.6.2" - resolved "https://registry.npmjs.org/@types/node/-/node-20.6.2.tgz" - integrity sha512-Y+/1vGBHV/cYk6OI1Na/LHzwnlNCAfU3ZNGrc1LdRe/LAIbdDPTTv/HU3M7yXN448aTVDq3eKRm2cg7iKLb8gw== + version "22.15.18" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.15.18.tgz#2f8240f7e932f571c2d45f555ba0b6c3f7a75963" + integrity sha512-v1DKRfUdyW+jJhZNEI1PYy29S2YRxMV5AOO/x/SjKmW0acCIOqmbj6Haf9eHAhsPmrhlHSxEhv/1WszcLWV4cg== + dependencies: + undici-types "~6.21.0" "@types/node@20.6.1": version "20.6.1" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.6.1.tgz#8b589bba9b2af0128796461a0979764562687e6f" integrity sha512-4LcJvuXQlv4lTHnxwyHQZ3uR9Zw2j7m1C9DfuwoTFQQP4Pmu04O6IfLYgMmHoOCt0nosItLLZAH+sOrRE0Bo8g== +"@types/node@22.7.5": + version "22.7.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.7.5.tgz#cfde981727a7ab3611a481510b473ae54442b92b" + integrity sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ== + dependencies: + undici-types "~6.19.2" + +"@types/node@>=13.7.0": + version "22.13.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.13.1.tgz#a2a3fefbdeb7ba6b89f40371842162fac0934f33" + integrity sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew== + dependencies: + undici-types "~6.20.0" + "@types/node@^12.12.54": version "12.20.55" - resolved "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240" integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== "@types/normalize-package-data@^2.4.0": - version "2.4.1" - resolved "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz" - integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw== + version "2.4.4" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz#56e2cc26c397c038fab0e3a917a12d5c5909e901" + integrity sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA== "@types/parse-json@^4.0.0": - version "4.0.0" - resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz" - integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.2.tgz#5950e50960793055845e956c427fc2b0d70c5239" + integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw== "@types/parsimmon@^1.10.6": version "1.10.9" @@ -2771,29 +2890,29 @@ integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA== "@types/qs@*": - version "6.9.8" - resolved "https://registry.npmjs.org/@types/qs/-/qs-6.9.8.tgz" - integrity sha512-u95svzDlTysU5xecFNTgfFG5RUWu1A9P0VzgpcIiGZA9iraHOdSzcxMxQ55DyeRaGCSxQi7LxXDI4rzq/MYfdg== + version "6.9.18" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.18.tgz#877292caa91f7c1b213032b34626505b746624c2" + integrity sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA== "@types/range-parser@*": - version "1.2.4" - resolved "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz" - integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== + version "1.2.7" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb" + integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== "@types/retry@^0.12.0": - version "0.12.2" - resolved "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz" - integrity sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow== + version "0.12.5" + resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.5.tgz#f090ff4bd8d2e5b940ff270ab39fd5ca1834a07e" + integrity sha512-3xSjTp3v03X/lSQLkczaN9UIEwJMoMCA1+Nb5HfbJEQWogdeQIyVtTvxPXDQjZ5zws8rFQfVfRdz03ARihPJgw== "@types/semver@^7.5.0": - version "7.5.8" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.8.tgz#8268a8c57a3e4abd25c165ecd36237db7948a55e" - integrity sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ== + version "7.7.0" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.7.0.tgz#64c441bdae033b378b6eef7d0c3d77c329b9378e" + integrity sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA== "@types/send@*": - version "0.17.1" - resolved "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz" - integrity sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q== + version "0.17.4" + resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.4.tgz#6619cd24e7270793702e4e6a4b958a9010cfc57a" + integrity sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA== dependencies: "@types/mime" "^1" "@types/node" "*" @@ -2822,24 +2941,19 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8" integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== -"@types/validator@*": - version "13.12.3" - resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.12.3.tgz#af160ddaf1e43ab66fe69473a90b14bb9f435d29" - integrity sha512-2ipwZ2NydGQJImne+FhNdhgRM37e9lCev99KnqkbFHd94Xn/mErARWI1RSLem1QA19ch5kOhzIZd7e8CA2FI8g== - -"@types/validator@^13.7.17": - version "13.11.1" - resolved "https://registry.npmjs.org/@types/validator/-/validator-13.11.1.tgz" - integrity sha512-d/MUkJYdOeKycmm75Arql4M5+UuXmf4cHdHKsyw1GcvnNgL6s77UkgSgJ8TE/rI5PYsnwYq5jkcWBLuN/MpQ1A== +"@types/validator@*", "@types/validator@^13.7.17": + version "13.15.0" + resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.15.0.tgz#d4643730536900190bb476a1dda0a4897c8881e2" + integrity sha512-nh7nrWhLr6CBq9ldtw0wx+z9wKnnv/uTVLA9g/3/TcOYxbpOSZE+MhKPmWqU+K0NvThjhv12uD8MuqijB0WzEA== "@types/verror@^1.10.4": - version "1.10.6" - resolved "https://registry.npmjs.org/@types/verror/-/verror-1.10.6.tgz" - integrity sha512-NNm+gdePAX1VGvPcGZCDKQZKYSiAWigKhKaz5KF94hG6f2s8de9Ow5+7AbXoeKxL8gavZfk4UquSAygOF2duEQ== + version "1.10.11" + resolved "https://registry.yarnpkg.com/@types/verror/-/verror-1.10.11.tgz#d3d6b418978c8aa202d41e5bb3483227b6ecc1bb" + integrity sha512-RlDm9K7+o5stv0Co8i8ZRGxDbrTxhJtgjqjFyVh/tXQyl/rYtTKlnTvZ88oSTeYREWurwx20Js4kTuKCsFkUtg== "@types/ws@^7.4.4": version "7.4.7" - resolved "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== dependencies: "@types/node" "*" @@ -2857,9 +2971,9 @@ "@types/yargs-parser" "*" "@types/yargs@^17.0.8": - version "17.0.32" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.32.tgz#030774723a2f7faafebf645f4e5a48371dca6229" - integrity sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog== + version "17.0.33" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.33.tgz#8c32303da83eec050a84b3c7ae7b9f922d13e32d" + integrity sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA== dependencies: "@types/yargs-parser" "*" @@ -3034,9 +3148,9 @@ eslint-visitor-keys "^3.4.1" "@ungap/structured-clone@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" - integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== + version "1.3.0" + resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.3.0.tgz#d06bbb384ebcf6c505fde1c3d0ed4ddffe0aaff8" + integrity sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g== "@urql/core@3.1.0", "@urql/core@>=3.1.0": version "3.1.0" @@ -3055,12 +3169,12 @@ "@yarnpkg/lockfile@^1.1.0": version "1.1.0" - resolved "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz" + resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== "@yarnpkg/parsers@3.0.0-rc.46": version "3.0.0-rc.46" - resolved "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-3.0.0-rc.46.tgz" + resolved "https://registry.yarnpkg.com/@yarnpkg/parsers/-/parsers-3.0.0-rc.46.tgz#03f8363111efc0ea670e53b0282cd3ef62de4e01" integrity sha512-aiATs7pSutzda/rq8fnuPwTglyVwjM22bNnK2ZgjrpAjQHSSl3lztd2f9evst1W/qnC58DRz7T7QndUDumAR4Q== dependencies: js-yaml "^3.10.0" @@ -3068,14 +3182,14 @@ "@zkochan/js-yaml@0.0.6": version "0.0.6" - resolved "https://registry.npmjs.org/@zkochan/js-yaml/-/js-yaml-0.0.6.tgz" + resolved "https://registry.yarnpkg.com/@zkochan/js-yaml/-/js-yaml-0.0.6.tgz#975f0b306e705e28b8068a07737fa46d3fc04826" integrity sha512-nzvgl3VfhcELQ8LyVrYOru+UtAy1nrygk2+AGbTm8a5YcO6o8lSjAT+pfg3vJWxIoZKOUhrK6UU7xW/+00kQrg== dependencies: argparse "^2.0.1" JSONStream@^1.0.4, JSONStream@^1.3.5: version "1.3.5" - resolved "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz" + resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== dependencies: jsonparse "^1.2.0" @@ -3083,22 +3197,22 @@ JSONStream@^1.0.4, JSONStream@^1.3.5: abbrev@1, abbrev@^1.0.0: version "1.1.1" - resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== abitype@^0.10.3: version "0.10.3" - resolved "https://registry.npmjs.org/abitype/-/abitype-0.10.3.tgz" + resolved "https://registry.yarnpkg.com/abitype/-/abitype-0.10.3.tgz#27ce7a7cdb9a80ccd732a3f3cf1ce6ff05266fce" integrity sha512-tRN+7XIa7J9xugdbRzFv/95ka5ivR/sRe01eiWvM0HWWjHuigSZEACgKa0sj4wGuekTDtghCx+5Izk/cOi78pQ== abstract-logging@^2.0.0: version "2.0.1" - resolved "https://registry.npmjs.org/abstract-logging/-/abstract-logging-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/abstract-logging/-/abstract-logging-2.0.1.tgz#6b0c371df212db7129b57d2e7fcf282b8bf1c839" integrity sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA== accepts@~1.3.8: version "1.3.8" - resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== dependencies: mime-types "~2.1.34" @@ -3110,50 +3224,69 @@ acorn-jsx@^5.3.2: integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== acorn-walk@^8.1.1: - version "8.3.2" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.2.tgz#7703af9415f1b6db9315d6895503862e231d34aa" - integrity sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A== + version "8.3.4" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.4.tgz#794dd169c3977edf4ba4ea47583587c5866236b7" + integrity sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g== + dependencies: + acorn "^8.11.0" -acorn@^8.4.1, acorn@^8.9.0: - version "8.11.3" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" - integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== +acorn@^8.11.0, acorn@^8.4.1, acorn@^8.9.0: + version "8.14.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.1.tgz#721d5dc10f7d5b5609a891773d47731796935dfb" + integrity sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg== add-stream@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa" integrity sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ== -aes-js@3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz" - integrity sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw== +adm-zip@^0.4.16: + version "0.4.16" + resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.16.tgz#cf4c508fdffab02c269cbc7f471a875f05570365" + integrity sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg== + +aes-js@4.0.0-beta.5: + version "4.0.0-beta.5" + resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-4.0.0-beta.5.tgz#8d2452c52adedebc3a3e28465d858c11ca315873" + integrity sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q== agent-base@6, agent-base@^6.0.2: version "6.0.2" - resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== dependencies: debug "4" agentkeepalive@^4.2.1: - version "4.5.0" - resolved "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz" - integrity sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew== + version "4.6.0" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.6.0.tgz#35f73e94b3f40bf65f105219c623ad19c136ea6a" + integrity sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ== dependencies: humanize-ms "^1.2.1" aggregate-error@^3.0.0: version "3.1.0" - resolved "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== dependencies: clean-stack "^2.0.0" indent-string "^4.0.0" +ajv-draft-04@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz#3b64761b268ba0b9e668f0b41ba53fce0ad77fc8" + integrity sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw== + +ajv-formats@~3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-3.0.1.tgz#3d5dc762bca17679c3c2ea7e90ad6b7532309578" + integrity sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ== + dependencies: + ajv "^8.0.0" + ajv@^6.11.0, ajv@^6.12.4, ajv@^6.12.6: version "6.12.6" - resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== dependencies: fast-deep-equal "^3.1.1" @@ -3161,29 +3294,46 @@ ajv@^6.11.0, ajv@^6.12.4, ajv@^6.12.6: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.1, ajv@^8.1.0: - version "8.12.0" - resolved "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz" - integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== +ajv@^8.0.0, ajv@^8.0.1, ajv@^8.1.0: + version "8.17.1" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.17.1.tgz#37d9a5c776af6bc92d7f4f9510eba4c0a60d11a6" + integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g== dependencies: - fast-deep-equal "^3.1.1" + fast-deep-equal "^3.1.3" + fast-uri "^3.0.1" json-schema-traverse "^1.0.0" require-from-string "^2.0.2" - uri-js "^4.2.2" + +ajv@~8.13.0: + version "8.13.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.13.0.tgz#a3939eaec9fb80d217ddf0c3376948c023f28c91" + integrity sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA== + dependencies: + fast-deep-equal "^3.1.3" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.4.1" + +ansi-align@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" + integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w== + dependencies: + string-width "^4.1.0" ansi-colors@^3.2.1: version "3.2.4" - resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== -ansi-colors@^4.1.1: +ansi-colors@^4.1.1, ansi-colors@^4.1.3: version "4.1.3" - resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== -ansi-escapes@^4.2.1: +ansi-escapes@^4.2.1, ansi-escapes@^4.3.0: version "4.3.2" - resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== dependencies: type-fest "^0.21.3" @@ -3195,18 +3345,18 @@ ansi-regex@^2.0.0: ansi-regex@^3.0.0: version "3.0.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1" integrity sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw== ansi-regex@^5.0.1: version "5.0.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== ansi-regex@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz" - integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + version "6.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.1.0.tgz#95ec409c69619d6cb1b8b34f14b660ef28ebd654" + integrity sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA== ansi-styles@^2.2.1: version "2.2.1" @@ -3215,14 +3365,14 @@ ansi-styles@^2.2.1: ansi-styles@^3.2.1: version "3.2.1" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: color-convert "^1.9.0" ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== dependencies: color-convert "^2.0.1" @@ -3232,9 +3382,9 @@ ansi-styles@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== -ansi-styles@^6.1.0: +ansi-styles@^6.1.0, ansi-styles@^6.2.1: version "6.2.1" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== anymatch@^1.3.0: @@ -3245,7 +3395,7 @@ anymatch@^1.3.0: micromatch "^2.1.5" normalize-path "^2.0.0" -anymatch@^3.0.3: +anymatch@^3.0.3, anymatch@~3.1.2: version "3.1.3" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== @@ -3255,29 +3405,29 @@ anymatch@^3.0.3: apisauce@^2.0.1: version "2.1.6" - resolved "https://registry.npmjs.org/apisauce/-/apisauce-2.1.6.tgz" + resolved "https://registry.yarnpkg.com/apisauce/-/apisauce-2.1.6.tgz#94887f335bf3d735305fc895c8a191c9c2608a7f" integrity sha512-MdxR391op/FucS2YQRfB/NMRyCnHEPDd4h17LRIuVYi0BpGmMhpxc0shbOpfs5ahABuBEffNCGal5EcsydbBWg== dependencies: axios "^0.21.4" app-module-path@^2.2.0: version "2.2.0" - resolved "https://registry.npmjs.org/app-module-path/-/app-module-path-2.2.0.tgz" + resolved "https://registry.yarnpkg.com/app-module-path/-/app-module-path-2.2.0.tgz#641aa55dfb7d6a6f0a8141c4b9c0aa50b6c24dd5" integrity sha512-gkco+qxENJV+8vFcDiiFhuoSvRXb2a/QPqpSoWhVz829VNJfOTnELbBmPmNKFxf3xdNnw4DWCkzkDaavcX/1YQ== "aproba@^1.0.3 || ^2.0.0", aproba@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== archy@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" integrity sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw== are-we-there-yet@^3.0.0: version "3.0.1" - resolved "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz#679df222b278c64f2cdba1175cdc00b0d96164bd" integrity sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg== dependencies: delegates "^1.0.0" @@ -3290,14 +3440,14 @@ arg@^4.1.0: argparse@^1.0.7, argparse@~1.0.9: version "1.0.10" - resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== dependencies: sprintf-js "~1.0.2" argparse@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== arr-diff@^2.0.0: @@ -3334,22 +3484,22 @@ array-back@^4.0.1, array-back@^4.0.2: array-differ@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-3.0.0.tgz#3cbb3d0f316810eafcc47624734237d6aee4ae6b" integrity sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg== array-flatten@1.1.1: version "1.1.1" - resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== array-ify@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" integrity sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng== array-union@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== array-unique@^0.2.1: @@ -3364,22 +3514,22 @@ array-unique@^0.3.2: arrify@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" integrity sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA== arrify@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa" integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug== asap@^2.0.0: version "2.0.6" - resolved "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== assert-plus@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== assign-symbols@^1.0.0: @@ -3389,7 +3539,7 @@ assign-symbols@^1.0.0: astral-regex@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== async-each@^1.0.0: @@ -3398,18 +3548,18 @@ async-each@^1.0.0: integrity sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg== async@^3.2.3: - version "3.2.4" - resolved "https://registry.npmjs.org/async/-/async-3.2.4.tgz" - integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== + version "3.2.6" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.6.tgz#1b0728e14929d51b85b449b7f06e27c1145e38ce" + integrity sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA== asynckit@^0.4.0: version "0.4.0" - resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== at-least-node@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== atob@^2.1.2: @@ -3419,12 +3569,12 @@ atob@^2.1.2: atomic-sleep@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b" integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ== avvio@^7.1.2: version "7.2.5" - resolved "https://registry.npmjs.org/avvio/-/avvio-7.2.5.tgz" + resolved "https://registry.yarnpkg.com/avvio/-/avvio-7.2.5.tgz#65ba255f10b0bea7ac6eded71a5344cd88f5de19" integrity sha512-AOhBxyLVdpOad3TujtC9kL/9r3HnTkxwQ5ggOsYrvvZP1cCFvzHWJd5XxZDFuTn+IN8vkKSG5SEJrd27vCSbeA== dependencies: archy "^1.0.0" @@ -3434,14 +3584,14 @@ avvio@^7.1.2: axios@0.26.1: version "0.26.1" - resolved "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.26.1.tgz#1ede41c51fcf51bbbd6fd43669caaa4f0495aaa9" integrity sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA== dependencies: follow-redirects "^1.14.8" axios@1.6.2: version "1.6.2" - resolved "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.2.tgz#de67d42c755b571d3e698df1b6504cde9b0ee9f2" integrity sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A== dependencies: follow-redirects "^1.15.0" @@ -3450,17 +3600,17 @@ axios@1.6.2: axios@^0.21.4: version "0.21.4" - resolved "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== dependencies: follow-redirects "^1.14.0" axios@^1.0.0: - version "1.5.0" - resolved "https://registry.npmjs.org/axios/-/axios-1.5.0.tgz" - integrity sha512-D4DdjDo5CY50Qms0qGQTTw6Q44jl7zRwY7bthds06pUGfChBCTcQs+N743eFWGEd6pRTMd6A+I87aWyFV5wiZQ== + version "1.9.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.9.0.tgz#25534e3b72b54540077d33046f77e3b8d7081901" + integrity sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg== dependencies: - follow-redirects "^1.15.0" + follow-redirects "^1.15.6" form-data "^4.0.0" proxy-from-env "^1.1.0" @@ -3593,22 +3743,25 @@ babel-polyfill@^6.26.0: regenerator-runtime "^0.10.5" babel-preset-current-node-syntax@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" - integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== + version "1.1.0" + resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz#9a929eafece419612ef4ae4f60b1862ebad8ef30" + integrity sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw== dependencies: "@babel/plugin-syntax-async-generators" "^7.8.4" "@babel/plugin-syntax-bigint" "^7.8.3" - "@babel/plugin-syntax-class-properties" "^7.8.3" - "@babel/plugin-syntax-import-meta" "^7.8.3" + "@babel/plugin-syntax-class-properties" "^7.12.13" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + "@babel/plugin-syntax-import-attributes" "^7.24.7" + "@babel/plugin-syntax-import-meta" "^7.10.4" "@babel/plugin-syntax-json-strings" "^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-syntax-numeric-separator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" "@babel/plugin-syntax-object-rest-spread" "^7.8.3" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" "@babel/plugin-syntax-optional-chaining" "^7.8.3" - "@babel/plugin-syntax-top-level-await" "^7.8.3" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/plugin-syntax-top-level-await" "^7.14.5" babel-preset-jest@^29.6.3: version "29.6.3" @@ -3682,24 +3835,24 @@ babylon@^6.18.0: balanced-match@^1.0.0: version "1.0.2" - resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== base-x@^3.0.6: - version "3.0.9" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" - integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== + version "3.0.11" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.11.tgz#40d80e2a1aeacba29792ccc6c5354806421287ff" + integrity sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA== dependencies: safe-buffer "^5.0.1" base-x@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz" - integrity sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw== + version "4.0.1" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-4.0.1.tgz#817fb7b57143c501f649805cb247617ad016a885" + integrity sha512-uAZ8x6r6S3aUM9rbHGVOIsR15U/ZSc82b3ymnCPsT45Gk1DDvhDPdIgB5MrhirZWt+5K0EEPQH985kNqZgNPFw== base64-js@^1.3.1: version "1.5.1" - resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== base@^0.11.1: @@ -3717,24 +3870,19 @@ base@^0.11.1: basic-auth@~2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-2.0.1.tgz#b998279bf47ce38344b4f3cf916d4679bbf51e3a" integrity sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg== dependencies: safe-buffer "5.1.2" -bech32@1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz" - integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== - before-after-hook@^2.1.0, before-after-hook@^2.2.0: version "2.2.3" - resolved "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz" + resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.3.tgz#c51e809c81a4e354084422b9b26bad88249c517c" integrity sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ== bin-links@^3.0.0: version "3.0.3" - resolved "https://registry.npmjs.org/bin-links/-/bin-links-3.0.3.tgz" + resolved "https://registry.yarnpkg.com/bin-links/-/bin-links-3.0.3.tgz#3842711ef3db2cd9f16a5f404a996a12db355a6e" integrity sha512-zKdnMPWEdh4F5INR07/eBrodC7QrF5JKvqskjz/ZZRXg5YSAZIbn8zGhbhUrElzHBZ2fvEQdOU59RHcTG3GiwA== dependencies: cmd-shim "^5.0.0" @@ -3749,21 +3897,26 @@ binary-extensions@^1.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== +binary-extensions@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" + integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== + bindings@^1.5.0: version "1.5.0" - resolved "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== dependencies: file-uri-to-path "1.0.0" bintrees@1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/bintrees/-/bintrees-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/bintrees/-/bintrees-1.0.2.tgz#49f896d6e858a4a499df85c38fb399b9aff840f8" integrity sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw== bl@^4.0.3, bl@^4.1.0: version "4.1.0" - resolved "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== dependencies: buffer "^5.5.0" @@ -3771,18 +3924,18 @@ bl@^4.0.3, bl@^4.1.0: readable-stream "^3.4.0" bn.js@^4.11.9: - version "4.12.0" - resolved "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz" - integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== + version "4.12.2" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.2.tgz#3d8fed6796c24e177737f7cc5172ee04ef39ec99" + integrity sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw== bn.js@^5.2.1: - version "5.2.1" - resolved "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz" - integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== + version "5.2.2" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.2.tgz#82c09f9ebbb17107cd72cb7fd39bd1f9d0aaa566" + integrity sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw== body-parser@1.20.1: version "1.20.1" - resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== dependencies: bytes "3.1.2" @@ -3800,7 +3953,7 @@ body-parser@1.20.1: body-parser@1.20.2: version "1.20.2" - resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== dependencies: bytes "3.1.2" @@ -3816,9 +3969,23 @@ body-parser@1.20.2: type-is "~1.6.18" unpipe "1.0.0" +boxen@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" + integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ== + dependencies: + ansi-align "^3.0.0" + camelcase "^6.2.0" + chalk "^4.1.0" + cli-boxes "^2.2.1" + string-width "^4.2.2" + type-fest "^0.20.2" + widest-line "^3.1.0" + wrap-ansi "^7.0.0" + brace-expansion@^1.1.7: version "1.1.11" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== dependencies: balanced-match "^1.0.0" @@ -3826,7 +3993,7 @@ brace-expansion@^1.1.7: brace-expansion@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== dependencies: balanced-match "^1.0.0" @@ -3856,27 +4023,32 @@ braces@^2.3.1: split-string "^3.0.2" to-regex "^3.0.1" -braces@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== +braces@^3.0.3, braces@~3.0.2: + 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.0.1" + fill-range "^7.1.1" brorand@^1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== -browserslist@^4.22.2: - version "4.23.0" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.0.tgz#8f3acc2bbe73af7213399430890f86c63a5674ab" - integrity sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ== +browser-stdout@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + +browserslist@^4.24.0: + version "4.24.5" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.5.tgz#aa0f5b8560fe81fde84c6dcb38f759bafba0e11b" + integrity sha512-FDToo4Wo82hIdgc1CQ+NQD0hEhmpPjrZ3hiUgwgOG6IuTdlpr8jdjyG24P6cNP1yJpTLzS5OcGgSw0xmDU1/Tw== dependencies: - caniuse-lite "^1.0.30001587" - electron-to-chromium "^1.4.668" - node-releases "^2.0.14" - update-browserslist-db "^1.0.13" + caniuse-lite "^1.0.30001716" + electron-to-chromium "^1.5.149" + node-releases "^2.0.19" + update-browserslist-db "^1.1.3" bs-logger@0.x, bs-logger@^0.2.6: version "0.2.6" @@ -3887,7 +4059,7 @@ bs-logger@0.x, bs-logger@^0.2.6: bs58@5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz" + resolved "https://registry.yarnpkg.com/bs58/-/bs58-5.0.0.tgz#865575b4d13c09ea2a84622df6c8cbeb54ffc279" integrity sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ== dependencies: base-x "^4.0.0" @@ -3901,17 +4073,17 @@ bser@2.1.1: buffer-from@^1.0.0: version "1.1.2" - resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== buffer-writer@2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/buffer-writer/-/buffer-writer-2.0.0.tgz#ce7eb81a38f7829db09c873f2fbb792c0c98ec04" integrity sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw== buffer@^5.5.0: version "5.7.1" - resolved "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== dependencies: base64-js "^1.3.1" @@ -3919,29 +4091,29 @@ buffer@^5.5.0: builtins@^1.0.3: version "1.0.3" - resolved "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz" + resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" integrity sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ== builtins@^5.0.0: - version "5.0.1" - resolved "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz" - integrity sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ== + version "5.1.0" + resolved "https://registry.yarnpkg.com/builtins/-/builtins-5.1.0.tgz#6d85eeb360c4ebc166c3fdef922a15aa7316a5e8" + integrity sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg== dependencies: semver "^7.0.0" byte-size@^7.0.0: version "7.0.1" - resolved "https://registry.npmjs.org/byte-size/-/byte-size-7.0.1.tgz" + resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-7.0.1.tgz#b1daf3386de7ab9d706b941a748dbfc71130dee3" integrity sha512-crQdqyCwhokxwV1UyDzLZanhkugAgft7vt0qbbdt60C6Zf3CAiGmtUCylbtYwrU6loOUw3euGrNtW1J651ot1A== bytes@3.1.2: version "3.1.2" - resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== cacache@^16.0.0, cacache@^16.0.6, cacache@^16.1.0: version "16.1.3" - resolved "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-16.1.3.tgz#a02b9f34ecfaf9a78c9f4bc16fceb94d5d67a38e" integrity sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ== dependencies: "@npmcli/fs" "^2.1.0" @@ -3963,24 +4135,6 @@ cacache@^16.0.0, cacache@^16.0.6, cacache@^16.1.0: tar "^6.1.11" unique-filename "^2.0.0" -cacache@^17.0.0: - version "17.1.4" - resolved "https://registry.npmjs.org/cacache/-/cacache-17.1.4.tgz" - integrity sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A== - dependencies: - "@npmcli/fs" "^3.1.0" - fs-minipass "^3.0.0" - glob "^10.2.2" - lru-cache "^7.7.1" - minipass "^7.0.3" - minipass-collect "^1.0.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - p-map "^4.0.0" - ssri "^10.0.0" - tar "^6.1.11" - unique-filename "^3.0.0" - cache-base@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" @@ -3996,22 +4150,30 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" -call-bind@^1.0.0: +call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6" + integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ== dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" + es-errors "^1.3.0" + function-bind "^1.1.2" + +call-bound@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/call-bound/-/call-bound-1.0.4.tgz#238de935d2a2a692928c538c7ccfa91067fd062a" + integrity sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg== + dependencies: + call-bind-apply-helpers "^1.0.2" + get-intrinsic "^1.3.0" callsites@^3.0.0: version "3.1.0" - resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== camelcase-keys@^6.2.2: version "6.2.2" - resolved "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-6.2.2.tgz#5e755d6ba51aa223ec7d3d52f25778210f9dc3c0" integrity sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg== dependencies: camelcase "^5.3.1" @@ -4020,22 +4182,22 @@ camelcase-keys@^6.2.2: camelcase@^5.0.0, camelcase@^5.3.1: version "5.3.1" - resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -camelcase@^6.2.0: +camelcase@^6.0.0, camelcase@^6.2.0: version "6.3.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001587: - version "1.0.30001616" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001616.tgz#4342712750d35f71ebba9fcac65e2cf8870013c3" - integrity sha512-RHVYKov7IcdNjVHJFNY/78RdG4oGVjbayxv8u5IO74Wv7Hlq4PnJE6mo/OjFijjVFNy5ijnCt6H3IIo4t+wfEw== +caniuse-lite@^1.0.30001716: + version "1.0.30001718" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001718.tgz#dae13a9c80d517c30c6197515a96131c194d8f82" + integrity sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw== chalk@4.1.2, chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.1: version "4.1.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== dependencies: ansi-styles "^4.1.0" @@ -4054,7 +4216,7 @@ chalk@^1.1.3: chalk@^2.4.2: version "2.4.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== dependencies: ansi-styles "^3.2.1" @@ -4063,7 +4225,7 @@ chalk@^2.4.2: chalk@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== dependencies: ansi-styles "^4.1.0" @@ -4076,7 +4238,7 @@ char-regex@^1.0.2: chardet@^0.7.0: version "0.7.0" - resolved "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== chokidar@^1.6.1: @@ -4095,14 +4257,36 @@ chokidar@^1.6.1: optionalDependencies: fsevents "^1.0.0" +chokidar@^3.5.3: + version "3.6.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" + integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chokidar@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-4.0.3.tgz#7be37a4c03c9aee1ecfe862a4a23b2c70c205d30" + integrity sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA== + dependencies: + readdirp "^4.0.1" + chownr@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== ci-info@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== ci-info@^3.2.0: @@ -4111,9 +4295,9 @@ ci-info@^3.2.0: integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== cjs-module-lexer@^1.0.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz#c485341ae8fd999ca4ee5af2d7a1c9ae01e0099c" - integrity sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q== + version "1.4.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz#0f79731eb8cfe1ec72acd4066efac9d61991b00d" + integrity sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q== class-utils@^0.3.5: version "0.3.6" @@ -4127,29 +4311,34 @@ class-utils@^0.3.5: clean-stack@^2.0.0: version "2.2.0" - resolved "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== +cli-boxes@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" + integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== + cli-cursor@3.1.0, cli-cursor@^3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== dependencies: restore-cursor "^3.1.0" cli-spinners@2.6.1: version "2.6.1" - resolved "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.1.tgz#adc954ebe281c37a6319bfa401e6dd2488ffb70d" integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g== cli-spinners@^2.2.0, cli-spinners@^2.5.0: - version "2.9.1" - resolved "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.1.tgz" - integrity sha512-jHgecW0pxkonBJdrKsqxgRX9AcG+u/5k0Q7WPDfi8AogLAdwxEkyYYNWwZ5GvVFoFx2uiY1eNcSK00fh+1+FyQ== + version "2.9.2" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.2.tgz#1773a8f4b9c4d6ac31563df53b3fc1d79462fe41" + integrity sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg== cli-table3@~0.5.0: version "0.5.1" - resolved "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz" + resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202" integrity sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw== dependencies: object-assign "^4.1.0" @@ -4159,12 +4348,12 @@ cli-table3@~0.5.0: cli-width@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== cliui@^7.0.2: version "7.0.4" - resolved "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== dependencies: string-width "^4.2.0" @@ -4173,7 +4362,7 @@ cliui@^7.0.2: cliui@^8.0.1: version "8.0.1" - resolved "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== dependencies: string-width "^4.2.0" @@ -4182,7 +4371,7 @@ cliui@^8.0.1: clone-deep@^4.0.1: version "4.0.1" - resolved "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== dependencies: is-plain-object "^2.0.4" @@ -4191,12 +4380,12 @@ clone-deep@^4.0.1: clone@^1.0.2: version "1.0.4" - resolved "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== cmd-shim@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/cmd-shim/-/cmd-shim-5.0.0.tgz" + resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-5.0.0.tgz#8d0aaa1a6b0708630694c4dbde070ed94c707724" integrity sha512-qkCtZ59BidfEwHltnJwkyVZn+XQojdAySM1D1gSeh11Z4pW1Kpolkyo53L5noc0nrxmIvyFwTmJRo4xs7FFLPw== dependencies: mkdirp-infer-owner "^2.0.0" @@ -4221,46 +4410,41 @@ collection-visit@^1.0.0: color-convert@^1.9.0: version "1.9.3" - resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== dependencies: color-name "1.1.3" color-convert@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== dependencies: color-name "~1.1.4" color-name@1.1.3: version "1.1.3" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== color-name@~1.1.4: version "1.1.4" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== color-support@^1.1.3: version "1.1.3" - resolved "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz" + resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== colors@^1.1.2, colors@^1.3.3: version "1.4.0" - resolved "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== -colors@~1.2.1: - version "1.2.5" - resolved "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz" - integrity sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg== - columnify@^1.6.0: version "1.6.0" - resolved "https://registry.npmjs.org/columnify/-/columnify-1.6.0.tgz" + resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.6.0.tgz#6989531713c9008bb29735e61e37acf5bd553cf3" integrity sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q== dependencies: strip-ansi "^6.0.1" @@ -4268,11 +4452,16 @@ columnify@^1.6.0: combined-stream@^1.0.8: version "1.0.8" - resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== dependencies: delayed-stream "~1.0.0" +command-exists@^1.2.8: + version "1.2.9" + resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.9.tgz#c50725af3808c8ab0260fd60b01fbfa25b954f69" + integrity sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w== + command-line-args@^5.1.1: version "5.2.1" resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.2.1.tgz#c44c32e437a57d7c51157696893c5909e9cec42e" @@ -4295,17 +4484,22 @@ command-line-usage@^6.1.0: commander@^2.11.0, commander@^2.20.3: version "2.20.3" - resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== +commander@^8.1.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" + integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== + common-ancestor-path@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz#4f7d2d1394d91b7abdf51871c62f71eadb0182a7" integrity sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w== compare-func@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/compare-func/-/compare-func-2.0.0.tgz#fb65e75edbddfd2e568554e8b5b05fff7a51fcb3" integrity sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA== dependencies: array-ify "^1.0.0" @@ -4318,12 +4512,12 @@ component-emitter@^1.2.1: concat-map@0.0.1: version "0.0.1" - resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== concat-stream@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-2.0.0.tgz#414cf5af790a48c60ab9be4527d56d5e41133cb1" integrity sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A== dependencies: buffer-from "^1.0.0" @@ -4333,7 +4527,7 @@ concat-stream@^2.0.0: config-chain@^1.1.12: version "1.1.13" - resolved "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz" + resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4" integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ== dependencies: ini "^1.3.4" @@ -4341,31 +4535,24 @@ config-chain@^1.1.12: console-control-strings@^1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== -console-table-printer@^2.11.1: - version "2.11.2" - resolved "https://registry.npmjs.org/console-table-printer/-/console-table-printer-2.11.2.tgz" - integrity sha512-uuUHie0sfPP542TKGzPFal0W1wo1beuKAqIZdaavcONx8OoqdnJRKjkinbRTOta4FaCa1RcIL+7mMJWX3pQGVg== - dependencies: - simple-wcswidth "^1.0.1" - content-disposition@0.5.4: version "0.5.4" - resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== dependencies: safe-buffer "5.2.1" content-type@~1.0.4, content-type@~1.0.5: version "1.0.5" - resolved "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== conventional-changelog-angular@^5.0.12: version "5.0.13" - resolved "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz" + resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz#896885d63b914a70d4934b59d2fe7bde1832b28c" integrity sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA== dependencies: compare-func "^2.0.0" @@ -4373,7 +4560,7 @@ conventional-changelog-angular@^5.0.12: conventional-changelog-core@^4.2.4: version "4.2.4" - resolved "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-4.2.4.tgz" + resolved "https://registry.yarnpkg.com/conventional-changelog-core/-/conventional-changelog-core-4.2.4.tgz#e50d047e8ebacf63fac3dc67bf918177001e1e9f" integrity sha512-gDVS+zVJHE2v4SLc6B0sLsPiloR0ygU7HaDW14aNJE1v4SlqJPILPl/aJC7YdtRE4CybBf8gDwObBvKha8Xlyg== dependencies: add-stream "^1.0.0" @@ -4393,12 +4580,12 @@ conventional-changelog-core@^4.2.4: conventional-changelog-preset-loader@^2.3.4: version "2.3.4" - resolved "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz" + resolved "https://registry.yarnpkg.com/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz#14a855abbffd59027fd602581f1f34d9862ea44c" integrity sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g== conventional-changelog-writer@^5.0.0: version "5.0.1" - resolved "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.1.tgz" + resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-5.0.1.tgz#e0757072f045fe03d91da6343c843029e702f359" integrity sha512-5WsuKUfxW7suLblAbFnxAcrvf6r+0b7GvNaWUwUIk0bXMnENP/PEieGKVUQrjPqwPT4o3EPAASBXiY6iHooLOQ== dependencies: conventional-commits-filter "^2.0.7" @@ -4413,7 +4600,7 @@ conventional-changelog-writer@^5.0.0: conventional-commits-filter@^2.0.7: version "2.0.7" - resolved "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz" + resolved "https://registry.yarnpkg.com/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz#f8d9b4f182fce00c9af7139da49365b136c8a0b3" integrity sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA== dependencies: lodash.ismatch "^4.4.0" @@ -4421,7 +4608,7 @@ conventional-commits-filter@^2.0.7: conventional-commits-parser@^3.2.0: version "3.2.4" - resolved "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz" + resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz#a7d3b77758a202a9b2293d2112a8d8052c740972" integrity sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q== dependencies: JSONStream "^1.0.4" @@ -4433,7 +4620,7 @@ conventional-commits-parser@^3.2.0: conventional-recommended-bump@^6.1.0: version "6.1.0" - resolved "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/conventional-recommended-bump/-/conventional-recommended-bump-6.1.0.tgz#cfa623285d1de554012f2ffde70d9c8a22231f55" integrity sha512-uiApbSiNGM/kkdL9GTOLAqC4hbptObFo4wW2QRyHsKciGAfQuLU1ShZ1BIVI/+K2BE/W1AWYQMCXAsv4dyKPaw== dependencies: concat-stream "^2.0.0" @@ -4457,17 +4644,17 @@ convert-source-map@^2.0.0: cookie-signature@1.0.6: version "1.0.6" - resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== cookie@0.5.0, cookie@^0.5.0: version "0.5.0" - resolved "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== cookie@^0.4.1: version "0.4.2" - resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== copy-descriptor@^0.1.0: @@ -4480,14 +4667,19 @@ core-js@^2.4.0, core-js@^2.5.0: resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== -core-util-is@1.0.2, core-util-is@~1.0.0: +core-util-is@1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + cors@2.8.5: version "2.8.5" - resolved "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== dependencies: object-assign "^4" @@ -4495,7 +4687,7 @@ cors@2.8.5: cosmiconfig@6.0.0: version "6.0.0" - resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== dependencies: "@types/parse-json" "^4.0.0" @@ -4506,7 +4698,7 @@ cosmiconfig@6.0.0: cosmiconfig@^7.0.0: version "7.1.0" - resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6" integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== dependencies: "@types/parse-json" "^4.0.0" @@ -4535,15 +4727,15 @@ create-require@^1.1.0: cross-fetch@4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-4.0.0.tgz#f037aef1580bb3a1a35164ea2a848ba81b445983" integrity sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g== dependencies: node-fetch "^2.6.12" -cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== +cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3, cross-spawn@^7.0.6: + version "7.0.6" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" + integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== dependencies: path-key "^3.1.0" shebang-command "^2.0.0" @@ -4551,36 +4743,36 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: dargs@^7.0.0: version "7.0.0" - resolved "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz" + resolved "https://registry.yarnpkg.com/dargs/-/dargs-7.0.0.tgz#04015c41de0bcb69ec84050f3d9be0caf8d6d5cc" integrity sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg== dateformat@^3.0.0: version "3.0.3" - resolved "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" - resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" -debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4: - version "4.3.4" - resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== +debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@^4.3.5, debug@^4.4.0: + version "4.4.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.1.tgz#e5a8bc6cbc4c6cd3e64308b0693a3d4fa550189b" + integrity sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ== dependencies: - ms "2.1.2" + ms "^2.1.3" debuglog@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" integrity sha512-syBZ+rnAK3EgMsH2aYEOLUW7mZSY9Gb+0wUMCFsZvcmiz+HigA0LOcq/HoQqVuGG+EKykunc7QG2bzrponfaSw== decamelize-keys@^1.1.0: version "1.1.1" - resolved "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz" + resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.1.tgz#04a2d523b2f18d80d0158a43b895d56dff8d19d8" integrity sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg== dependencies: decamelize "^1.1.0" @@ -4588,9 +4780,14 @@ decamelize-keys@^1.1.0: decamelize@^1.1.0, decamelize@^1.2.0: version "1.2.0" - resolved "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== +decamelize@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" + integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== + decode-uri-component@^0.2.0: version "0.2.2" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" @@ -4598,13 +4795,13 @@ decode-uri-component@^0.2.0: dedent@^0.7.0: version "0.7.0" - resolved "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== dedent@^1.0.0: - version "1.5.3" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.5.3.tgz#99aee19eb9bae55a67327717b6e848d0bf777e5a" - integrity sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ== + version "1.6.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.6.0.tgz#79d52d6389b1ffa67d2bcef59ba51847a9d503b2" + integrity sha512-F1Z+5UCFpmQUzJa11agbyPVMbpgT/qA3/SKyJ1jyBgm7dUcUEa8v9JwDkerSQXfakBwFljIxhOJqGkjUwZ9FSA== deep-extend@~0.6.0: version "0.6.0" @@ -4618,19 +4815,19 @@ deep-is@^0.1.3: deepmerge@^4.2.2: version "4.3.1" - resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== defaults@^1.0.3: version "1.0.4" - resolved "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.4.tgz#b0b02062c1e2aa62ff5d9528f0f98baa90978d7a" integrity sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A== dependencies: clone "^1.0.2" define-lazy-prop@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== define-property@^0.2.5: @@ -4657,32 +4854,32 @@ define-property@^2.0.2: delay@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz" + resolved "https://registry.yarnpkg.com/delay/-/delay-5.0.0.tgz#137045ef1b96e5071060dd5be60bf9334436bd1d" integrity sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw== delayed-stream@~1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== delegates@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== depd@2.0.0, depd@~2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== deprecation@^2.0.0: version "2.3.1" - resolved "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz" + resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ== destroy@1.2.0: version "1.2.0" - resolved "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== detect-indent@^4.0.0: @@ -4694,12 +4891,12 @@ detect-indent@^4.0.0: detect-indent@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" integrity sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g== detect-indent@^6.0.0: version "6.1.0" - resolved "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.1.0.tgz#592485ebbbf6b3b1ab2be175c8393d04ca0d57e6" integrity sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA== detect-newline@^3.0.0: @@ -4709,7 +4906,7 @@ detect-newline@^3.0.0: dezalgo@^1.0.0: version "1.0.4" - resolved "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz" + resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.4.tgz#751235260469084c132157dfa857f386d4c33d81" integrity sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig== dependencies: asap "^2.0.0" @@ -4725,9 +4922,14 @@ diff@^4.0.1: resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== +diff@^5.2.0: + version "5.2.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.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== dependencies: path-type "^4.0.0" @@ -4741,86 +4943,88 @@ doctrine@^3.0.0: dom-walk@^0.1.0: version "0.1.2" - resolved "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz" + resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== dot-prop@^5.1.0: version "5.3.0" - resolved "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q== dependencies: is-obj "^2.0.0" dot-prop@^6.0.1: version "6.0.1" - resolved "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-6.0.1.tgz#fc26b3cf142b9e59b74dbd39ed66ce620c681083" integrity sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA== dependencies: is-obj "^2.0.0" dotenv@~10.0.0: version "10.0.0" - resolved "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== dottie@^2.0.6: version "2.0.6" - resolved "https://registry.npmjs.org/dottie/-/dottie-2.0.6.tgz" + resolved "https://registry.yarnpkg.com/dottie/-/dottie-2.0.6.tgz#34564ebfc6ec5e5772272d466424ad5b696484d4" integrity sha512-iGCHkfUc5kFekGiqhe8B/mdaurD+lakO9txNnTvKtA6PISrw86LgqHvRzWYPyoE2Ph5aMIrCw9/uko6XHTKCwA== +dunder-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a" + integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A== + dependencies: + call-bind-apply-helpers "^1.0.1" + es-errors "^1.3.0" + gopd "^1.2.0" + duplexer@^0.1.1: version "0.1.2" - resolved "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== duplexify@^4.1.1, duplexify@^4.1.2: - version "4.1.2" - resolved "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz" - integrity sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw== + version "4.1.3" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-4.1.3.tgz#a07e1c0d0a2c001158563d32592ba58bddb0236f" + integrity sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA== dependencies: end-of-stream "^1.4.1" inherits "^2.0.3" readable-stream "^3.1.1" - stream-shift "^1.0.0" + stream-shift "^1.0.2" eastasianwidth@^0.2.0: version "0.2.0" - resolved "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== ee-first@1.1.1: version "1.1.1" - resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== ejs@^2.6.1: version "2.7.4" - resolved "https://registry.npmjs.org/ejs/-/ejs-2.7.4.tgz" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.4.tgz#48661287573dcc53e366c7a1ae52c3a120eec9ba" integrity sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA== -ejs@^3.1.10: +ejs@^3.1.10, ejs@^3.1.7: version "3.1.10" resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.10.tgz#69ab8358b14e896f80cc39e62087b88500c3ac3b" integrity sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA== dependencies: jake "^10.8.5" -ejs@^3.1.7: - version "3.1.9" - resolved "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz" - integrity sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ== - dependencies: - jake "^10.8.5" +electron-to-chromium@^1.5.149: + version "1.5.155" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.155.tgz#809dd0ae9ae1db87c358e0c0c17c09a2ffc432d1" + integrity sha512-ps5KcGGmwL8VaeJlvlDlu4fORQpv3+GIcF5I3f9tUKUlJ/wsysh6HU8P5L1XWRYeXfA0oJd4PyM8ds8zTFf6Ng== -electron-to-chromium@^1.4.668: - version "1.4.758" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.758.tgz#f39e530cae2ca4329a0f0e1840629d8d1da73156" - integrity sha512-/o9x6TCdrYZBMdGeTifAP3wlF/gVT+TtWJe3BSmtNh92Mw81U9hrYwW9OAGUh+sEOX/yz5e34sksqRruZbjYrw== - -elliptic@6.5.4: - version "6.5.4" - resolved "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz" - integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== +elliptic@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.6.1.tgz#3b8ffb02670bf69e382c7f65bf524c97c5405c06" + integrity sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g== dependencies: bn.js "^4.11.9" brorand "^1.1.0" @@ -4832,7 +5036,7 @@ elliptic@6.5.4: emittery@^0.10.0: version "0.10.2" - resolved "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.10.2.tgz#902eec8aedb8c41938c46e9385e9db7e03182933" integrity sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw== emittery@^0.13.1: @@ -4840,101 +5044,136 @@ emittery@^0.13.1: resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== +emoji-regex@^10.3.0: + version "10.4.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-10.4.0.tgz#03553afea80b3975749cfcb36f776ca268e413d4" + integrity sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw== + emoji-regex@^8.0.0: version "8.0.0" - resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== emoji-regex@^9.2.2: version "9.2.2" - resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== encodeurl@~1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== encoding@^0.1.13: version "0.1.13" - resolved "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== dependencies: iconv-lite "^0.6.2" end-of-stream@^1.1.0, end-of-stream@^1.4.1: version "1.4.4" - resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== dependencies: once "^1.4.0" enquirer@2.3.4: version "2.3.4" - resolved "https://registry.npmjs.org/enquirer/-/enquirer-2.3.4.tgz" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.4.tgz#c608f2e1134c7f68c1c9ee056de13f9b31076de9" integrity sha512-pkYrrDZumL2VS6VBGDhqbajCM2xpkUNLuKfGPjfKaSIBKYopQbqEFyrOkRMIb2HDR/rO1kGhEt/5twBwtzKBXw== dependencies: ansi-colors "^3.2.1" +enquirer@^2.3.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.4.1.tgz#93334b3fbd74fc7097b224ab4a8fb7e40bf4ae56" + integrity sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ== + dependencies: + ansi-colors "^4.1.1" + strip-ansi "^6.0.1" + enquirer@~2.3.6: version "2.3.6" - resolved "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== dependencies: ansi-colors "^4.1.1" env-paths@2.2.1, env-paths@^2.2.0: version "2.2.1" - resolved "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz" + resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== envinfo@^7.7.4: - version "7.10.0" - resolved "https://registry.npmjs.org/envinfo/-/envinfo-7.10.0.tgz" - integrity sha512-ZtUjZO6l5mwTHvc1L9+1q5p/R3wTopcfqMW8r5t8SJSKqeVI/LtajORwRFEKpEFuekjD0VBjwu1HMxL4UalIRw== + version "7.14.0" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.14.0.tgz#26dac5db54418f2a4c1159153a0b2ae980838aae" + integrity sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg== err-code@^2.0.2: version "2.0.3" - resolved "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz" + resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== error-ex@^1.3.1: version "1.3.2" - resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== dependencies: is-arrayish "^0.2.1" +es-define-property@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa" + integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g== + +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + +es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz#1c4f2c4837327597ce69d2ca190a7fdd172338c1" + integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA== + dependencies: + es-errors "^1.3.0" + +es-set-tostringtag@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz#f31dbbe0c183b00a6d26eb6325c810c0fd18bd4d" + integrity sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA== + dependencies: + es-errors "^1.3.0" + get-intrinsic "^1.2.6" + has-tostringtag "^1.0.2" + hasown "^2.0.2" + es6-promise@^4.0.3: version "4.2.8" - resolved "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== es6-promisify@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz" + resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" integrity sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ== dependencies: es6-promise "^4.0.3" -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escalade@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" - integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA== +escalade@^3.1.1, escalade@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" + integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== escape-html@~1.0.3: version "1.0.3" - resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== escape-string-regexp@^2.0.0: @@ -4970,7 +5209,7 @@ eslint-scope@^7.2.2: esrecurse "^4.3.0" estraverse "^5.2.0" -eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: +eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: 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== @@ -5073,13 +5312,13 @@ espree@^9.6.0, espree@^9.6.1: esprima@^4.0.0: version "4.0.1" - resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esquery@^1.4.2: - version "1.5.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" - integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== + version "1.6.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.6.0.tgz#91419234f804d852a82dceec3e16cdc22cf9dae7" + integrity sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg== dependencies: estraverse "^5.1.0" @@ -5102,53 +5341,50 @@ esutils@^2.0.2: etag@~1.8.1: version "1.8.1" - resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== -ethers@5.7.0, ethers@^5.6.0: - version "5.7.0" - resolved "https://registry.npmjs.org/ethers/-/ethers-5.7.0.tgz" - integrity sha512-5Xhzp2ZQRi0Em+0OkOcRHxPzCfoBfgtOQA+RUylSkuHbhTEaQklnYi2hsWbRgs3ztJsXVXd9VKBcO1ScWL8YfA== - dependencies: - "@ethersproject/abi" "5.7.0" - "@ethersproject/abstract-provider" "5.7.0" - "@ethersproject/abstract-signer" "5.7.0" - "@ethersproject/address" "5.7.0" - "@ethersproject/base64" "5.7.0" - "@ethersproject/basex" "5.7.0" - "@ethersproject/bignumber" "5.7.0" - "@ethersproject/bytes" "5.7.0" - "@ethersproject/constants" "5.7.0" - "@ethersproject/contracts" "5.7.0" - "@ethersproject/hash" "5.7.0" - "@ethersproject/hdnode" "5.7.0" - "@ethersproject/json-wallets" "5.7.0" - "@ethersproject/keccak256" "5.7.0" - "@ethersproject/logger" "5.7.0" - "@ethersproject/networks" "5.7.0" - "@ethersproject/pbkdf2" "5.7.0" - "@ethersproject/properties" "5.7.0" - "@ethersproject/providers" "5.7.0" - "@ethersproject/random" "5.7.0" - "@ethersproject/rlp" "5.7.0" - "@ethersproject/sha2" "5.7.0" - "@ethersproject/signing-key" "5.7.0" - "@ethersproject/solidity" "5.7.0" - "@ethersproject/strings" "5.7.0" - "@ethersproject/transactions" "5.7.0" - "@ethersproject/units" "5.7.0" - "@ethersproject/wallet" "5.7.0" - "@ethersproject/web" "5.7.0" - "@ethersproject/wordlists" "5.7.0" +ethereum-cryptography@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz#5ccfa183e85fdaf9f9b299a79430c044268c9b3a" + integrity sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw== + dependencies: + "@noble/hashes" "1.2.0" + "@noble/secp256k1" "1.7.1" + "@scure/bip32" "1.1.5" + "@scure/bip39" "1.1.1" + +ethereum-cryptography@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz#58f2810f8e020aecb97de8c8c76147600b0b8ccf" + integrity sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg== + dependencies: + "@noble/curves" "1.4.2" + "@noble/hashes" "1.4.0" + "@scure/bip32" "1.4.0" + "@scure/bip39" "1.3.0" + +ethers@6.13.7: + version "6.13.7" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.13.7.tgz#7457fcb32413b441a3ee6e9f4cd63bf782de6226" + integrity sha512-qbaJ0uIrjh+huP1Lad2f2QtzW5dcqSVjIzVH6yWB4dKoMuj2WqYz5aMeeQTCNpAKgTJBM5J9vcc2cYJ23UAimQ== + dependencies: + "@adraffy/ens-normalize" "1.10.1" + "@noble/curves" "1.2.0" + "@noble/hashes" "1.3.2" + "@types/node" "22.7.5" + aes-js "4.0.0-beta.5" + tslib "2.7.0" + ws "8.17.1" eventemitter3@^4.0.4: version "4.0.7" - resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== evt@1.10.1: version "1.10.1" - resolved "https://registry.npmjs.org/evt/-/evt-1.10.1.tgz" + resolved "https://registry.yarnpkg.com/evt/-/evt-1.10.1.tgz#2f25b6f9588f4a8951aa541d968e2d5d1ea94fd8" integrity sha512-0vkCFzH3Q2Qb9gs3yav4p3uu+l4mcIfKPTRFTO1WHYZd0+O/ZR7BgzpuF+FbqOJ6r9q20/sDL/5TQM+de0/hyg== dependencies: minimal-polyfills "^2.1.5" @@ -5156,7 +5392,7 @@ evt@1.10.1: evt@1.9.12: version "1.9.12" - resolved "https://registry.npmjs.org/evt/-/evt-1.9.12.tgz" + resolved "https://registry.yarnpkg.com/evt/-/evt-1.9.12.tgz#8d06177259cbcb09ef936e18945bf7ddd087170c" integrity sha512-u8wC4Xif2pcDJ9cEm0wzWCIQb+Y214m1eUgsgm2hVIuXuvC6LToryA0Ecl1O8Slii2E9l6USLsyxXWntjlnIbw== dependencies: minimal-polyfills "^2.1.5" @@ -5164,7 +5400,7 @@ evt@1.9.12: execa@^3.0.0: version "3.4.0" - resolved "https://registry.npmjs.org/execa/-/execa-3.4.0.tgz" + resolved "https://registry.yarnpkg.com/execa/-/execa-3.4.0.tgz#c08ed4550ef65d858fac269ffc8572446f37eb89" integrity sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g== dependencies: cross-spawn "^7.0.0" @@ -5180,7 +5416,7 @@ execa@^3.0.0: execa@^5.0.0: version "5.1.1" - resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== dependencies: cross-spawn "^7.0.3" @@ -5237,13 +5473,13 @@ expect@^29.0.0, expect@^29.7.0: jest-util "^29.7.0" exponential-backoff@^3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz" - integrity sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw== + version "3.1.2" + resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.2.tgz#a8f26adb96bf78e8cd8ad1037928d5e5c0679d91" + integrity sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA== express@4.18.2: version "4.18.2" - resolved "https://registry.npmjs.org/express/-/express-4.18.2.tgz" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== dependencies: accepts "~1.3.8" @@ -5295,7 +5531,7 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: external-editor@^3.0.3: version "3.1.0" - resolved "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== dependencies: chardet "^0.7.0" @@ -5325,27 +5561,27 @@ extglob@^2.0.4: extsprintf@^1.2.0: version "1.4.1" - resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== eyes@^0.1.8: version "0.1.8" - resolved "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz" + resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" integrity sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ== fast-decode-uri-component@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz#46f8b6c22b30ff7a81357d4f59abfae938202543" integrity sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg== fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" - resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" + 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.7: version "3.2.7" - resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1" integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q== dependencies: "@nodelib/fs.stat" "^2.0.2" @@ -5355,24 +5591,24 @@ fast-glob@3.2.7: micromatch "^4.0.4" fast-glob@^3.2.9: - version "3.3.1" - resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz" - integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== + version "3.3.3" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.3.tgz#d06d585ce8dba90a16b0505c543c3ccfb3aeb818" + integrity sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg== 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" + micromatch "^4.0.8" fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== fast-json-stringify@^2.5.2: version "2.7.13" - resolved "https://registry.npmjs.org/fast-json-stringify/-/fast-json-stringify-2.7.13.tgz" + resolved "https://registry.yarnpkg.com/fast-json-stringify/-/fast-json-stringify-2.7.13.tgz#277aa86c2acba4d9851bd6108ed657aa327ed8c0" integrity sha512-ar+hQ4+OIurUGjSJD1anvYSDcUflywhKjfxnsW4TBTD7+u0tJufv6DKRWoQk3vI6YBOWMoz0TQtfbe7dxbQmvA== dependencies: ajv "^6.11.0" @@ -5386,28 +5622,33 @@ fast-levenshtein@^2.0.6: integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== fast-redact@^3.0.0: - version "3.3.0" - resolved "https://registry.npmjs.org/fast-redact/-/fast-redact-3.3.0.tgz" - integrity sha512-6T5V1QK1u4oF+ATxs1lWUmlEk6P2T9HqJG3e2DnHOdVgZy2rFJBoEnrIedcTXlkAHU/zKC+7KETJ+KGGKwxgMQ== + version "3.5.0" + resolved "https://registry.yarnpkg.com/fast-redact/-/fast-redact-3.5.0.tgz#e9ea02f7e57d0cd8438180083e93077e496285e4" + integrity sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A== fast-safe-stringify@^2.0.8: version "2.1.1" - resolved "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz" + resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884" integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA== +fast-uri@^3.0.1: + version "3.0.6" + resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.0.6.tgz#88f130b77cfaea2378d56bf970dea21257a68748" + integrity sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw== + fastify-error@^0.3.0: version "0.3.1" - resolved "https://registry.npmjs.org/fastify-error/-/fastify-error-0.3.1.tgz" + resolved "https://registry.yarnpkg.com/fastify-error/-/fastify-error-0.3.1.tgz#8eb993e15e3cf57f0357fc452af9290f1c1278d2" integrity sha512-oCfpcsDndgnDVgiI7bwFKAun2dO+4h84vBlkWsWnz/OUK9Reff5UFoFl241xTiLeHWX/vU9zkDVXqYUxjOwHcQ== fastify-warning@^0.2.0: version "0.2.0" - resolved "https://registry.npmjs.org/fastify-warning/-/fastify-warning-0.2.0.tgz" + resolved "https://registry.yarnpkg.com/fastify-warning/-/fastify-warning-0.2.0.tgz#e717776026a4493dc9a2befa44db6d17f618008f" integrity sha512-s1EQguBw/9qtc1p/WTY4eq9WMRIACkj+HTcOIK1in4MV5aFaQC9ZCIt0dJ7pr5bIf4lPpHvAtP2ywpTNgs7hqw== fastify@3.25.0: version "3.25.0" - resolved "https://registry.npmjs.org/fastify/-/fastify-3.25.0.tgz" + resolved "https://registry.yarnpkg.com/fastify/-/fastify-3.25.0.tgz#04b682fa738c6468bc36efba9f1e943609502111" integrity sha512-GblpjS7yuJ9jpkz1guHTyzlVQn9NYvGrMkDLtoxctEt7n1d6MSwA9i3p10HjNiY+zVurPf3YdOqXsJmVgAR3cg== dependencies: "@fastify/ajv-compiler" "^1.0.0" @@ -5427,9 +5668,9 @@ fastify@3.25.0: tiny-lru "^7.0.0" fastq@^1.6.0, fastq@^1.6.1: - version "1.15.0" - resolved "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz" - integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== + version "1.19.1" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.19.1.tgz#d50eaba803c8846a883c16492821ebcd2cda55f5" + integrity sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ== dependencies: reusify "^1.0.4" @@ -5440,9 +5681,14 @@ fb-watchman@^2.0.0: dependencies: bser "2.1.1" +fdir@^6.4.4: + version "6.4.4" + resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.4.4.tgz#1cfcf86f875a883e19a8fab53622cfe992e8d2f9" + integrity sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg== + figures@3.2.0, figures@^3.0.0: version "3.2.0" - resolved "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz" + resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== dependencies: escape-string-regexp "^1.0.5" @@ -5456,12 +5702,12 @@ file-entry-cache@^6.0.1: file-uri-to-path@1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== filelist@^1.0.4: version "1.0.4" - resolved "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz" + resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== dependencies: minimatch "^5.0.1" @@ -5492,16 +5738,16 @@ fill-range@^4.0.0: repeat-string "^1.6.1" to-regex-range "^2.1.0" -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== +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.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== dependencies: debug "2.6.9" @@ -5514,7 +5760,7 @@ finalhandler@1.2.0: find-my-way@^4.1.0: version "4.5.1" - resolved "https://registry.npmjs.org/find-my-way/-/find-my-way-4.5.1.tgz" + resolved "https://registry.yarnpkg.com/find-my-way/-/find-my-way-4.5.1.tgz#758e959194b90aea0270db18fff75e2fceb2239f" integrity sha512-kE0u7sGoUFbMXcOG/xpkmz4sRLCklERnBcg7Ftuu1iAxsfEt2S46RLJ3Sq7vshsEy2wJT2hZxE58XZK27qa8kg== dependencies: fast-decode-uri-component "^1.0.1" @@ -5531,14 +5777,14 @@ find-replace@^3.0.0: find-up@^2.0.0: version "2.1.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" integrity sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ== dependencies: locate-path "^2.0.0" find-up@^4.0.0, find-up@^4.1.0: version "4.1.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== dependencies: locate-path "^5.0.0" @@ -5563,23 +5809,23 @@ flat-cache@^3.0.4: flat@^5.0.2: version "5.0.2" - resolved "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== flatstr@^1.0.12: version "1.0.12" - resolved "https://registry.npmjs.org/flatstr/-/flatstr-1.0.12.tgz" + resolved "https://registry.yarnpkg.com/flatstr/-/flatstr-1.0.12.tgz#c2ba6a08173edbb6c9640e3055b95e287ceb5931" integrity sha512-4zPxDyhCyiN2wIAtSLI6gc82/EjqZc1onI4Mz/l0pWrAlsSfYH/2ZIcU+e3oA2wDwbzIWNKwa23F8rh6+DRWkw== flatted@^3.2.9: - version "3.3.1" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a" - integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw== + version "3.3.3" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.3.tgz#67c8fad95454a7c7abebf74bb78ee74a44023358" + integrity sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg== -follow-redirects@^1.14.0, follow-redirects@^1.14.8, follow-redirects@^1.15.0: - version "1.15.2" - resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz" - integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== +follow-redirects@^1.12.1, follow-redirects@^1.14.0, follow-redirects@^1.14.8, follow-redirects@^1.15.0, follow-redirects@^1.15.6: + version "1.15.9" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.9.tgz#a604fa10e443bf98ca94228d9eebcc2e8a2c8ee1" + integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ== for-in@^1.0.1, for-in@^1.0.2: version "1.0.2" @@ -5594,27 +5840,38 @@ for-own@^0.1.4: for-in "^1.0.1" foreground-child@^3.1.0: - version "3.1.1" - resolved "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz" - integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== + version "3.3.1" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.1.tgz#32e8e9ed1b68a3497befb9ac2b6adf92a638576f" + integrity sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw== dependencies: - cross-spawn "^7.0.0" + cross-spawn "^7.0.6" signal-exit "^4.0.1" form-data@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz" - integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + version "4.0.2" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.2.tgz#35cabbdd30c3ce73deb2c42d3c8d3ed9ca51794c" + integrity sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w== dependencies: asynckit "^0.4.0" combined-stream "^1.0.8" + es-set-tostringtag "^2.1.0" mime-types "^2.1.12" forwarded@0.2.0: version "0.2.0" - resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== +fp-ts@1.19.3: + version "1.19.3" + resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.3.tgz#261a60d1088fbff01f91256f91d21d0caaaaa96f" + integrity sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg== + +fp-ts@^1.0.0: + version "1.19.5" + resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.5.tgz#3da865e585dfa1fdfd51785417357ac50afc520a" + integrity sha512-wDNqTimnzs8QqpldiId9OavWK2NptormjXnRJTQecNjzwfyp6P/8s/zG8e4h3ja3oqkKaY72UlTjQYt/1yXf9A== + fragment-cache@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" @@ -5624,24 +5881,24 @@ fragment-cache@^0.2.1: fresh@0.5.2: version "0.5.2" - resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== fs-constants@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== -fs-extra@^11.1.0: - version "11.1.1" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz" - integrity sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ== +fs-extra@^11.1.0, fs-extra@~11.3.0: + version "11.3.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.3.0.tgz#0daced136bbaf65a555a326719af931adc7a314d" + integrity sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew== dependencies: graceful-fs "^4.2.0" jsonfile "^6.0.1" universalify "^2.0.0" -fs-extra@^7.0.0: +fs-extra@^7.0.0, fs-extra@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== @@ -5652,7 +5909,7 @@ fs-extra@^7.0.0: fs-extra@^9.1.0: version "9.1.0" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== dependencies: at-least-node "^1.0.0" @@ -5662,7 +5919,7 @@ fs-extra@^9.1.0: fs-jetpack@^2.2.2: version "2.4.0" - resolved "https://registry.npmjs.org/fs-jetpack/-/fs-jetpack-2.4.0.tgz" + resolved "https://registry.yarnpkg.com/fs-jetpack/-/fs-jetpack-2.4.0.tgz#6080c4ab464a019d37a404baeb47f32af8835026" integrity sha512-S/o9Dd7K9A7gicVU32eT8G0kHcmSu0rCVdP79P0MWInKFb8XpTc8Syhoo66k9no+HDshtlh4pUJTws8X+8fdFQ== dependencies: minimatch "^3.0.2" @@ -5670,7 +5927,7 @@ fs-jetpack@^2.2.2: fs-jetpack@^4.1.0: version "4.3.1" - resolved "https://registry.npmjs.org/fs-jetpack/-/fs-jetpack-4.3.1.tgz" + resolved "https://registry.yarnpkg.com/fs-jetpack/-/fs-jetpack-4.3.1.tgz#cdfd4b64e6bfdec7c7dc55c76b39efaa7853bb20" integrity sha512-dbeOK84F6BiQzk2yqqCVwCPWTxAvVGJ3fMQc6E2wuEohS28mR6yHngbrKuVCK1KHRx/ccByDylqu4H5PCP2urQ== dependencies: minimatch "^3.0.2" @@ -5678,18 +5935,11 @@ fs-jetpack@^4.1.0: fs-minipass@^2.0.0, fs-minipass@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== dependencies: minipass "^3.0.0" -fs-minipass@^3.0.0: - version "3.0.3" - resolved "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz" - integrity sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw== - dependencies: - minipass "^7.0.3" - fs-readdir-recursive@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" @@ -5697,7 +5947,7 @@ fs-readdir-recursive@^1.0.0: fs.realpath@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== fsevents@^1.0.0: @@ -5708,19 +5958,19 @@ fsevents@^1.0.0: bindings "^1.5.0" nan "^2.12.1" -fsevents@^2.3.2: +fsevents@^2.3.2, fsevents@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== -function-bind@^1.1.1, function-bind@^1.1.2: +function-bind@^1.1.2: version "1.1.2" - resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== gauge@^4.0.3: version "4.0.4" - resolved "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-4.0.4.tgz#52ff0652f2bbf607a989793d53b751bef2328dce" integrity sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg== dependencies: aproba "^1.0.3 || ^2.0.0" @@ -5739,18 +5989,29 @@ gensync@^1.0.0-beta.2: get-caller-file@^2.0.5: version "2.0.5" - resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.2: - version "1.2.1" - resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz" - integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== +get-east-asian-width@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz#21b4071ee58ed04ee0db653371b55b4299875389" + integrity sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ== + +get-intrinsic@^1.2.5, get-intrinsic@^1.2.6, get-intrinsic@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01" + integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ== dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-proto "^1.0.1" - has-symbols "^1.0.3" + call-bind-apply-helpers "^1.0.2" + es-define-property "^1.0.1" + es-errors "^1.3.0" + es-object-atoms "^1.1.1" + function-bind "^1.1.2" + get-proto "^1.0.1" + gopd "^1.2.0" + has-symbols "^1.1.0" + hasown "^2.0.2" + math-intrinsics "^1.1.0" get-package-type@^0.1.0: version "0.1.0" @@ -5759,7 +6020,7 @@ get-package-type@^0.1.0: get-pkg-repo@^4.0.0: version "4.2.1" - resolved "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz" + resolved "https://registry.yarnpkg.com/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz#75973e1c8050c73f48190c52047c4cee3acbf385" integrity sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA== dependencies: "@hutson/parse-repository-url" "^3.0.0" @@ -5769,19 +6030,27 @@ get-pkg-repo@^4.0.0: get-port@^5.1.1: version "5.1.1" - resolved "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz" + resolved "https://registry.yarnpkg.com/get-port/-/get-port-5.1.1.tgz#0469ed07563479de6efb986baf053dcd7d4e3193" integrity sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ== +get-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1" + integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g== + dependencies: + dunder-proto "^1.0.1" + es-object-atoms "^1.0.0" + get-stream@^5.0.0: version "5.2.0" - resolved "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== dependencies: pump "^3.0.0" get-stream@^6.0.0: version "6.0.1" - resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== get-value@^2.0.3, get-value@^2.0.6: @@ -5791,7 +6060,7 @@ get-value@^2.0.3, get-value@^2.0.6: git-raw-commits@^2.0.8: version "2.0.11" - resolved "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz" + resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-2.0.11.tgz#bc3576638071d18655e1cc60d7f524920008d723" integrity sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A== dependencies: dargs "^7.0.0" @@ -5802,7 +6071,7 @@ git-raw-commits@^2.0.8: git-remote-origin-url@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz#5282659dae2107145a11126112ad3216ec5fa65f" integrity sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw== dependencies: gitconfiglocal "^1.0.0" @@ -5810,7 +6079,7 @@ git-remote-origin-url@^2.0.0: git-semver-tags@^4.1.1: version "4.1.1" - resolved "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-4.1.1.tgz" + resolved "https://registry.yarnpkg.com/git-semver-tags/-/git-semver-tags-4.1.1.tgz#63191bcd809b0ec3e151ba4751c16c444e5b5780" integrity sha512-OWyMt5zBe7xFs8vglMmhM9lRQzCWL3WjHtxNNfJTMngGym7pC1kh8sP6jevfydJ6LP3ZvGxfb6ABYgPUM0mtsA== dependencies: meow "^8.0.0" @@ -5818,22 +6087,22 @@ git-semver-tags@^4.1.1: git-up@^7.0.0: version "7.0.0" - resolved "https://registry.npmjs.org/git-up/-/git-up-7.0.0.tgz" + resolved "https://registry.yarnpkg.com/git-up/-/git-up-7.0.0.tgz#bace30786e36f56ea341b6f69adfd83286337467" integrity sha512-ONdIrbBCFusq1Oy0sC71F5azx8bVkvtZtMJAsv+a6lz5YAmbNnLD6HAB4gptHZVLPR8S2/kVN6Gab7lryq5+lQ== dependencies: is-ssh "^1.4.0" parse-url "^8.1.0" git-url-parse@^13.1.0: - version "13.1.0" - resolved "https://registry.npmjs.org/git-url-parse/-/git-url-parse-13.1.0.tgz" - integrity sha512-5FvPJP/70WkIprlUZ33bm4UAaFdjcLkJLpWft1BeZKqwR0uhhNGoKwlUaPtVb4LxCSQ++erHapRak9kWGj+FCA== + version "13.1.1" + resolved "https://registry.yarnpkg.com/git-url-parse/-/git-url-parse-13.1.1.tgz#664bddf0857c6a75b3c1f0ae6239abb08a1486d4" + integrity sha512-PCFJyeSSdtnbfhSNRw9Wk96dDCNx+sogTe4YNXeXSJxt7xz5hvXekuRn9JX7m+Mf4OscCu8h+mtAl3+h5Fo8lQ== dependencies: git-up "^7.0.0" gitconfiglocal@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz#41d045f3851a5ea88f03f24ca1c6178114464b9b" integrity sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ== dependencies: ini "^1.3.2" @@ -5853,9 +6122,9 @@ glob-parent@^2.0.0: dependencies: is-glob "^2.0.0" -glob-parent@^5.1.1, glob-parent@^5.1.2: +glob-parent@^5.1.1, glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" @@ -5869,7 +6138,7 @@ glob-parent@^6.0.2: glob@7.1.4: version "7.1.4" - resolved "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== dependencies: fs.realpath "^1.0.0" @@ -5891,20 +6160,21 @@ glob@7.1.7: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^10.2.2: - version "10.3.4" - resolved "https://registry.npmjs.org/glob/-/glob-10.3.4.tgz" - integrity sha512-6LFElP3A+i/Q8XQKEvZjkEWEOTgAIALR9AO2rwT8bgPhDd1anmqDJDZ6lLddI4ehxxxR1S5RIqKe1uapMQfYaQ== +glob@^11.0.1: + version "11.0.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-11.0.2.tgz#3261e3897bbc603030b041fd77ba636022d51ce0" + integrity sha512-YT7U7Vye+t5fZ/QMkBFrTJ7ZQxInIUjwyAjVj84CYXqgBdv30MFUPGnBR6sQaVq6Is15wYJUsnzTuWaGRBhBAQ== dependencies: foreground-child "^3.1.0" - jackspeak "^2.0.3" - minimatch "^9.0.1" - minipass "^5.0.0 || ^6.0.2 || ^7.0.0" - path-scurry "^1.10.1" + jackspeak "^4.0.1" + minimatch "^10.0.0" + minipass "^7.1.2" + package-json-from-dist "^1.0.0" + path-scurry "^2.0.0" glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: version "7.2.3" - resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== dependencies: fs.realpath "^1.0.0" @@ -5914,9 +6184,9 @@ glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^8.0.1: +glob@^8.0.1, glob@^8.1.0: version "8.1.0" - resolved "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz" + resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== dependencies: fs.realpath "^1.0.0" @@ -5927,7 +6197,7 @@ glob@^8.0.1: global@4.4.0: version "4.4.0" - resolved "https://registry.npmjs.org/global/-/global-4.4.0.tgz" + resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w== dependencies: min-document "^2.19.0" @@ -5952,7 +6222,7 @@ globals@^9.18.0: globby@^11.0.2, globby@^11.1.0: version "11.1.0" - resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== dependencies: array-union "^2.1.0" @@ -5964,7 +6234,7 @@ globby@^11.0.2, globby@^11.1.0: gluegun@4.7.0: version "4.7.0" - resolved "https://registry.npmjs.org/gluegun/-/gluegun-4.7.0.tgz" + resolved "https://registry.yarnpkg.com/gluegun/-/gluegun-4.7.0.tgz#d1e88828ec6737d966619fff07c04f7e689dc59e" integrity sha512-St+J/rly0FoWLeISgBGDuymwF3/b8OdmxBCbSvK1hXEoRbaaATiRpPepJSJWuRYR7cGR7Hy9drgQwGFBAolhbQ== dependencies: apisauce "^2.0.1" @@ -5999,9 +6269,14 @@ gluegun@4.7.0: which "^2.0.0" yargs-parser "^16.1.0" +gopd@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1" + integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== + graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.4, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.6, graceful-fs@^4.2.9: version "4.2.11" - resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz" + 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: @@ -6011,19 +6286,19 @@ graphemer@^1.4.0: graphql-tag@2.12.6: version "2.12.6" - resolved "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz" + resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.12.6.tgz#d441a569c1d2537ef10ca3d1633b48725329b5f1" integrity sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg== dependencies: tslib "^2.1.0" graphql@16.8.0: version "16.8.0" - resolved "https://registry.npmjs.org/graphql/-/graphql-16.8.0.tgz" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.8.0.tgz#374478b7f27b2dc6153c8f42c1b80157f79d79d4" integrity sha512-0oKGaR+y3qcS5mCu1vb7KG+a89vjn06C7Ihq/dDl3jA+A8B3TKomvi3CiEcVLJQGalbu8F52LxkOym7U5sSfbg== handlebars@^4.7.7: version "4.7.8" - resolved "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.8.tgz#41c42c18b1be2365439188c77c6afae71c0cd9e9" integrity sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ== dependencies: minimist "^1.2.5" @@ -6035,9 +6310,56 @@ handlebars@^4.7.7: hard-rejection@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/hard-rejection/-/hard-rejection-2.1.0.tgz#1c6eda5c1685c63942766d79bb40ae773cecd883" integrity sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA== +hardhat@^2.22.16: + version "2.24.0" + resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.24.0.tgz#33dbe8c3972c2d2db6206966e19466571a937932" + integrity sha512-wDkD5GPmttYv21MR7tGDkyQ22tO2V86OEV8pA7NcXWYUpibe8XZ2EanXCeRHO61vwEx0f7/M+NqrhJwasaNMJg== + dependencies: + "@ethereumjs/util" "^9.1.0" + "@ethersproject/abi" "^5.1.2" + "@nomicfoundation/edr" "^0.11.0" + "@nomicfoundation/solidity-analyzer" "^0.1.0" + "@sentry/node" "^5.18.1" + "@types/bn.js" "^5.1.0" + "@types/lru-cache" "^5.1.0" + adm-zip "^0.4.16" + aggregate-error "^3.0.0" + ansi-escapes "^4.3.0" + boxen "^5.1.2" + chokidar "^4.0.0" + ci-info "^2.0.0" + debug "^4.1.1" + enquirer "^2.3.0" + env-paths "^2.2.0" + ethereum-cryptography "^1.0.3" + find-up "^5.0.0" + fp-ts "1.19.3" + fs-extra "^7.0.1" + immutable "^4.0.0-rc.12" + io-ts "1.10.4" + json-stream-stringify "^3.1.4" + keccak "^3.0.2" + lodash "^4.17.11" + micro-eth-signer "^0.14.0" + mnemonist "^0.38.0" + mocha "^10.0.0" + p-map "^4.0.0" + picocolors "^1.1.0" + raw-body "^2.4.1" + resolve "1.17.0" + semver "^6.3.0" + solc "0.8.26" + source-map-support "^0.5.13" + stacktrace-parser "^0.1.10" + tinyglobby "^0.2.6" + tsort "0.0.1" + undici "^5.14.0" + uuid "^8.3.2" + ws "^7.4.6" + has-ansi@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" @@ -6047,27 +6369,29 @@ has-ansi@^2.0.0: has-flag@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== has-flag@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-proto@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz" - integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== +has-symbols@^1.0.3, has-symbols@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338" + integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== -has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== +has-tostringtag@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" + integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== + dependencies: + has-symbols "^1.0.3" has-unicode@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== has-value@^0.3.1: @@ -6101,36 +6425,34 @@ has-values@^1.0.0: is-number "^3.0.0" kind-of "^4.0.0" -has@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3: version "1.1.7" - resolved "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== dependencies: inherits "^2.0.3" minimalistic-assert "^1.0.1" -hasown@^2.0.0: +hasown@^2.0.0, hasown@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== dependencies: function-bind "^1.1.2" +he@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + helmet@7.0.0: version "7.0.0" - resolved "https://registry.npmjs.org/helmet/-/helmet-7.0.0.tgz" + resolved "https://registry.yarnpkg.com/helmet/-/helmet-7.0.0.tgz#ac3011ba82fa2467f58075afa58a49427ba6212d" integrity sha512-MsIgYmdBh460ZZ8cJC81q4XJknjG567wzEmv46WOBblDb6TUd3z8/GhgmsM9pn8g2B80tAJ4m5/d3Bi1KrSUBQ== hmac-drbg@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== dependencies: hash.js "^1.0.3" @@ -6147,26 +6469,26 @@ home-or-tmp@^2.0.0: hosted-git-info@^2.1.4: version "2.8.9" - resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== hosted-git-info@^3.0.6: version "3.0.8" - resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.8.tgz" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-3.0.8.tgz#6e35d4cc87af2c5f816e4cb9ce350ba87a3f370d" integrity sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw== dependencies: lru-cache "^6.0.0" hosted-git-info@^4.0.0, hosted-git-info@^4.0.1: version "4.1.0" - resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.1.0.tgz#827b82867e9ff1c8d0c4d9d53880397d2c86d224" integrity sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA== dependencies: lru-cache "^6.0.0" hosted-git-info@^5.0.0: version "5.2.1" - resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-5.2.1.tgz" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-5.2.1.tgz#0ba1c97178ef91f3ab30842ae63d6a272341156f" integrity sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw== dependencies: lru-cache "^7.5.1" @@ -6176,14 +6498,14 @@ html-escaper@^2.0.0: resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== -http-cache-semantics@^4.1.0, http-cache-semantics@^4.1.1: - version "4.1.1" - resolved "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz" - integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== +http-cache-semantics@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz#205f4db64f8562b76a4ff9235aa5279839a09dd5" + integrity sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ== http-errors@2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== dependencies: depd "2.0.0" @@ -6194,7 +6516,7 @@ http-errors@2.0.0: http-proxy-agent@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== dependencies: "@tootallnate/once" "2" @@ -6203,7 +6525,7 @@ http-proxy-agent@^5.0.0: https-proxy-agent@^5.0.0: version "5.0.1" - resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== dependencies: agent-base "6" @@ -6211,96 +6533,101 @@ https-proxy-agent@^5.0.0: human-signals@^1.1.1: version "1.1.1" - resolved "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== human-signals@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== humanize-ms@^1.2.1: version "1.2.1" - resolved "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz" + 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" iconv-lite@0.4.24, iconv-lite@^0.4.24: version "0.4.24" - resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== dependencies: safer-buffer ">= 2.1.2 < 3" iconv-lite@^0.6.2: version "0.6.3" - resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== dependencies: safer-buffer ">= 2.1.2 < 3.0.0" ieee754@^1.1.13: version "1.2.1" - resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== ignore-walk@^5.0.1: version "5.0.1" - resolved "https://registry.npmjs.org/ignore-walk/-/ignore-walk-5.0.1.tgz" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-5.0.1.tgz#5f199e23e1288f518d90358d461387788a154776" integrity sha512-yemi4pMf51WKT7khInJqAvsIGzoqYXblnsz0ql8tM+yi1EKYTY1evX4NAbJrLL/Aanr2HyZeluqU+Oi7MGHokw== dependencies: minimatch "^5.0.1" -ignore@^5.0.4, ignore@^5.2.0: - version "5.2.4" - resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz" - integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== +ignore@^5.0.4, ignore@^5.2.0, ignore@^5.2.4: + version "5.3.2" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" + integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== -ignore@^5.2.4: - version "5.3.1" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" - integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== +immutable@^4.0.0-rc.12: + version "4.3.7" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.7.tgz#c70145fc90d89fb02021e65c84eb0226e4e5a381" + integrity sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw== import-fresh@^3.1.0, import-fresh@^3.2.1: - version "3.3.0" - resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + version "3.3.1" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.1.tgz#9cecb56503c0ada1f2741dbbd6546e4b13b57ccf" + integrity sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ== dependencies: parent-module "^1.0.0" resolve-from "^4.0.0" +import-lazy@~4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-4.0.0.tgz#e8eb627483a0a43da3c03f3e35548be5cb0cc153" + integrity sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw== + import-local@^3.0.2: - version "3.1.0" - resolved "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz" - integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== + version "3.2.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.2.0.tgz#c3d5c745798c02a6f8b897726aba5100186ee260" + integrity sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA== dependencies: pkg-dir "^4.2.0" resolve-cwd "^3.0.0" imurmurhash@^0.1.4: version "0.1.4" - resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== indent-string@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== infer-owner@^1.0.4: version "1.0.4" - resolved "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz" + resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== inflection@^1.13.4: version "1.13.4" - resolved "https://registry.npmjs.org/inflection/-/inflection-1.13.4.tgz" + resolved "https://registry.yarnpkg.com/inflection/-/inflection-1.13.4.tgz#65aa696c4e2da6225b148d7a154c449366633a32" integrity sha512-6I/HUDeYFfuNCVS3td055BaXBwKYuzw7K3ExVMStBowKo9oOAMJIXIHvdyR3iboTCp1b+1i5DSkIZTcwIktuDw== inflight@^1.0.4: version "1.0.6" - resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== dependencies: once "^1.3.0" @@ -6308,17 +6635,17 @@ inflight@^1.0.4: inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: version "2.0.4" - resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== ini@^1.3.2, ini@^1.3.4: version "1.3.8" - resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== init-package-json@^3.0.2: version "3.0.2" - resolved "https://registry.npmjs.org/init-package-json/-/init-package-json-3.0.2.tgz" + resolved "https://registry.yarnpkg.com/init-package-json/-/init-package-json-3.0.2.tgz#f5bc9bac93f2bdc005778bc2271be642fecfcd69" integrity sha512-YhlQPEjNFqlGdzrBfDNRLhvoSgX7iQRgSxgsNknRQ9ITXFT7UMfVMWhBTOh2Y+25lRnGrv5Xz8yZwQ3ACR6T3A== dependencies: npm-package-arg "^9.0.1" @@ -6331,7 +6658,7 @@ init-package-json@^3.0.2: inquirer@^8.2.4: version "8.2.6" - resolved "https://registry.npmjs.org/inquirer/-/inquirer-8.2.6.tgz" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.6.tgz#733b74888195d8d400a67ac332011b5fae5ea562" integrity sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg== dependencies: ansi-escapes "^4.2.1" @@ -6357,14 +6684,24 @@ invariant@^2.2.2: dependencies: loose-envify "^1.0.0" -ip@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz" - integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ== +io-ts@1.10.4: + version "1.10.4" + resolved "https://registry.yarnpkg.com/io-ts/-/io-ts-1.10.4.tgz#cd5401b138de88e4f920adbcb7026e2d1967e6e2" + integrity sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g== + dependencies: + fp-ts "^1.0.0" + +ip-address@^9.0.5: + version "9.0.5" + resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-9.0.5.tgz#117a960819b08780c3bd1f14ef3c1cc1d3f3ea5a" + integrity sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g== + dependencies: + jsbn "1.1.0" + sprintf-js "^1.1.3" ipaddr.js@1.9.1: version "1.9.1" - resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== is-accessor-descriptor@^1.0.1: @@ -6376,7 +6713,7 @@ is-accessor-descriptor@^1.0.1: is-arrayish@^0.2.1: version "0.2.1" - resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== is-binary-path@^1.0.0: @@ -6386,6 +6723,13 @@ is-binary-path@^1.0.0: dependencies: binary-extensions "^1.0.0" +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" @@ -6393,17 +6737,17 @@ is-buffer@^1.1.5: is-ci@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== dependencies: ci-info "^2.0.0" -is-core-module@^2.13.0, is-core-module@^2.5.0, is-core-module@^2.8.1: - version "2.13.0" - resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz" - integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== +is-core-module@^2.16.0, is-core-module@^2.5.0, is-core-module@^2.8.1: + version "2.16.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4" + integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w== dependencies: - has "^1.0.3" + hasown "^2.0.2" is-data-descriptor@^1.0.1: version "1.0.1" @@ -6430,7 +6774,7 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2: is-docker@^2.0.0, is-docker@^2.1.1: version "2.2.1" - resolved "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== is-dotfile@^1.0.0: @@ -6464,7 +6808,7 @@ is-extglob@^1.0.0: is-extglob@^2.1.1: version "2.1.1" - resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== is-finite@^1.0.0: @@ -6474,12 +6818,12 @@ is-finite@^1.0.0: is-fullwidth-code-point@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" integrity sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w== is-fullwidth-code-point@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" + 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-generator-fn@^2.0.0: @@ -6494,21 +6838,21 @@ is-glob@^2.0.0, is-glob@^2.0.1: dependencies: is-extglob "^1.0.0" -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: +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.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== dependencies: is-extglob "^2.1.1" is-interactive@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== is-lambda@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ== is-number@^2.1.0: @@ -6532,12 +6876,12 @@ is-number@^4.0.0: is-number@^7.0.0: version "7.0.0" - resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== is-obj@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== is-path-inside@^3.0.3: @@ -6547,24 +6891,24 @@ is-path-inside@^3.0.3: is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" integrity sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg== -is-plain-obj@^2.0.0: +is-plain-obj@^2.0.0, is-plain-obj@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" - resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== dependencies: isobject "^3.0.1" is-plain-object@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== is-posix-bracket@^0.1.0: @@ -6578,32 +6922,32 @@ is-primitive@^2.0.0: integrity sha512-N3w1tFaRfk3UrPfqeRyD+GYDASU3W5VinKhlORy8EWVf/sIdDL9GAcew85XmktCfH+ngG7SRXEVDoO18WMdB/Q== is-ssh@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/is-ssh/-/is-ssh-1.4.0.tgz" - integrity sha512-x7+VxdxOdlV3CYpjvRLBv5Lo9OJerlYanjwFrPR9fuGPjCiNiCzFgAWpiLAohSbsnH4ZAys3SBh+hq5rJosxUQ== + version "1.4.1" + resolved "https://registry.yarnpkg.com/is-ssh/-/is-ssh-1.4.1.tgz#76de1cdbe8f92a8b905d1a172b6bc09704c20396" + integrity sha512-JNeu1wQsHjyHgn9NcWTaXq6zWSR6hqE0++zhfZlkFBbScNkyvxCdeV8sRkSBaeLKxmbpR21brail63ACNxJ0Tg== dependencies: protocols "^2.0.1" is-stream@^2.0.0: version "2.0.1" - resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== is-text-path@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/is-text-path/-/is-text-path-1.0.1.tgz#4e1aa0fb51bfbcb3e92688001397202c1775b66e" integrity sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w== dependencies: text-extensions "^1.0.0" is-typedarray@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== is-unicode-supported@^0.1.0: version "0.1.0" - resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== is-windows@^1.0.2: @@ -6613,19 +6957,19 @@ is-windows@^1.0.2: is-wsl@^2.2.0: version "2.2.0" - resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== dependencies: is-docker "^2.0.0" isarray@1.0.0, isarray@~1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== isexe@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== isobject@^2.0.0: @@ -6637,12 +6981,12 @@ isobject@^2.0.0: isobject@^3.0.0, isobject@^3.0.1: version "3.0.1" - resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== isomorphic-fetch@3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz#0267b005049046d2421207215d45d6a262b8b8b4" integrity sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA== dependencies: node-fetch "^2.6.1" @@ -6650,7 +6994,7 @@ isomorphic-fetch@3.0.0: isomorphic-ws@^4.0.1: version "4.0.1" - resolved "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz" + resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: @@ -6670,9 +7014,9 @@ istanbul-lib-instrument@^5.0.4: semver "^6.3.0" istanbul-lib-instrument@^6.0.0: - version "6.0.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.2.tgz#91655936cf7380e4e473383081e38478b69993b1" - integrity sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw== + version "6.0.3" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz#fa15401df6c15874bcb2105f773325d78c666765" + integrity sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q== dependencies: "@babel/core" "^7.23.9" "@babel/parser" "^7.23.9" @@ -6706,19 +7050,17 @@ istanbul-reports@^3.1.3: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -jackspeak@^2.0.3: - version "2.3.3" - resolved "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.3.tgz" - integrity sha512-R2bUw+kVZFS/h1AZqBKrSgDmdmjApzgY0AlCPumopFiAlbUxE2gf+SCuBzQ0cP5hHmUmFYF5yw55T97Th5Kstg== +jackspeak@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-4.1.0.tgz#c489c079f2b636dc4cbe9b0312a13ff1282e561b" + integrity sha512-9DDdhb5j6cpeitCbvLO7n7J4IxnbM6hoF6O1g4HQ5TfhvvKN8ywDM7668ZhMHRqVmxqhps/F6syWK2KcPxYlkw== dependencies: "@isaacs/cliui" "^8.0.2" - optionalDependencies: - "@pkgjs/parseargs" "^0.11.0" jake@^10.8.5: - version "10.8.7" - resolved "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz" - integrity sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w== + version "10.9.2" + resolved "https://registry.yarnpkg.com/jake/-/jake-10.9.2.tgz#6ae487e6a69afec3a5e167628996b59f35ae2b7f" + integrity sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA== dependencies: async "^3.2.3" chalk "^4.0.2" @@ -6727,7 +7069,7 @@ jake@^10.8.5: jayson@3.6.6: version "3.6.6" - resolved "https://registry.npmjs.org/jayson/-/jayson-3.6.6.tgz" + resolved "https://registry.yarnpkg.com/jayson/-/jayson-3.6.6.tgz#189984f624e398f831bd2be8e8c80eb3abf764a1" integrity sha512-f71uvrAWTtrwoww6MKcl9phQTC+56AopLyEenWvKVAIMz+q0oVGj6tenLZ7Z6UiPBkJtKLj4kt0tACllFQruGQ== dependencies: "@types/connect" "^3.4.33" @@ -7104,14 +7446,19 @@ jest@<30.0.0-0: import-local "^3.0.2" jest-cli "^29.7.0" +jju@~1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/jju/-/jju-1.4.0.tgz#a3abe2718af241a2b2904f84a625970f389ae32a" + integrity sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA== + js-sha3@0.8.0, js-sha3@^0.8.0: version "0.8.0" - resolved "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz" + resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== js-tokens@^3.0.2: @@ -7121,28 +7468,33 @@ js-tokens@^3.0.2: js-yaml@4.1.0, js-yaml@^4.1.0: version "4.1.0" - resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== dependencies: argparse "^2.0.1" js-yaml@^3.10.0, js-yaml@^3.13.1: version "3.14.1" - resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== dependencies: argparse "^1.0.7" esprima "^4.0.0" +jsbn@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-1.1.0.tgz#b01307cb29b618a1ed26ec79e911f803c4da0040" + integrity sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A== + jsesc@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" integrity sha512-Mke0DA0QjUWuJlhsE0ZPPhYiJkRap642SmI/4ztCFaUs6V2AiH1sfecc+57NgaryfAA2VR3v6O+CSjC1jZJKOA== -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== +jsesc@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d" + integrity sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA== json-buffer@3.0.1: version "3.0.1" @@ -7151,22 +7503,22 @@ json-buffer@3.0.1: json-parse-better-errors@^1.0.1: version "1.0.2" - resolved "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: version "2.3.1" - resolved "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== json-schema-traverse@^0.4.1: version "0.4.1" - resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== json-schema-traverse@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== json-stable-stringify-without-jsonify@^1.0.1: @@ -7174,14 +7526,19 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== +json-stream-stringify@^3.1.4: + version "3.1.6" + resolved "https://registry.yarnpkg.com/json-stream-stringify/-/json-stream-stringify-3.1.6.tgz#ebe32193876fb99d4ec9f612389a8d8e2b5d54d4" + integrity sha512-x7fpwxOkbhFCaJDJ8vb1fBY3DdSa4AlITaz+HHILQJzdPMnHEFjxPwVUi1ALIbcIxDE0PNe/0i7frnY8QnBQog== + json-stringify-nice@^1.1.4: version "1.1.4" - resolved "https://registry.npmjs.org/json-stringify-nice/-/json-stringify-nice-1.1.4.tgz" + resolved "https://registry.yarnpkg.com/json-stringify-nice/-/json-stringify-nice-1.1.4.tgz#2c937962b80181d3f317dd39aa323e14f5a60a67" integrity sha512-5Z5RFW63yxReJ7vANgW6eZFGWaQvnPE3WNmZoOJrSkGju2etKA2L5rrOa1sm877TVTFt57A80BH1bArcmlLfPw== json-stringify-safe@^5.0.1: version "5.0.1" - resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== json5@^0.5.1: @@ -7191,12 +7548,12 @@ json5@^0.5.1: json5@^2.2.2, json5@^2.2.3: version "2.2.3" - resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== jsonc-parser@3.2.0: version "3.2.0" - resolved "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w== jsonfile@^4.0.0: @@ -7208,7 +7565,7 @@ jsonfile@^4.0.0: jsonfile@^6.0.1: version "6.1.0" - resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== dependencies: universalify "^2.0.0" @@ -7217,19 +7574,28 @@ jsonfile@^6.0.1: jsonparse@^1.2.0, jsonparse@^1.3.1: version "1.3.1" - resolved "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz" + resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== just-diff-apply@^5.2.0: version "5.5.0" - resolved "https://registry.npmjs.org/just-diff-apply/-/just-diff-apply-5.5.0.tgz" + resolved "https://registry.yarnpkg.com/just-diff-apply/-/just-diff-apply-5.5.0.tgz#771c2ca9fa69f3d2b54e7c3f5c1dfcbcc47f9f0f" integrity sha512-OYTthRfSh55WOItVqwpefPtNt2VdKsq5AnAK6apdtR6yCH8pr0CmSr710J0Mf+WdQy7K/OzMy7K2MgAfdQURDw== just-diff@^5.0.1: version "5.2.0" - resolved "https://registry.npmjs.org/just-diff/-/just-diff-5.2.0.tgz" + resolved "https://registry.yarnpkg.com/just-diff/-/just-diff-5.2.0.tgz#60dca55891cf24cd4a094e33504660692348a241" integrity sha512-6ufhP9SHjb7jibNFrNxyFZ6od3g+An6Ai9mhGRvcYe8UJlH0prseN64M+6ZBBUoKYHZsitDP42gAJ8+eVWr3lw== +keccak@^3.0.2: + version "3.0.4" + resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.4.tgz#edc09b89e633c0549da444432ecf062ffadee86d" + integrity sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q== + dependencies: + node-addon-api "^2.0.0" + node-gyp-build "^4.2.0" + readable-stream "^3.6.0" + keyv@^4.5.3: version "4.5.4" resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" @@ -7253,7 +7619,7 @@ kind-of@^4.0.0: kind-of@^6.0.0, kind-of@^6.0.2, kind-of@^6.0.3: version "6.0.3" - resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== kleur@^3.0.3: @@ -7263,7 +7629,7 @@ kleur@^3.0.3: lerna@6.1.0: version "6.1.0" - resolved "https://registry.npmjs.org/lerna/-/lerna-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/lerna/-/lerna-6.1.0.tgz#693145393ec22fd3ca98d817deab2246c1e2b107" integrity sha512-3qAjIj8dgBwHtCAiLbq4VU/C1V9D1tvTLm2owZubdGAN72aB5TxuCu2mcw+yeEorOcXuR9YWx7EXIkAf+G0N2w== dependencies: "@lerna/add" "6.1.0" @@ -7305,7 +7671,7 @@ levn@^0.4.1: libnpmaccess@^6.0.3: version "6.0.4" - resolved "https://registry.npmjs.org/libnpmaccess/-/libnpmaccess-6.0.4.tgz" + resolved "https://registry.yarnpkg.com/libnpmaccess/-/libnpmaccess-6.0.4.tgz#2dd158bd8a071817e2207d3b201d37cf1ad6ae6b" integrity sha512-qZ3wcfIyUoW0+qSFkMBovcTrSGJ3ZeyvpR7d5N9pEYv/kXs8sHP2wiqEIXBKLFrZlmM0kR0RJD7mtfLngtlLag== dependencies: aproba "^2.0.0" @@ -7315,7 +7681,7 @@ libnpmaccess@^6.0.3: libnpmpublish@^6.0.4: version "6.0.5" - resolved "https://registry.npmjs.org/libnpmpublish/-/libnpmpublish-6.0.5.tgz" + resolved "https://registry.yarnpkg.com/libnpmpublish/-/libnpmpublish-6.0.5.tgz#5a894f3de2e267d62f86be2a508e362599b5a4b1" integrity sha512-LUR08JKSviZiqrYTDfywvtnsnxr+tOvBU0BF8H+9frt7HMvc6Qn6F8Ubm72g5hDTHbq8qupKfDvDAln2TVPvFg== dependencies: normalize-package-data "^4.0.0" @@ -7326,7 +7692,7 @@ libnpmpublish@^6.0.4: light-my-request@^4.2.0: version "4.12.0" - resolved "https://registry.npmjs.org/light-my-request/-/light-my-request-4.12.0.tgz" + resolved "https://registry.yarnpkg.com/light-my-request/-/light-my-request-4.12.0.tgz#fd59329a7b4f794842103c7bef69e12252478831" integrity sha512-0y+9VIfJEsPVzK5ArSIJ8Dkxp8QMP7/aCuxCUtG/tr9a2NoOf/snATE/OUc05XUplJCEnRh6gTkH7xh9POt1DQ== dependencies: ajv "^8.1.0" @@ -7336,17 +7702,17 @@ light-my-request@^4.2.0: lines-and-columns@^1.1.6: version "1.2.4" - resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== lines-and-columns@~2.0.3: - version "2.0.3" - resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.3.tgz" - integrity sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w== + version "2.0.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-2.0.4.tgz#d00318855905d2660d8c0822e3f5a4715855fc42" + integrity sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A== load-json-file@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" integrity sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw== dependencies: graceful-fs "^4.1.2" @@ -7356,7 +7722,7 @@ load-json-file@^4.0.0: load-json-file@^6.2.0: version "6.2.0" - resolved "https://registry.npmjs.org/load-json-file/-/load-json-file-6.2.0.tgz" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-6.2.0.tgz#5c7770b42cafa97074ca2848707c61662f4251a1" integrity sha512-gUD/epcRms75Cw8RT1pUdHugZYM5ce64ucs2GEISABwkRsOQr0q2wm/MV2TKThycIe5e0ytRweW2RZxclogCdQ== dependencies: graceful-fs "^4.1.15" @@ -7366,7 +7732,7 @@ load-json-file@^6.2.0: locate-path@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" integrity sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA== dependencies: p-locate "^2.0.0" @@ -7374,7 +7740,7 @@ locate-path@^2.0.0: locate-path@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== dependencies: p-locate "^4.1.0" @@ -7388,47 +7754,47 @@ locate-path@^6.0.0: lodash.camelcase@^4.3.0: version "4.3.0" - resolved "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== lodash.clonedeep@^4.5.0: version "4.5.0" - resolved "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== lodash.groupby@^4.6.0: version "4.6.0" - resolved "https://registry.npmjs.org/lodash.groupby/-/lodash.groupby-4.6.0.tgz" + resolved "https://registry.yarnpkg.com/lodash.groupby/-/lodash.groupby-4.6.0.tgz#0b08a1dcf68397c397855c3239783832df7403d1" integrity sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw== -lodash.isequal@4.5.0: +lodash.isequal@4.5.0, lodash.isequal@^4.5.0: version "4.5.0" - resolved "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ== lodash.ismatch@^4.4.0: version "4.4.0" - resolved "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz" + resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37" integrity sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g== lodash.kebabcase@^4.1.1: version "4.1.1" - resolved "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz" + resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36" integrity sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g== lodash.lowercase@^4.3.0: version "4.3.0" - resolved "https://registry.npmjs.org/lodash.lowercase/-/lodash.lowercase-4.3.0.tgz" + resolved "https://registry.yarnpkg.com/lodash.lowercase/-/lodash.lowercase-4.3.0.tgz#46515aced4acb0b7093133333af068e4c3b14e9d" integrity sha512-UcvP1IZYyDKyEL64mmrwoA1AbFu5ahojhTtkOUr1K9dbuxzS9ev8i4TxMMGCqRC9TE8uDaSoufNAXxRPNTseVA== lodash.lowerfirst@^4.3.1: version "4.3.1" - resolved "https://registry.npmjs.org/lodash.lowerfirst/-/lodash.lowerfirst-4.3.1.tgz" + resolved "https://registry.yarnpkg.com/lodash.lowerfirst/-/lodash.lowerfirst-4.3.1.tgz#de3c7b12e02c6524a0059c2f6cb7c5c52655a13d" integrity sha512-UUKX7VhP1/JL54NXg2aq/E1Sfnjjes8fNYTNkPU8ZmsaVeBvPHKdbNaN79Re5XRL01u6wbq3j0cbYZj71Fcu5w== lodash.mapvalues@^4.6.0: version "4.6.0" - resolved "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz" + resolved "https://registry.yarnpkg.com/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz#1bafa5005de9dd6f4f26668c30ca37230cc9689c" integrity sha512-JPFqXFeZQ7BfS00H58kClY7SPVeHertPE0lNuCyZ26/XlN8TvakYD7b9bGyNmXbT/D3BbtPAAmq90gPWqLkxlQ== lodash.memoize@4.x, lodash.memoize@^4.1.2: @@ -7443,101 +7809,111 @@ lodash.merge@^4.6.2: lodash.pad@^4.5.1: version "4.5.1" - resolved "https://registry.npmjs.org/lodash.pad/-/lodash.pad-4.5.1.tgz" + resolved "https://registry.yarnpkg.com/lodash.pad/-/lodash.pad-4.5.1.tgz#4330949a833a7c8da22cc20f6a26c4d59debba70" integrity sha512-mvUHifnLqM+03YNzeTBS1/Gr6JRFjd3rRx88FHWUvamVaT9k2O/kXha3yBSOwB9/DTQrSTLJNHvLBBt2FdX7Mg== lodash.padend@^4.6.1: version "4.6.1" - resolved "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz" + resolved "https://registry.yarnpkg.com/lodash.padend/-/lodash.padend-4.6.1.tgz#53ccba047d06e158d311f45da625f4e49e6f166e" integrity sha512-sOQs2aqGpbl27tmCS1QNZA09Uqp01ZzWfDUoD+xzTii0E7dSQfRKcRetFwa+uXaxaqL+TKm7CgD2JdKP7aZBSw== lodash.padstart@^4.6.1: version "4.6.1" - resolved "https://registry.npmjs.org/lodash.padstart/-/lodash.padstart-4.6.1.tgz" + resolved "https://registry.yarnpkg.com/lodash.padstart/-/lodash.padstart-4.6.1.tgz#d2e3eebff0d9d39ad50f5cbd1b52a7bce6bb611b" integrity sha512-sW73O6S8+Tg66eY56DBk85aQzzUJDtpoXFBgELMd5P/SotAguo+1kYO6RuYgXxA4HJH3LFTFPASX6ET6bjfriw== lodash.repeat@^4.1.0: version "4.1.0" - resolved "https://registry.npmjs.org/lodash.repeat/-/lodash.repeat-4.1.0.tgz" + resolved "https://registry.yarnpkg.com/lodash.repeat/-/lodash.repeat-4.1.0.tgz#fc7de8131d8c8ac07e4b49f74ffe829d1f2bec44" integrity sha512-eWsgQW89IewS95ZOcr15HHCX6FVDxq3f2PNUIng3fyzsPev9imFQxIYdFZ6crl8L56UR6ZlGDLcEb3RZsCSSqw== lodash.snakecase@^4.1.1: version "4.1.1" - resolved "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz" + resolved "https://registry.yarnpkg.com/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz#39d714a35357147837aefd64b5dcbb16becd8f8d" integrity sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw== lodash.startcase@^4.4.0: version "4.4.0" - resolved "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz" + resolved "https://registry.yarnpkg.com/lodash.startcase/-/lodash.startcase-4.4.0.tgz#9436e34ed26093ed7ffae1936144350915d9add8" integrity sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg== lodash.trim@^4.5.1: version "4.5.1" - resolved "https://registry.npmjs.org/lodash.trim/-/lodash.trim-4.5.1.tgz" + resolved "https://registry.yarnpkg.com/lodash.trim/-/lodash.trim-4.5.1.tgz#36425e7ee90be4aa5e27bcebb85b7d11ea47aa57" integrity sha512-nJAlRl/K+eiOehWKDzoBVrSMhK0K3A3YQsUNXHQa5yIrKBAhsZgSu3KoAFoFT+mEgiyBHddZ0pRk1ITpIp90Wg== lodash.trimend@^4.5.1: version "4.5.1" - resolved "https://registry.npmjs.org/lodash.trimend/-/lodash.trimend-4.5.1.tgz" + resolved "https://registry.yarnpkg.com/lodash.trimend/-/lodash.trimend-4.5.1.tgz#12804437286b98cad8996b79414e11300114082f" integrity sha512-lsD+k73XztDsMBKPKvzHXRKFNMohTjoTKIIo4ADLn5dA65LZ1BqlAvSXhR2rPEC3BgAUQnzMnorqDtqn2z4IHA== lodash.trimstart@^4.5.1: version "4.5.1" - resolved "https://registry.npmjs.org/lodash.trimstart/-/lodash.trimstart-4.5.1.tgz" + resolved "https://registry.yarnpkg.com/lodash.trimstart/-/lodash.trimstart-4.5.1.tgz#8ff4dec532d82486af59573c39445914e944a7f1" integrity sha512-b/+D6La8tU76L/61/aN0jULWHkT0EeJCmVstPBn/K9MtD2qBW83AsBNrr63dKuWYwVMO7ucv13QNO/Ek/2RKaQ== lodash.truncate@^4.4.2: version "4.4.2" - resolved "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz" + resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw== lodash.uppercase@^4.3.0: version "4.3.0" - resolved "https://registry.npmjs.org/lodash.uppercase/-/lodash.uppercase-4.3.0.tgz" + resolved "https://registry.yarnpkg.com/lodash.uppercase/-/lodash.uppercase-4.3.0.tgz#c404abfd1469f93931f9bb24cf6cc7d57059bc73" integrity sha512-+Nbnxkj7s8K5U8z6KnEYPGUOGp3woZbB7Ecs7v3LkkjLQSm2kP9SKIILitN1ktn2mB/tmM9oSlku06I+/lH7QA== lodash.upperfirst@^4.3.1: version "4.3.1" - resolved "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz" + resolved "https://registry.yarnpkg.com/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz#1365edf431480481ef0d1c68957a5ed99d49f7ce" integrity sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg== lodash.xor@^4.5.0: version "4.5.0" - resolved "https://registry.npmjs.org/lodash.xor/-/lodash.xor-4.5.0.tgz" + resolved "https://registry.yarnpkg.com/lodash.xor/-/lodash.xor-4.5.0.tgz#4d48ed7e98095b0632582ba714d3ff8ae8fb1db6" integrity sha512-sVN2zimthq7aZ5sPGXnSz32rZPuqcparVW50chJQe+mzTYV+IsxSsl/2gnkWWE2Of7K3myBQBqtLKOUEHJKRsQ== lodash.zip@^4.2.0: version "4.2.0" - resolved "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz" + resolved "https://registry.yarnpkg.com/lodash.zip/-/lodash.zip-4.2.0.tgz#ec6662e4896408ed4ab6c542a3990b72cc080020" integrity sha512-C7IOaBBK/0gMORRBd8OETNx3kmOkgIWIPvyDpZSCTwUrpYmgZwJkjZeOD8ww4xbOUOs4/attY+pciKvadNfFbg== -lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4: +lodash@^4.17.11, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4: version "4.17.21" - resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== log-symbols@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4" integrity sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ== dependencies: chalk "^2.4.2" log-symbols@^4.1.0: version "4.1.0" - resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== dependencies: chalk "^4.1.0" is-unicode-supported "^0.1.0" +long@^5.0.0: + version "5.2.4" + resolved "https://registry.yarnpkg.com/long/-/long-5.2.4.tgz#ee651d5c7c25901cfca5e67220ae9911695e99b2" + integrity sha512-qtzLbJE8hq7VabR3mISmVGtoXP8KGc2Z/AT8OuqlYD7JTR3oqrgwdjnk07wpj1twXxYmgDXgoKVWUG/fReSzHg== + loose-envify@^1.0.0: version "1.4.0" - resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== dependencies: js-tokens "^3.0.0 || ^4.0.0" +lru-cache@^11.0.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.1.0.tgz#afafb060607108132dbc1cf8ae661afb69486117" + integrity sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A== + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -7547,29 +7923,24 @@ lru-cache@^5.1.1: lru-cache@^6.0.0: version "6.0.0" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== dependencies: yallist "^4.0.0" lru-cache@^7.4.4, lru-cache@^7.5.1, lru-cache@^7.7.1: version "7.18.3" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== -"lru-cache@^9.1.1 || ^10.0.0": - version "10.0.1" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz" - integrity sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g== - lru_map@^0.3.3: version "0.3.3" - resolved "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz" + resolved "https://registry.yarnpkg.com/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd" integrity sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ== make-dir@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== dependencies: pify "^4.0.1" @@ -7577,7 +7948,7 @@ make-dir@^2.1.0: make-dir@^3.0.0: version "3.1.0" - resolved "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== dependencies: semver "^6.0.0" @@ -7594,9 +7965,9 @@ make-error@1.x, make-error@^1.1.1, make-error@^1.3.6: resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== -make-fetch-happen@^10.0.6: +make-fetch-happen@^10.0.3, make-fetch-happen@^10.0.6: version "10.2.1" - resolved "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz#f5e3835c5e9817b617f2770870d9492d28678164" integrity sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w== dependencies: agentkeepalive "^4.2.1" @@ -7616,27 +7987,6 @@ make-fetch-happen@^10.0.6: socks-proxy-agent "^7.0.0" ssri "^9.0.0" -make-fetch-happen@^11.0.3: - version "11.1.1" - resolved "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz" - integrity sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w== - dependencies: - agentkeepalive "^4.2.1" - cacache "^17.0.0" - http-cache-semantics "^4.1.1" - http-proxy-agent "^5.0.0" - https-proxy-agent "^5.0.0" - is-lambda "^1.0.1" - lru-cache "^7.7.1" - minipass "^5.0.0" - minipass-fetch "^3.0.0" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - negotiator "^0.6.3" - promise-retry "^2.0.1" - socks-proxy-agent "^7.0.0" - ssri "^10.0.0" - makeerror@1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" @@ -7651,12 +8001,12 @@ map-cache@^0.2.2: map-obj@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" integrity sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg== map-obj@^4.0.0: version "4.3.0" - resolved "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.3.0.tgz#9304f906e93faae70880da102a9f1df0ea8bb05a" integrity sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ== map-visit@^1.0.0: @@ -7666,6 +8016,11 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" +math-intrinsics@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9" + integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== + math-random@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.4.tgz#5dd6943c938548267016d4e34f057583080c514c" @@ -7673,12 +8028,17 @@ math-random@^1.0.1: media-typer@0.3.0: version "0.3.0" - resolved "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== +memorystream@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" + integrity sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw== + meow@^8.0.0: version "8.1.2" - resolved "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz" + resolved "https://registry.yarnpkg.com/meow/-/meow-8.1.2.tgz#bcbe45bda0ee1729d350c03cffc8395a36c4e897" integrity sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q== dependencies: "@types/minimist" "^1.2.0" @@ -7695,24 +8055,40 @@ meow@^8.0.0: merge-descriptors@1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== merge-stream@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" - resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" + 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.npmjs.org/methods/-/methods-1.1.2.tgz" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== +micro-eth-signer@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/micro-eth-signer/-/micro-eth-signer-0.14.0.tgz#8aa1fe997d98d6bdf42f2071cef7eb01a66ecb22" + integrity sha512-5PLLzHiVYPWClEvZIXXFu5yutzpadb73rnQCpUqIHu3No3coFuWQNfE5tkBQJ7djuLYl6aRLaS0MgWJYGoqiBw== + dependencies: + "@noble/curves" "~1.8.1" + "@noble/hashes" "~1.7.1" + micro-packed "~0.7.2" + +micro-packed@~0.7.2: + version "0.7.3" + resolved "https://registry.yarnpkg.com/micro-packed/-/micro-packed-0.7.3.tgz#59e96b139dffeda22705c7a041476f24cabb12b6" + integrity sha512-2Milxs+WNC00TRlem41oRswvw31146GiSaoCT7s3Xi2gMUglW5QBeqlQaZeHr5tJx9nm3i57LNXPqxOOaWtTYg== + dependencies: + "@scure/base" "~1.2.5" + micromatch@^2.1.5: version "2.3.11" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" @@ -7751,94 +8127,94 @@ micromatch@^3.1.10: snapdragon "^0.8.1" to-regex "^3.0.2" -micromatch@^4.0.4: - version "4.0.5" - resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== +micromatch@^4.0.4, micromatch@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" + integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== dependencies: - braces "^3.0.2" + braces "^3.0.3" picomatch "^2.3.1" mime-db@1.52.0: version "1.52.0" - resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== mime-types@^2.1.12, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.35" - resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: mime-db "1.52.0" mime@1.6.0: version "1.6.0" - resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== mimic-fn@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== min-document@^2.19.0: version "2.19.0" - resolved "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz" + resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" integrity sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ== dependencies: dom-walk "^0.1.0" min-indent@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== minimal-polyfills@^2.1.5, minimal-polyfills@^2.2.3: version "2.2.3" - resolved "https://registry.npmjs.org/minimal-polyfills/-/minimal-polyfills-2.2.3.tgz" + resolved "https://registry.yarnpkg.com/minimal-polyfills/-/minimal-polyfills-2.2.3.tgz#22af58de16807b325f29b83ca38ffb83e75ec3f4" integrity sha512-oxdmJ9cL+xV72h0xYxp4tP2d5/fTBpP45H8DIOn9pASuF8a3IYTf+25fMGDYGiWW+MFsuog6KD6nfmhZJQ+uUw== minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== minimalistic-crypto-utils@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== minimatch@3.0.5: version "3.0.5" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.5.tgz#4da8f1290ee0f0f8e83d60ca69f8f134068604a3" integrity sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw== dependencies: brace-expansion "^1.1.7" +minimatch@^10.0.0: + version "10.0.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.0.1.tgz#ce0521856b453c86e25f2c4c0d03e6ff7ddc440b" + integrity sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ== + dependencies: + brace-expansion "^2.0.1" + minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: brace-expansion "^1.1.7" -minimatch@^5.0.1: +minimatch@^5.0.1, minimatch@^5.1.6: version "5.1.6" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== dependencies: brace-expansion "^2.0.1" -minimatch@^9.0.1: - version "9.0.3" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz" - integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== - dependencies: - brace-expansion "^2.0.1" - minimist-options@4.1.0: version "4.1.0" - resolved "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz" + resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-4.1.0.tgz#c0655713c53a8a2ebd77ffa247d342c40f010619" integrity sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A== dependencies: arrify "^1.0.1" @@ -7847,19 +8223,19 @@ minimist-options@4.1.0: minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: version "1.2.8" - resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== minipass-collect@^1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== dependencies: minipass "^3.0.0" minipass-fetch@^2.0.3: version "2.1.2" - resolved "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz" + resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-2.1.2.tgz#95560b50c472d81a3bc76f20ede80eaed76d8add" integrity sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA== dependencies: minipass "^3.1.6" @@ -7868,66 +8244,55 @@ minipass-fetch@^2.0.3: optionalDependencies: encoding "^0.1.13" -minipass-fetch@^3.0.0: - version "3.0.4" - resolved "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.4.tgz" - integrity sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg== - dependencies: - minipass "^7.0.3" - minipass-sized "^1.0.3" - minizlib "^2.1.2" - optionalDependencies: - encoding "^0.1.13" - minipass-flush@^1.0.5: version "1.0.5" - resolved "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz" + resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== dependencies: minipass "^3.0.0" minipass-json-stream@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz" - integrity sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg== + version "1.0.2" + resolved "https://registry.yarnpkg.com/minipass-json-stream/-/minipass-json-stream-1.0.2.tgz#5121616c77a11c406c3ffa77509e0b77bb267ec3" + integrity sha512-myxeeTm57lYs8pH2nxPzmEEg8DGIgW+9mv6D4JZD2pa81I/OBjeU7PtICXV6c9eRGTA5JMDsuIPUZRCyBMYNhg== dependencies: jsonparse "^1.3.1" minipass "^3.0.0" minipass-pipeline@^1.2.4: version "1.2.4" - resolved "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz" + resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== dependencies: minipass "^3.0.0" minipass-sized@^1.0.3: version "1.0.3" - resolved "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz" + resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-1.0.3.tgz#70ee5a7c5052070afacfbc22977ea79def353b70" integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== dependencies: minipass "^3.0.0" minipass@^3.0.0, minipass@^3.1.1, minipass@^3.1.6: version "3.3.6" - resolved "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== dependencies: yallist "^4.0.0" minipass@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== -"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.3: - version "7.0.3" - resolved "https://registry.npmjs.org/minipass/-/minipass-7.0.3.tgz" - integrity sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg== +minipass@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707" + integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== minizlib@^2.1.1, minizlib@^2.1.2: version "2.1.2" - resolved "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== dependencies: minipass "^3.0.0" @@ -7943,7 +8308,7 @@ mixin-deep@^1.2.0: mkdirp-infer-owner@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/mkdirp-infer-owner/-/mkdirp-infer-owner-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/mkdirp-infer-owner/-/mkdirp-infer-owner-2.0.0.tgz#55d3b368e7d89065c38f32fd38e638f0ab61d316" integrity sha512-sdqtiFt3lkOaYvTXSRIUjkIdPTcxgv5+fgqYE/5qgwdw12cOrAuzzgzvVExIkH/ul1oeHN3bCLOWSG3XOqbKKw== dependencies: chownr "^2.0.0" @@ -7959,29 +8324,62 @@ mkdirp@^0.5.1: mkdirp@^1.0.3, mkdirp@^1.0.4: version "1.0.4" - resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== +mnemonist@^0.38.0: + version "0.38.5" + resolved "https://registry.yarnpkg.com/mnemonist/-/mnemonist-0.38.5.tgz#4adc7f4200491237fe0fa689ac0b86539685cade" + integrity sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg== + dependencies: + obliterator "^2.0.0" + +mocha@^10.0.0: + version "10.8.2" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.8.2.tgz#8d8342d016ed411b12a429eb731b825f961afb96" + integrity sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg== + dependencies: + ansi-colors "^4.1.3" + browser-stdout "^1.3.1" + chokidar "^3.5.3" + debug "^4.3.5" + diff "^5.2.0" + escape-string-regexp "^4.0.0" + find-up "^5.0.0" + glob "^8.1.0" + he "^1.2.0" + js-yaml "^4.1.0" + log-symbols "^4.1.0" + minimatch "^5.1.6" + ms "^2.1.3" + serialize-javascript "^6.0.2" + strip-json-comments "^3.1.1" + supports-color "^8.1.1" + workerpool "^6.5.1" + yargs "^16.2.0" + yargs-parser "^20.2.9" + yargs-unparser "^2.0.0" + modify-values@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw== moment-timezone@^0.5.43: - version "0.5.43" - resolved "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.43.tgz" - integrity sha512-72j3aNyuIsDxdF1i7CEgV2FfxM1r6aaqJyLB2vwb33mXYyoyLly+F1zbWqhA3/bVIoJ4szlUoMbUnVdid32NUQ== + version "0.5.48" + resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.48.tgz#111727bb274734a518ae154b5ca589283f058967" + integrity sha512-f22b8LV1gbTO2ms2j2z13MuPogNoh5UzxL3nzNAYKGraILnbGc9NEE6dyiiiLv46DGRb8A4kg8UKWLjPthxBHw== dependencies: moment "^2.29.4" moment@^2.29.4: - version "2.29.4" - resolved "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz" - integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w== + version "2.30.1" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae" + integrity sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how== morgan@1.10.0: version "1.10.0" - resolved "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz" + resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.10.0.tgz#091778abc1fc47cd3509824653dae1faab6b17d7" integrity sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ== dependencies: basic-auth "~2.0.1" @@ -7992,22 +8390,17 @@ morgan@1.10.0: ms@2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== -ms@2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@2.1.3, ms@^2.0.0: +ms@2.1.3, ms@^2.0.0, ms@^2.1.3: version "2.1.3" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== multimatch@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz" + resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-5.0.0.tgz#932b800963cea7a31a033328fa1e0c3a1874dbe6" integrity sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA== dependencies: "@types/minimatch" "^3.0.3" @@ -8018,13 +8411,13 @@ multimatch@^5.0.0: mute-stream@0.0.8, mute-stream@~0.0.4: version "0.0.8" - resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== nan@^2.12.1: - version "2.19.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.19.0.tgz#bb58122ad55a6c5bc973303908d5b16cfdd5a8c0" - integrity sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw== + version "2.22.2" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.22.2.tgz#6b504fd029fb8f38c0990e52ad5c26772fdacfbb" + integrity sha512-DANghxFkS1plDdRsX0X9pm0Z6SJNN6gBdtXfanwoZ8hooC5gosGFSBGRYHUVPz1asKA/kMRqDRdHrluZ61SpBQ== nanomatch@^1.2.9: version "1.2.13" @@ -8048,48 +8441,58 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== -negotiator@0.6.3, negotiator@^0.6.3: +negotiator@0.6.3: version "0.6.3" - resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== +negotiator@^0.6.3: + version "0.6.4" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.4.tgz#777948e2452651c570b712dd01c23e262713fff7" + integrity sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w== + neo-async@^2.6.2: version "2.6.2" - resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== ngeohash@0.6.3: version "0.6.3" - resolved "https://registry.npmjs.org/ngeohash/-/ngeohash-0.6.3.tgz" + resolved "https://registry.yarnpkg.com/ngeohash/-/ngeohash-0.6.3.tgz#10b1e80be5488262ec95c56cf2dbb6c45fbdf245" integrity sha512-kltF0cOxgx1AbmVzKxYZaoB0aj7mOxZeHaerEtQV0YaqnkXNq26WWqMmJ6lTqShYxVRWZ/mwvvTrNeOwdslWiw== +node-addon-api@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" + integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== + node-addon-api@^3.2.1: version "3.2.1" - resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161" integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A== node-fetch@^2.6.1, node-fetch@^2.6.12, node-fetch@^2.6.7: version "2.7.0" - resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz" + 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" -node-gyp-build@^4.3.0: - version "4.6.1" - resolved "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.1.tgz" - integrity sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ== +node-gyp-build@^4.2.0, node-gyp-build@^4.3.0: + version "4.8.4" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.4.tgz#8a70ee85464ae52327772a90d66c6077a900cfc8" + integrity sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ== node-gyp@^9.0.0: - version "9.4.0" - resolved "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.0.tgz" - integrity sha512-dMXsYP6gc9rRbejLXmTbVRYjAHw7ppswsKyMxuxJxxOHzluIO1rGp9TOQgjFJ+2MCqcOcQTOPB/8Xwhr+7s4Eg== + version "9.4.1" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-9.4.1.tgz#8a1023e0d6766ecb52764cc3a734b36ff275e185" + integrity sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ== dependencies: env-paths "^2.2.0" exponential-backoff "^3.1.1" glob "^7.1.4" graceful-fs "^4.2.6" - make-fetch-happen "^11.0.3" + make-fetch-happen "^10.0.3" nopt "^6.0.0" npmlog "^6.0.0" rimraf "^3.0.2" @@ -8102,28 +8505,28 @@ node-int64@^0.4.0: resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== -node-releases@^2.0.14: - version "2.0.14" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b" - integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== +node-releases@^2.0.19: + version "2.0.19" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.19.tgz#9e445a52950951ec4d177d843af370b411caf314" + integrity sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw== nopt@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== dependencies: abbrev "1" nopt@^6.0.0: version "6.0.0" - resolved "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-6.0.0.tgz#245801d8ebf409c6df22ab9d95b65e1309cdb16d" integrity sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g== dependencies: abbrev "^1.0.0" normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: version "2.5.0" - resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== dependencies: hosted-git-info "^2.1.4" @@ -8133,7 +8536,7 @@ normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: normalize-package-data@^3.0.0: version "3.0.3" - resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-3.0.3.tgz#dbcc3e2da59509a0983422884cd172eefdfa525e" integrity sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA== dependencies: hosted-git-info "^4.0.1" @@ -8143,7 +8546,7 @@ normalize-package-data@^3.0.0: normalize-package-data@^4.0.0: version "4.0.1" - resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-4.0.1.tgz" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-4.0.1.tgz#b46b24e0616d06cadf9d5718b29b6d445a82a62c" integrity sha512-EBk5QKKuocMJhB3BILuKhmaPjI8vNRSpIfO9woLC6NyHVkKKdVEdAO1mrT0ZfxNR1lKwCcTkuZfmGIFdizZ8Pg== dependencies: hosted-git-info "^5.0.0" @@ -8158,45 +8561,45 @@ normalize-path@^2.0.0, normalize-path@^2.0.1: dependencies: remove-trailing-separator "^1.0.1" -normalize-path@^3.0.0: +normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== npm-bundled@^1.1.1: version "1.1.2" - resolved "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.2.tgz#944c78789bd739035b70baa2ca5cc32b8d860bc1" integrity sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ== dependencies: npm-normalize-package-bin "^1.0.1" npm-bundled@^2.0.0: version "2.0.1" - resolved "https://registry.npmjs.org/npm-bundled/-/npm-bundled-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-2.0.1.tgz#94113f7eb342cd7a67de1e789f896b04d2c600f4" integrity sha512-gZLxXdjEzE/+mOstGDqR6b0EkhJ+kM6fxM6vUuckuctuVPh80Q6pw/rSZj9s4Gex9GxWtIicO1pc8DB9KZWudw== dependencies: npm-normalize-package-bin "^2.0.0" npm-install-checks@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-5.0.0.tgz" + resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-5.0.0.tgz#5ff27d209a4e3542b8ac6b0c1db6063506248234" integrity sha512-65lUsMI8ztHCxFz5ckCEC44DRvEGdZX5usQFriauxHEwt7upv1FKaQEmAtU0YnOAdwuNWCmk64xYiQABNrEyLA== dependencies: semver "^7.1.1" npm-normalize-package-bin@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== npm-normalize-package-bin@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-2.0.0.tgz#9447a1adaaf89d8ad0abe24c6c84ad614a675fff" integrity sha512-awzfKUO7v0FscrSpRoogyNm0sajikhBWpU0QMrW09AMi9n1PoKU6WaIqUzuJSQnpciZZmJ/jMZ2Egfmb/9LiWQ== npm-package-arg@8.1.1: version "8.1.1" - resolved "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-8.1.1.tgz" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.1.1.tgz#00ebf16ac395c63318e67ce66780a06db6df1b04" integrity sha512-CsP95FhWQDwNqiYS+Q0mZ7FAEDytDZAkNxQqea6IaAFJTAY9Lhhqyl0irU/6PMc7BGfUmnsbHcqxJD7XuVM/rg== dependencies: hosted-git-info "^3.0.6" @@ -8205,7 +8608,7 @@ npm-package-arg@8.1.1: npm-package-arg@^9.0.0, npm-package-arg@^9.0.1: version "9.1.2" - resolved "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-9.1.2.tgz" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-9.1.2.tgz#fc8acecb00235f42270dda446f36926ddd9ac2bc" integrity sha512-pzd9rLEx4TfNJkovvlBSLGhq31gGu2QDexFPWT19yCDh0JgnRhlBLNo5759N0AJmBk+kQ9Y/hXoLnlgFD+ukmg== dependencies: hosted-git-info "^5.0.0" @@ -8215,7 +8618,7 @@ npm-package-arg@^9.0.0, npm-package-arg@^9.0.1: npm-packlist@^5.1.0, npm-packlist@^5.1.1: version "5.1.3" - resolved "https://registry.npmjs.org/npm-packlist/-/npm-packlist-5.1.3.tgz" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-5.1.3.tgz#69d253e6fd664b9058b85005905012e00e69274b" integrity sha512-263/0NGrn32YFYi4J533qzrQ/krmmrWwhKkzwTuM4f/07ug51odoaNjUexxO4vxlzURHcmYMH1QjvHjsNDKLVg== dependencies: glob "^8.0.1" @@ -8225,7 +8628,7 @@ npm-packlist@^5.1.0, npm-packlist@^5.1.1: npm-pick-manifest@^7.0.0: version "7.0.2" - resolved "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-7.0.2.tgz" + resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-7.0.2.tgz#1d372b4e7ea7c6712316c0e99388a73ed3496e84" integrity sha512-gk37SyRmlIjvTfcYl6RzDbSmS9Y4TOBXfsPnoYqTHARNgWbyDiCSMLUpmALDj4jjcTZpURiEfsSHJj9k7EV4Rw== dependencies: npm-install-checks "^5.0.0" @@ -8235,7 +8638,7 @@ npm-pick-manifest@^7.0.0: npm-registry-fetch@^13.0.0, npm-registry-fetch@^13.0.1, npm-registry-fetch@^13.3.0: version "13.3.1" - resolved "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-13.3.1.tgz" + resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-13.3.1.tgz#bb078b5fa6c52774116ae501ba1af2a33166af7e" integrity sha512-eukJPi++DKRTjSBRcDZSDDsGqRK3ehbxfFUcgaRd0Yp6kRwOwh2WVn0r+8rMB4nnuzvAk6rQVzl6K5CkYOmnvw== dependencies: make-fetch-happen "^10.0.6" @@ -8248,14 +8651,14 @@ npm-registry-fetch@^13.0.0, npm-registry-fetch@^13.0.1, npm-registry-fetch@^13.3 npm-run-path@^4.0.0, npm-run-path@^4.0.1: version "4.0.1" - resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== dependencies: path-key "^3.0.0" npmlog@^6.0.0, npmlog@^6.0.2: version "6.0.2" - resolved "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-6.0.2.tgz#c8166017a42f2dea92d6453168dd865186a70830" integrity sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg== dependencies: are-we-there-yet "^3.0.0" @@ -8265,7 +8668,7 @@ npmlog@^6.0.0, npmlog@^6.0.2: nx@15.9.7, "nx@>=14.8.6 < 16": version "15.9.7" - resolved "https://registry.npmjs.org/nx/-/nx-15.9.7.tgz" + resolved "https://registry.yarnpkg.com/nx/-/nx-15.9.7.tgz#f0e713cedb8637a517d9c4795c99afec4959a1b6" integrity sha512-1qlEeDjX9OKZEryC8i4bA+twNg+lB5RKrozlNwWx/lLJHqWPUfvUTvxh+uxlPYL9KzVReQjUuxMLFMsHNqWUrA== dependencies: "@nrwl/cli" "15.9.7" @@ -8316,7 +8719,7 @@ nx@15.9.7, "nx@>=14.8.6 < 16": object-assign@^4, object-assign@^4.1.0: version "4.1.1" - resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== object-copy@^0.1.0: @@ -8328,10 +8731,10 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" -object-inspect@^1.9.0: - version "1.12.3" - resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz" - integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== +object-inspect@^1.13.3: + version "1.13.4" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.4.tgz#8375265e21bc20d0fa582c22e1b13485d6e00213" + integrity sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew== object-visit@^1.0.0: version "1.0.1" @@ -8355,47 +8758,52 @@ object.pick@^1.3.0: dependencies: isobject "^3.0.1" +obliterator@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/obliterator/-/obliterator-2.0.5.tgz#031e0145354b0c18840336ae51d41e7d6d2c76aa" + integrity sha512-42CPE9AhahZRsMNslczq0ctAEtqk8Eka26QofnqC346BZdHDySk3LWka23LI7ULIw11NmltpiLagIq8gBozxTw== + on-exit-leak-free@^0.2.0: version "0.2.0" - resolved "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-0.2.0.tgz" + resolved "https://registry.yarnpkg.com/on-exit-leak-free/-/on-exit-leak-free-0.2.0.tgz#b39c9e3bf7690d890f4861558b0d7b90a442d209" integrity sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg== on-finished@2.4.1: version "2.4.1" - resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== dependencies: ee-first "1.1.1" on-finished@~2.3.0: version "2.3.0" - resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" integrity sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww== dependencies: ee-first "1.1.1" on-headers@~1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" - resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== dependencies: wrappy "1" onetime@^5.1.0, onetime@^5.1.2: version "5.1.2" - resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== dependencies: mimic-fn "^2.1.0" open@^8.4.0: version "8.4.2" - resolved "https://registry.npmjs.org/open/-/open-8.4.2.tgz" + resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== dependencies: define-lazy-prop "^2.0.0" @@ -8416,7 +8824,7 @@ optionator@^0.9.3: ora@^4.0.0: version "4.1.1" - resolved "https://registry.npmjs.org/ora/-/ora-4.1.1.tgz" + resolved "https://registry.yarnpkg.com/ora/-/ora-4.1.1.tgz#566cc0348a15c36f5f0e979612842e02ba9dddbc" integrity sha512-sjYP8QyVWBpBZWD6Vr1M/KwknSw6kJOz41tvGMlwWeClHBtYKTbHMki1PsLZnxKpXMPbTKv9b3pjQu3REib96A== dependencies: chalk "^3.0.0" @@ -8430,7 +8838,7 @@ ora@^4.0.0: ora@^5.4.1: version "5.4.1" - resolved "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz" + resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== dependencies: bl "^4.1.0" @@ -8450,7 +8858,7 @@ os-homedir@^1.0.0: os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== output-file-sync@^1.1.2: @@ -8464,52 +8872,52 @@ output-file-sync@^1.1.2: p-filter@2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/p-filter/-/p-filter-2.1.0.tgz#1b1472562ae7a0f742f0f3d3d3718ea66ff9c09c" integrity sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw== dependencies: p-map "^2.0.0" p-finally@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== p-finally@^2.0.0: version "2.0.1" - resolved "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-2.0.1.tgz#bd6fcaa9c559a096b680806f4d657b3f0f240561" integrity sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw== p-limit@^1.1.0: version "1.3.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== dependencies: p-try "^1.0.0" p-limit@^2.2.0: version "2.3.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== dependencies: p-try "^2.0.0" p-limit@^3.0.2, p-limit@^3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== dependencies: yocto-queue "^0.1.0" p-locate@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" integrity sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg== dependencies: p-limit "^1.1.0" p-locate@^4.1.0: version "4.1.0" - resolved "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== dependencies: p-limit "^2.2.0" @@ -8523,29 +8931,29 @@ p-locate@^5.0.0: p-map-series@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/p-map-series/-/p-map-series-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/p-map-series/-/p-map-series-2.1.0.tgz#7560d4c452d9da0c07e692fdbfe6e2c81a2a91f2" integrity sha512-RpYIIK1zXSNEOdwxcfe7FdvGcs7+y5n8rifMhMNWvaxRNMPINJHF5GDeuVxWqnfrcHPSCnp7Oo5yNXHId9Av2Q== p-map@4.0.0, p-map@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== dependencies: aggregate-error "^3.0.0" p-map@^2.0.0: version "2.1.0" - resolved "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== p-pipe@^3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/p-pipe/-/p-pipe-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/p-pipe/-/p-pipe-3.1.0.tgz#48b57c922aa2e1af6a6404cb7c6bf0eb9cc8e60e" integrity sha512-08pj8ATpzMR0Y80x50yJHn37NF6vjrqHutASaX5LiH5npS9XPvrUmscd9MF5R4fuYRHOxQR1FfMIlF7AzwoPqw== p-queue@6.6.2, p-queue@^6.6.2: version "6.6.2" - resolved "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz" + resolved "https://registry.yarnpkg.com/p-queue/-/p-queue-6.6.2.tgz#2068a9dcf8e67dd0ec3e7a2bcb76810faa85e426" integrity sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ== dependencies: eventemitter3 "^4.0.4" @@ -8553,12 +8961,12 @@ p-queue@6.6.2, p-queue@^6.6.2: p-reduce@2.1.0, p-reduce@^2.0.0, p-reduce@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/p-reduce/-/p-reduce-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-2.1.0.tgz#09408da49507c6c274faa31f28df334bc712b64a" integrity sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw== p-retry@4.6.1: version "4.6.1" - resolved "https://registry.npmjs.org/p-retry/-/p-retry-4.6.1.tgz" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.1.tgz#8fcddd5cdf7a67a0911a9cf2ef0e5df7f602316c" integrity sha512-e2xXGNhZOZ0lfgR9kL34iGlU8N/KO0xZnQxVEwdeOvpqNDQfdnxIYizvWtK8RglUa3bGqI8g0R/BdfzLMxRkiA== dependencies: "@types/retry" "^0.12.0" @@ -8566,41 +8974,46 @@ p-retry@4.6.1: p-timeout@4.1.0: version "4.1.0" - resolved "https://registry.npmjs.org/p-timeout/-/p-timeout-4.1.0.tgz" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-4.1.0.tgz#788253c0452ab0ffecf18a62dff94ff1bd09ca0a" integrity sha512-+/wmHtzJuWii1sXn3HCuH/FTwGhrp4tmJTxSKJbfS+vkipci6osxXM5mY0jUiRzWKMTgUT8l7HFbeSwZAynqHw== p-timeout@^3.2.0: version "3.2.0" - resolved "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== dependencies: p-finally "^1.0.0" p-try@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" integrity sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww== p-try@^2.0.0: version "2.2.0" - resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== p-waterfall@^2.1.1: version "2.1.1" - resolved "https://registry.npmjs.org/p-waterfall/-/p-waterfall-2.1.1.tgz" + resolved "https://registry.yarnpkg.com/p-waterfall/-/p-waterfall-2.1.1.tgz#63153a774f472ccdc4eb281cdb2967fcf158b2ee" integrity sha512-RRTnDb2TBG/epPRI2yYXsimO0v3BXC8Yd3ogr1545IaqKK17VGhbWVeGGN+XfCm/08OK8635nH31c8bATkHuSw== dependencies: p-reduce "^2.0.0" +package-json-from-dist@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz#4f1471a010827a86f94cfd9b0727e36d267de505" + integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw== + packet-reader@1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/packet-reader/-/packet-reader-1.0.0.tgz#9238e5480dedabacfe1fe3f2771063f164157d74" integrity sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ== pacote@^13.0.3, pacote@^13.6.1: version "13.6.2" - resolved "https://registry.npmjs.org/pacote/-/pacote-13.6.2.tgz" + resolved "https://registry.yarnpkg.com/pacote/-/pacote-13.6.2.tgz#0d444ba3618ab3e5cd330b451c22967bbd0ca48a" integrity sha512-Gu8fU3GsvOPkak2CkbojR7vjs3k3P9cA6uazKTHdsdV0gpCEQq2opelnEv30KRQWgVzP5Vd/5umjcedma3MKtg== dependencies: "@npmcli/git" "^3.0.0" @@ -8627,14 +9040,14 @@ pacote@^13.0.3, pacote@^13.6.1: parent-module@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== dependencies: callsites "^3.0.0" parse-conflict-json@^2.0.1: version "2.0.2" - resolved "https://registry.npmjs.org/parse-conflict-json/-/parse-conflict-json-2.0.2.tgz" + resolved "https://registry.yarnpkg.com/parse-conflict-json/-/parse-conflict-json-2.0.2.tgz#3d05bc8ffe07d39600dc6436c6aefe382033d323" integrity sha512-jDbRGb00TAPFsKWCpZZOT93SxVP9nONOSgES3AevqRq/CHvavEBvKAjxX9p5Y5F0RZLxH9Ufd9+RwtCsa+lFDA== dependencies: json-parse-even-better-errors "^2.3.1" @@ -8653,7 +9066,7 @@ parse-glob@^3.0.4: parse-json@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" integrity sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw== dependencies: error-ex "^1.3.1" @@ -8661,7 +9074,7 @@ parse-json@^4.0.0: parse-json@^5.0.0, parse-json@^5.2.0: version "5.2.0" - resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== dependencies: "@babel/code-frame" "^7.0.0" @@ -8670,27 +9083,27 @@ parse-json@^5.0.0, parse-json@^5.2.0: lines-and-columns "^1.1.6" parse-path@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/parse-path/-/parse-path-7.0.0.tgz" - integrity sha512-Euf9GG8WT9CdqwuWJGdf3RkUcTBArppHABkO7Lm8IzRQp0e2r/kkFnmhu4TSK30Wcu5rVAZLmfPKSBBi9tWFog== + version "7.1.0" + resolved "https://registry.yarnpkg.com/parse-path/-/parse-path-7.1.0.tgz#41fb513cb122831807a4c7b29c8727947a09d8c6" + integrity sha512-EuCycjZtfPcjWk7KTksnJ5xPMvWGA/6i4zrLYhRG0hGvC3GPU/jGUj3Cy+ZR0v30duV3e23R95T1lE2+lsndSw== dependencies: protocols "^2.0.0" parse-url@^8.1.0: version "8.1.0" - resolved "https://registry.npmjs.org/parse-url/-/parse-url-8.1.0.tgz" + resolved "https://registry.yarnpkg.com/parse-url/-/parse-url-8.1.0.tgz#972e0827ed4b57fc85f0ea6b0d839f0d8a57a57d" integrity sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w== dependencies: parse-path "^7.0.0" parseurl@~1.3.3: version "1.3.3" - resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== parsimmon@^1.18.1: version "1.18.1" - resolved "https://registry.npmjs.org/parsimmon/-/parsimmon-1.18.1.tgz" + resolved "https://registry.yarnpkg.com/parsimmon/-/parsimmon-1.18.1.tgz#d8dd9c28745647d02fc6566f217690897eed7709" integrity sha512-u7p959wLfGAhJpSDJVYXoyMCXWYwHia78HhRBWqk7AIbxdmlrfdp5wX0l3xv/iTSH5HvhN9K7o26hwwpgS5Nmw== pascalcase@^0.1.1: @@ -8700,89 +9113,89 @@ pascalcase@^0.1.1: path-exists@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== path-exists@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" - resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== -path-parse@^1.0.7: +path-parse@^1.0.6, path-parse@^1.0.7: version "1.0.7" - resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -path-scurry@^1.10.1: - version "1.10.1" - resolved "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz" - integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== +path-scurry@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-2.0.0.tgz#9f052289f23ad8bf9397a2a0425e7b8615c58580" + integrity sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg== dependencies: - lru-cache "^9.1.1 || ^10.0.0" - minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + lru-cache "^11.0.0" + minipass "^7.1.2" path-to-regexp@0.1.7: version "0.1.7" - resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== path-type@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== dependencies: pify "^3.0.0" path-type@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== pg-cloudflare@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz" - integrity sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q== + version "1.2.5" + resolved "https://registry.yarnpkg.com/pg-cloudflare/-/pg-cloudflare-1.2.5.tgz#2e3649c38a7a9c74a7e5327c8098a2fd9af595bd" + integrity sha512-OOX22Vt0vOSRrdoUPKJ8Wi2OpE/o/h9T8X1s4qSkCedbNah9ei2W2765be8iMVxQUsvgT7zIAT2eIa9fs5+vtg== pg-connection-string@^2.6.1, pg-connection-string@^2.6.2: - version "2.6.2" - resolved "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz" - integrity sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA== + version "2.9.0" + resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.9.0.tgz#f75e06591fdd42ec7636fe2c6a03febeedbec9bf" + integrity sha512-P2DEBKuvh5RClafLngkAuGe9OUlFV7ebu8w1kmaaOgPcpJd1RIFh7otETfI6hAR8YupOLFTY7nuvvIn7PLciUQ== pg-hstore@2.3.4: version "2.3.4" - resolved "https://registry.npmjs.org/pg-hstore/-/pg-hstore-2.3.4.tgz" + resolved "https://registry.yarnpkg.com/pg-hstore/-/pg-hstore-2.3.4.tgz#4425e3e2a3e15d2a334c35581186c27cf2e9b8dd" integrity sha512-N3SGs/Rf+xA1M2/n0JBiXFDVMzdekwLZLAO0g7mpDY9ouX+fDI7jS6kTq3JujmYbtNSJ53TJ0q4G98KVZSM4EA== dependencies: underscore "^1.13.1" pg-int8@1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c" integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw== pg-pool@^3.6.1: - version "3.6.1" - resolved "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.1.tgz" - integrity sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og== + version "3.10.0" + resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.10.0.tgz#134b0213755c5e7135152976488aa7cd7ee1268d" + integrity sha512-DzZ26On4sQ0KmqnO34muPcmKbhrjmyiO4lCCR0VwEd7MjmiKf5NTg/6+apUEu0NF7ESa37CGzFxH513CoUmWnA== pg-protocol@^1.6.0: - version "1.6.0" - resolved "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz" - integrity sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q== + version "1.10.0" + resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.10.0.tgz#a473afcbb1c6e5dc3ac24869ba3dd563f8a1ae1b" + integrity sha512-IpdytjudNuLv8nhlHs/UrVBhU0e78J0oIS/0AVdTbWxSOkFUVdsHC/NrorO6nXsQNDTT1kzDSOMJubBQviX18Q== pg-types@^2.1.0: version "2.2.0" - resolved "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz" + resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-2.2.0.tgz#2d0250d636454f7cfa3b6ae0382fdfa8063254a3" integrity sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA== dependencies: pg-int8 "1.0.1" @@ -8793,7 +9206,7 @@ pg-types@^2.1.0: pg@8.11.3: version "8.11.3" - resolved "https://registry.npmjs.org/pg/-/pg-8.11.3.tgz" + resolved "https://registry.yarnpkg.com/pg/-/pg-8.11.3.tgz#d7db6e3fe268fcedd65b8e4599cda0b8b4bf76cb" integrity sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g== dependencies: buffer-writer "2.0.0" @@ -8808,44 +9221,49 @@ pg@8.11.3: pgpass@1.x: version "1.0.5" - resolved "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz" + resolved "https://registry.yarnpkg.com/pgpass/-/pgpass-1.0.5.tgz#9b873e4a564bb10fa7a7dbd55312728d422a223d" integrity sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug== dependencies: split2 "^4.1.0" -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== +picocolors@^1.1.0, picocolors@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== -picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.1: version "2.3.1" - resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +picomatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.2.tgz#77c742931e8f3b8820946c76cd0c1f13730d1dab" + integrity sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg== + pify@^2.3.0: version "2.3.0" - resolved "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== pify@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" integrity sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg== pify@^4.0.1: version "4.0.1" - resolved "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== pify@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz" + resolved "https://registry.yarnpkg.com/pify/-/pify-5.0.0.tgz#1f5eca3f5e87ebec28cc6d54a0e4aaf00acc127f" integrity sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA== pino-abstract-transport@v0.5.0: version "0.5.0" - resolved "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-0.5.0.tgz" + resolved "https://registry.yarnpkg.com/pino-abstract-transport/-/pino-abstract-transport-0.5.0.tgz#4b54348d8f73713bfd14e3dc44228739aa13d9c0" integrity sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ== dependencies: duplexify "^4.1.2" @@ -8853,24 +9271,24 @@ pino-abstract-transport@v0.5.0: pino-multi-stream@6.0.0: version "6.0.0" - resolved "https://registry.npmjs.org/pino-multi-stream/-/pino-multi-stream-6.0.0.tgz" + resolved "https://registry.yarnpkg.com/pino-multi-stream/-/pino-multi-stream-6.0.0.tgz#2116bca740cb5eb606f430b20fd480f4944b2b99" integrity sha512-oCuTtaDSUB5xK1S45r9oWE0Dj8RWdHVvaGTft5pO/rmzgIqQRkilf5Ooilz3uRm0IYj8sPRho3lVx48LCmXjvQ== dependencies: pino "^7.0.0" pino-std-serializers@^3.1.0: version "3.2.0" - resolved "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-3.2.0.tgz" + resolved "https://registry.yarnpkg.com/pino-std-serializers/-/pino-std-serializers-3.2.0.tgz#b56487c402d882eb96cd67c257868016b61ad671" integrity sha512-EqX4pwDPrt3MuOAAUBMU0Tk5kR/YcCM5fNPEzgCO2zJ5HfX0vbiH9HbJglnyeQsN96Kznae6MWD47pZB5avTrg== pino-std-serializers@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/pino-std-serializers/-/pino-std-serializers-4.0.0.tgz#1791ccd2539c091ae49ce9993205e2cd5dbba1e2" integrity sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q== pino@7.6.0: version "7.6.0" - resolved "https://registry.npmjs.org/pino/-/pino-7.6.0.tgz" + resolved "https://registry.yarnpkg.com/pino/-/pino-7.6.0.tgz#f9abd13e221e15855e3cf6e88a2b6280527b3800" integrity sha512-CCCdryvM/chT0CDt9jQ1//z62RpSXPrzUFUpY4b8eKCVq3T2T3UF6DomoczkPze9d6VFiTyVF6Y8A6F9iAyAxg== dependencies: fast-redact "^3.0.0" @@ -8886,7 +9304,7 @@ pino@7.6.0: pino@^6.13.0: version "6.14.0" - resolved "https://registry.npmjs.org/pino/-/pino-6.14.0.tgz" + resolved "https://registry.yarnpkg.com/pino/-/pino-6.14.0.tgz#b745ea87a99a6c4c9b374e4f29ca7910d4c69f78" integrity sha512-iuhEDel3Z3hF9Jfe44DPXR8l07bhjuFY3GMHIXbjnY9XcafbyDDwl2sN2vw2GjMPf5Nkoe+OFao7ffn9SXaKDg== dependencies: fast-redact "^3.0.0" @@ -8899,7 +9317,7 @@ pino@^6.13.0: pino@^7.0.0: version "7.11.0" - resolved "https://registry.npmjs.org/pino/-/pino-7.11.0.tgz" + resolved "https://registry.yarnpkg.com/pino/-/pino-7.11.0.tgz#0f0ea5c4683dc91388081d44bff10c83125066f6" integrity sha512-dMACeu63HtRLmCG8VKdy4cShCPKaYDR4youZqoSWLxl5Gu99HUw8bw75thbPv9Nip+H+QYX8o3ZJbTdVZZ2TVg== dependencies: atomic-sleep "^1.0.0" @@ -8915,20 +9333,20 @@ pino@^7.0.0: thread-stream "^0.15.1" pirates@^4.0.4: - version "4.0.6" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" - integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== + version "4.0.7" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.7.tgz#643b4a18c4257c8a65104b73f3049ce9a0a15e22" + integrity sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA== pkg-dir@^4.2.0: version "4.2.0" - resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== dependencies: find-up "^4.0.0" pluralize@^8.0.0: version "8.0.0" - resolved "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1" integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== posix-character-classes@^0.1.0: @@ -8938,22 +9356,22 @@ posix-character-classes@^0.1.0: postgres-array@~2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e" integrity sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA== postgres-bytea@~1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-1.0.0.tgz#027b533c0aa890e26d172d47cf9ccecc521acd35" integrity sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w== postgres-date@~1.0.4: version "1.0.7" - resolved "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz" + resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.7.tgz#51bc086006005e5061c591cee727f2531bf641a8" integrity sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q== postgres-interval@^1.1.0: version "1.2.0" - resolved "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz" + resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.2.0.tgz#b460c82cb1587507788819a06aa0fffdb3544695" integrity sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ== dependencies: xtend "^4.0.0" @@ -8994,49 +9412,49 @@ private@^0.1.8: proc-log@^2.0.0, proc-log@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/proc-log/-/proc-log-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-2.0.1.tgz#8f3f69a1f608de27878f91f5c688b225391cb685" integrity sha512-Kcmo2FhfDTXdcbfDH76N7uBYHINxc/8GW7UAVuVP9I+Va3uHSerrnKV6dLooga/gh7GlgzuCCr/eoldnL1muGw== process-nextick-args@~2.0.0: version "2.0.1" - resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== process-warning@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/process-warning/-/process-warning-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/process-warning/-/process-warning-1.0.0.tgz#980a0b25dc38cd6034181be4b7726d89066b4616" integrity sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q== process@^0.11.10: version "0.11.10" - resolved "https://registry.npmjs.org/process/-/process-0.11.10.tgz" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== prom-client@14.2.0: version "14.2.0" - resolved "https://registry.npmjs.org/prom-client/-/prom-client-14.2.0.tgz" + resolved "https://registry.yarnpkg.com/prom-client/-/prom-client-14.2.0.tgz#ca94504e64156f6506574c25fb1c34df7812cf11" integrity sha512-sF308EhTenb/pDRPakm+WgiN+VdM/T1RaHj1x+MvAuT8UiQP8JmOEbxVqtkbfR4LrvOg5n7ic01kRBDGXjYikA== dependencies: tdigest "^0.1.1" promise-all-reject-late@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz#f8ebf13483e5ca91ad809ccc2fcf25f26f8643c2" integrity sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw== promise-call-limit@^1.0.1: version "1.0.2" - resolved "https://registry.npmjs.org/promise-call-limit/-/promise-call-limit-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/promise-call-limit/-/promise-call-limit-1.0.2.tgz#f64b8dd9ef7693c9c7613e7dfe8d6d24de3031ea" integrity sha512-1vTUnfI2hzui8AEIixbdAJlFY4LFDXqQswy/2eOlThAscXCY4It8FdVuI0fMJGAB2aWGbdQf/gv0skKYXmdrHA== promise-inflight@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" integrity sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g== promise-retry@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== dependencies: err-code "^2.0.2" @@ -9052,24 +9470,42 @@ prompts@^2.0.1: promzard@^0.3.0: version "0.3.0" - resolved "https://registry.npmjs.org/promzard/-/promzard-0.3.0.tgz" + resolved "https://registry.yarnpkg.com/promzard/-/promzard-0.3.0.tgz#26a5d6ee8c7dee4cb12208305acfb93ba382a9ee" integrity sha512-JZeYqd7UAcHCwI+sTOeUDYkvEU+1bQ7iE0UT1MgB/tERkAPkesW46MrpIySzODi+owTjZtiF8Ay5j9m60KmMBw== dependencies: read "1" proto-list@~1.2.1: version "1.2.4" - resolved "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz" + resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" integrity sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA== +protobufjs@^7.2.5: + version "7.4.0" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.4.0.tgz#7efe324ce9b3b61c82aae5de810d287bc08a248a" + integrity sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/node" ">=13.7.0" + long "^5.0.0" + protocols@^2.0.0, protocols@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/protocols/-/protocols-2.0.1.tgz" - integrity sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q== + version "2.0.2" + resolved "https://registry.yarnpkg.com/protocols/-/protocols-2.0.2.tgz#822e8fcdcb3df5356538b3e91bfd890b067fd0a4" + integrity sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ== proxy-addr@^2.0.7, proxy-addr@~2.0.7: version "2.0.7" - resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== dependencies: forwarded "0.2.0" @@ -9077,20 +9513,20 @@ proxy-addr@^2.0.7, proxy-addr@~2.0.7: proxy-from-env@^1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== pump@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + version "3.0.2" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.2.tgz#836f3edd6bc2ee599256c924ffe0d88573ddcbf8" + integrity sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw== dependencies: end-of-stream "^1.1.0" once "^1.3.1" pumpify@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/pumpify/-/pumpify-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-2.0.1.tgz#abfc7b5a621307c728b551decbbefb51f0e4aa1e" integrity sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw== dependencies: duplexify "^4.1.1" @@ -9109,39 +9545,39 @@ pure-rand@^6.0.0: q@^1.5.1: version "1.5.1" - resolved "https://registry.npmjs.org/q/-/q-1.5.1.tgz" + resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" integrity sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw== qs@6.11.0: version "6.11.0" - resolved "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== dependencies: side-channel "^1.0.4" queue-microtask@^1.1.2, queue-microtask@^1.2.2: version "1.2.3" - resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== quick-format-unescaped@^4.0.3: version "4.0.4" - resolved "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz" + resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz#93ef6dd8d3453cbc7970dd614fad4c5954d6b5a7" integrity sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg== quick-lru@^4.0.1: version "4.0.1" - resolved "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== ramda@^0.24.1: version "0.24.1" - resolved "https://registry.npmjs.org/ramda/-/ramda-0.24.1.tgz" + resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.24.1.tgz#c3b7755197f35b8dc3502228262c4c91ddb6b857" integrity sha512-HEm619G8PaZMfkqCa23qiOe7r3R0brPu7ZgOsgKUsnvLhd0qhc/vTjkUovomgPWa5ECBa08fJZixth9LaoBo5w== ramdasauce@^2.1.0: version "2.1.3" - resolved "https://registry.npmjs.org/ramdasauce/-/ramdasauce-2.1.3.tgz" + resolved "https://registry.yarnpkg.com/ramdasauce/-/ramdasauce-2.1.3.tgz#acb45ecc7e4fc4d6f39e19989b4a16dff383e9c2" integrity sha512-Ml3CPim4SKwmg5g9UI77lnRSeKr/kQw7YhQ6rfdMcBYy6DMlwmkEwQqjygJ3OhxPR+NfFfpjKl3Tf8GXckaqqg== dependencies: ramda "^0.24.1" @@ -9155,14 +9591,21 @@ randomatic@^3.0.0: kind-of "^6.0.0" math-random "^1.0.1" +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + range-parser@~1.2.1: version "1.2.1" - resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== raw-body@2.5.1: version "2.5.1" - resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== dependencies: bytes "3.1.2" @@ -9170,9 +9613,9 @@ raw-body@2.5.1: iconv-lite "0.4.24" unpipe "1.0.0" -raw-body@2.5.2: +raw-body@2.5.2, raw-body@^2.4.1: version "2.5.2" - resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== dependencies: bytes "3.1.2" @@ -9187,12 +9630,12 @@ react-is@^18.0.0: read-cmd-shim@^3.0.0: version "3.0.1" - resolved "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-3.0.1.tgz" + resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-3.0.1.tgz#868c235ec59d1de2db69e11aec885bc095aea087" integrity sha512-kEmDUoYf/CDy8yZbLTmhB1X9kkjf9Q80PCNsDMb7ufrGd6zZSQA1+UyjrO+pZm5K/S4OXCWJeiIt1JA8kAsa6g== read-package-json-fast@^2.0.2, read-package-json-fast@^2.0.3: version "2.0.3" - resolved "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-2.0.3.tgz" + resolved "https://registry.yarnpkg.com/read-package-json-fast/-/read-package-json-fast-2.0.3.tgz#323ca529630da82cb34b36cc0b996693c98c2b83" integrity sha512-W/BKtbL+dUjTuRL2vziuYhp76s5HZ9qQhd/dKfWIZveD0O40453QNyZhC0e63lqZrAQ4jiOapVoeJ7JrszenQQ== dependencies: json-parse-even-better-errors "^2.3.0" @@ -9200,7 +9643,7 @@ read-package-json-fast@^2.0.2, read-package-json-fast@^2.0.3: read-package-json@^5.0.0, read-package-json@^5.0.1: version "5.0.2" - resolved "https://registry.npmjs.org/read-package-json/-/read-package-json-5.0.2.tgz" + resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-5.0.2.tgz#b8779ccfd169f523b67208a89cc912e3f663f3fa" integrity sha512-BSzugrt4kQ/Z0krro8zhTwV1Kd79ue25IhNN/VtHFy1mG/6Tluyi+msc0UpwaoQzxSHa28mntAjIZY6kEgfR9Q== dependencies: glob "^8.0.1" @@ -9210,7 +9653,7 @@ read-package-json@^5.0.0, read-package-json@^5.0.1: read-pkg-up@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" integrity sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw== dependencies: find-up "^2.0.0" @@ -9218,7 +9661,7 @@ read-pkg-up@^3.0.0: read-pkg-up@^7.0.1: version "7.0.1" - resolved "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg== dependencies: find-up "^4.1.0" @@ -9227,7 +9670,7 @@ read-pkg-up@^7.0.1: read-pkg@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" integrity sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA== dependencies: load-json-file "^4.0.0" @@ -9236,7 +9679,7 @@ read-pkg@^3.0.0: read-pkg@^5.2.0: version "5.2.0" - resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== dependencies: "@types/normalize-package-data" "^2.4.0" @@ -9246,14 +9689,14 @@ read-pkg@^5.2.0: read@1, read@^1.0.7: version "1.0.7" - resolved "https://registry.npmjs.org/read/-/read-1.0.7.tgz" + resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" integrity sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ== dependencies: mute-stream "~0.0.4" "readable-stream@2 || 3", readable-stream@3, readable-stream@^3.0.0, readable-stream@^3.0.2, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: version "3.6.2" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== dependencies: inherits "^2.0.3" @@ -9262,7 +9705,7 @@ read@1, read@^1.0.7: readable-stream@^2.0.2, readable-stream@~2.3.6: version "2.3.8" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== dependencies: core-util-is "~1.0.0" @@ -9275,7 +9718,7 @@ readable-stream@^2.0.2, readable-stream@~2.3.6: readdir-scoped-modules@^1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz" + resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz#8d45407b4f870a0dcaebc0e28670d18e74514309" integrity sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw== dependencies: debuglog "^1.0.1" @@ -9292,14 +9735,26 @@ readdirp@^2.0.0: micromatch "^3.1.10" readable-stream "^2.0.2" +readdirp@^4.0.1: + version "4.1.2" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-4.1.2.tgz#eb85801435fbf2a7ee58f19e0921b068fc69948d" + integrity sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg== + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + real-require@^0.1.0: version "0.1.0" - resolved "https://registry.npmjs.org/real-require/-/real-require-0.1.0.tgz" + resolved "https://registry.yarnpkg.com/real-require/-/real-require-0.1.0.tgz#736ac214caa20632847b7ca8c1056a0767df9381" integrity sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg== redent@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" integrity sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg== dependencies: indent-string "^4.0.0" @@ -9359,29 +9814,29 @@ repeating@^2.0.0: require-directory@^2.1.1: version "2.1.1" - resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== require-from-string@^2.0.2: version "2.0.2" - resolved "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== resolve-cwd@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== dependencies: resolve-from "^5.0.0" resolve-from@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== resolve-from@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== resolve-url@^0.2.1: @@ -9390,31 +9845,29 @@ resolve-url@^0.2.1: integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== resolve.exports@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800" - integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg== + version "2.0.3" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.3.tgz#41955e6f1b4013b7586f873749a635dea07ebe3f" + integrity sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A== -resolve@^1.10.0: - version "1.22.6" - resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.6.tgz" - integrity sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw== +resolve@1.17.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" + integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== dependencies: - is-core-module "^2.13.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" + path-parse "^1.0.6" -resolve@^1.20.0: - version "1.22.8" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" - integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== +resolve@^1.10.0, resolve@^1.20.0, resolve@~1.22.1: + version "1.22.10" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.10.tgz#b663e83ffb09bbf2386944736baae803029b8b39" + integrity sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w== dependencies: - is-core-module "^2.13.0" + is-core-module "^2.16.0" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" restore-cursor@^3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== dependencies: onetime "^5.1.0" @@ -9427,87 +9880,87 @@ ret@~0.1.10: ret@~0.2.0: version "0.2.2" - resolved "https://registry.npmjs.org/ret/-/ret-0.2.2.tgz" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.2.2.tgz#b6861782a1f4762dce43402a71eb7a283f44573c" integrity sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ== retry-as-promised@^7.0.4: - version "7.0.4" - resolved "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-7.0.4.tgz" - integrity sha512-XgmCoxKWkDofwH8WddD0w85ZfqYz+ZHlr5yo+3YUCfycWawU56T5ckWXsScsj5B8tqUcIG67DxXByo3VUgiAdA== + version "7.1.1" + resolved "https://registry.yarnpkg.com/retry-as-promised/-/retry-as-promised-7.1.1.tgz#3626246f04c1941ff10cebcfa3df0577fd8ab2d7" + integrity sha512-hMD7odLOt3LkTjcif8aRZqi/hybjpLNgSk5oF5FCowfCjok6LukpN2bDX7R5wDmbgBQFn7YoBxSagmtXHaJYJw== retry@^0.12.0: version "0.12.0" - resolved "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== retry@^0.13.1: version "0.13.1" - resolved "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + version "1.1.0" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.1.0.tgz#0fe13b9522e1473f51b558ee796e08f11f9b489f" + integrity sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw== rfdc@^1.1.4, rfdc@^1.2.0: - version "1.3.0" - resolved "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz" - integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== + version "1.4.1" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.4.1.tgz#778f76c4fb731d93414e8f925fbecf64cce7f6ca" + integrity sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA== rimraf@^2.6.3: version "2.7.1" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== dependencies: glob "^7.1.3" rimraf@^3.0.0, rimraf@^3.0.2: version "3.0.2" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== dependencies: glob "^7.1.3" run-async@^2.4.0: version "2.4.1" - resolved "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== run-exclusive@^2.2.14: version "2.2.19" - resolved "https://registry.npmjs.org/run-exclusive/-/run-exclusive-2.2.19.tgz" + resolved "https://registry.yarnpkg.com/run-exclusive/-/run-exclusive-2.2.19.tgz#37a2fb6e3671f8ae0d63521ebd1865fc796cf307" integrity sha512-K3mdoAi7tjJ/qT7Flj90L7QyPozwUaAG+CVhkdDje4HLKXUYC3N/Jzkau3flHVDLQVhiHBtcimVodMjN9egYbA== dependencies: minimal-polyfills "^2.2.3" run-parallel@^1.1.9: version "1.2.0" - resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" + 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.5.5: - version "7.8.1" - resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz" - integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== + version "7.8.2" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.2.tgz#955bc473ed8af11a002a2be52071bf475638607b" + integrity sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA== dependencies: tslib "^2.1.0" safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@~5.2.0: +safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0: version "5.2.1" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== safe-regex2@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/safe-regex2/-/safe-regex2-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/safe-regex2/-/safe-regex2-2.0.0.tgz#b287524c397c7a2994470367e0185e1916b1f5b9" integrity sha512-PaUSFsUaNNuKwkBijoAPHAK6/eM6VirvyPWlZ7BAQy4D+hCvh4B6lIG+nPdhbFfIbP+gTGBcrdsOaUs0F+ZBOQ== dependencies: ret "~0.2.0" @@ -9520,60 +9973,50 @@ safe-regex@^1.1.0: ret "~0.1.10" safe-stable-stringify@^2.1.0: - version "2.4.3" - resolved "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz" - integrity sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g== + version "2.5.0" + resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz#4ca2f8e385f2831c432a719b108a3bf7af42a1dd" + integrity sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA== "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" - resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -scrypt-js@3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz" - integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== - secure-json-parse@^2.0.0: version "2.7.0" - resolved "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz" + resolved "https://registry.yarnpkg.com/secure-json-parse/-/secure-json-parse-2.7.0.tgz#5a5f9cd6ae47df23dba3151edd06855d47e09862" integrity sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw== semver-store@^0.3.0: version "0.3.0" - resolved "https://registry.npmjs.org/semver-store/-/semver-store-0.3.0.tgz" + resolved "https://registry.yarnpkg.com/semver-store/-/semver-store-0.3.0.tgz#ce602ff07df37080ec9f4fb40b29576547befbe9" integrity sha512-TcZvGMMy9vodEFSse30lWinkj+JgOBvPn8wRItpQRSayhc+4ssDs335uklkfvQQJgL/WvmHLVj4Ycv2s7QCQMg== -"semver@2 || 3 || 4 || 5", semver@^5.6.0: +"semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.6.0: version "5.7.2" - resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -semver@7.5.4, semver@^7.0.0, semver@^7.1.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.5.4: +semver@7.5.4, semver@~7.5.4: version "7.5.4" - resolved "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0" semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: version "6.3.1" - resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.5.3: - version "7.6.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.1.tgz#60bfe090bf907a25aa8119a72b9f90ef7ca281b2" - integrity sha512-f/vbBsu+fOiYt+lmwZV0rVwJScl46HppnOA1ZvIuBWKOTlllpyJ3bfVax76/OrhCH38dyxoDIA8K7uB963IYgA== - -semver@^7.6.3: - version "7.6.3" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" - integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== +semver@^7.0.0, semver@^7.1.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.5.3, semver@^7.5.4, semver@^7.7.2: + version "7.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.2.tgz#67d99fdcd35cec21e6f8b87a7fd515a33f982b58" + integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA== send@0.18.0: version "0.18.0" - resolved "https://registry.npmjs.org/send/-/send-0.18.0.tgz" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== dependencies: debug "2.6.9" @@ -9592,12 +10035,12 @@ send@0.18.0: sequelize-pool@^7.1.0: version "7.1.0" - resolved "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-7.1.0.tgz" + resolved "https://registry.yarnpkg.com/sequelize-pool/-/sequelize-pool-7.1.0.tgz#210b391af4002762f823188fd6ecfc7413020768" integrity sha512-G9c0qlIWQSK29pR/5U2JF5dDQeqqHRragoyahj/Nx4KOOQ3CPPfzxnfqFPCSB7x5UgjOgnZ61nSxz+fjDpRlJg== sequelize@6.33.0: version "6.33.0" - resolved "https://registry.npmjs.org/sequelize/-/sequelize-6.33.0.tgz" + resolved "https://registry.yarnpkg.com/sequelize/-/sequelize-6.33.0.tgz#45c70d52687f1c7eae3a0496f21f7055d99b46da" integrity sha512-GkeCbqgaIcpyZ1EyXrDNIwktbfMldHAGOVXHGM4x8bxGSRAOql5htDWofPvwpfL/FoZ59CaFmfO3Mosv1lDbQw== dependencies: "@types/debug" "^4.1.8" @@ -9617,9 +10060,16 @@ sequelize@6.33.0: validator "^13.9.0" wkx "^0.5.0" +serialize-javascript@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" + integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== + dependencies: + randombytes "^2.1.0" + serve-static@1.15.0: version "1.15.0" - resolved "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== dependencies: encodeurl "~1.0.2" @@ -9629,13 +10079,13 @@ serve-static@1.15.0: set-blocking@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== set-cookie-parser@^2.4.1: - version "2.6.0" - resolved "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz" - integrity sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ== + version "2.7.1" + resolved "https://registry.yarnpkg.com/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz#3016f150072202dfbe90fadee053573cc89d2943" + integrity sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ== set-value@^2.0.0, set-value@^2.0.1: version "2.0.1" @@ -9649,52 +10099,78 @@ set-value@^2.0.0, set-value@^2.0.1: setprototypeof@1.2.0: version "1.2.0" - resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== shallow-clone@^3.0.0: version "3.0.1" - resolved "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== dependencies: kind-of "^6.0.2" shebang-command@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== dependencies: shebang-regex "^3.0.0" shebang-regex@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== +side-channel-list@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/side-channel-list/-/side-channel-list-1.0.0.tgz#10cb5984263115d3b7a0e336591e290a830af8ad" + integrity sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA== + dependencies: + es-errors "^1.3.0" + object-inspect "^1.13.3" + +side-channel-map@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/side-channel-map/-/side-channel-map-1.0.1.tgz#d6bb6b37902c6fef5174e5f533fab4c732a26f42" + integrity sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA== + dependencies: + call-bound "^1.0.2" + es-errors "^1.3.0" + get-intrinsic "^1.2.5" + object-inspect "^1.13.3" + +side-channel-weakmap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz#11dda19d5368e40ce9ec2bdc1fb0ecbc0790ecea" + integrity sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A== + dependencies: + call-bound "^1.0.2" + es-errors "^1.3.0" + get-intrinsic "^1.2.5" + object-inspect "^1.13.3" + side-channel-map "^1.0.1" + side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + version "1.1.0" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.1.0.tgz#c3fcff9c4da932784873335ec9765fa94ff66bc9" + integrity sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw== dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" + es-errors "^1.3.0" + object-inspect "^1.13.3" + side-channel-list "^1.0.0" + side-channel-map "^1.0.1" + side-channel-weakmap "^1.0.2" signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" - resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== signal-exit@^4.0.1: version "4.1.0" - resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== -simple-wcswidth@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/simple-wcswidth/-/simple-wcswidth-1.0.1.tgz" - integrity sha512-xMO/8eNREtaROt7tJvWJqHBDTMFN4eiQ5I4JRMuilwfnFcV5W9u7RUkueNkdw0jPqGMX36iCywelS5yilTuOxg== - sisteransi@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" @@ -9707,12 +10183,12 @@ slash@^1.0.0: slash@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" + 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.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== dependencies: ansi-styles "^4.0.0" @@ -9721,7 +10197,7 @@ slice-ansi@^4.0.0: smart-buffer@^4.2.0: version "4.2.0" - resolved "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== snapdragon-node@^2.0.1: @@ -9756,7 +10232,7 @@ snapdragon@^0.8.1: socks-proxy-agent@^7.0.0: version "7.0.0" - resolved "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz#dc069ecf34436621acb41e3efa66ca1b5fed15b6" integrity sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww== dependencies: agent-base "^6.0.2" @@ -9764,16 +10240,29 @@ socks-proxy-agent@^7.0.0: socks "^2.6.2" socks@^2.6.2: - version "2.7.1" - resolved "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz" - integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ== + version "2.8.4" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.8.4.tgz#07109755cdd4da03269bda4725baa061ab56d5cc" + integrity sha512-D3YaD0aRxR3mEcqnidIs7ReYJFVzWdd6fXJYUM8ixcQcJRGTka/b3saV0KflYhyVJXKhb947GndU35SxYNResQ== dependencies: - ip "^2.0.0" + ip-address "^9.0.5" smart-buffer "^4.2.0" +solc@0.8.26: + version "0.8.26" + resolved "https://registry.yarnpkg.com/solc/-/solc-0.8.26.tgz#afc78078953f6ab3e727c338a2fefcd80dd5b01a" + integrity sha512-yiPQNVf5rBFHwN6SIf3TUUvVAFKcQqmSUFeq+fb6pNRCo0ZCgpYOZDi3BVoezCPIAcKrVYd/qXlBLUP9wVrZ9g== + dependencies: + command-exists "^1.2.8" + commander "^8.1.0" + follow-redirects "^1.12.1" + js-sha3 "0.8.0" + memorystream "^0.3.1" + semver "^5.5.0" + tmp "0.0.33" + sonic-boom@^1.0.2: version "1.4.1" - resolved "https://registry.npmjs.org/sonic-boom/-/sonic-boom-1.4.1.tgz" + resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-1.4.1.tgz#d35d6a74076624f12e6f917ade7b9d75e918f53e" integrity sha512-LRHh/A8tpW7ru89lrlkU4AszXt1dbwSjVWguGrmlxE7tawVmDBlI1PILMkXAxJTwqhgsEeTHzj36D5CmHgQmNg== dependencies: atomic-sleep "^1.0.0" @@ -9781,21 +10270,21 @@ sonic-boom@^1.0.2: sonic-boom@^2.2.1: version "2.8.0" - resolved "https://registry.npmjs.org/sonic-boom/-/sonic-boom-2.8.0.tgz" + resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-2.8.0.tgz#c1def62a77425090e6ad7516aad8eb402e047611" integrity sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg== dependencies: atomic-sleep "^1.0.0" sort-keys@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" integrity sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg== dependencies: is-plain-obj "^1.0.0" sort-keys@^4.0.0: version "4.2.0" - resolved "https://registry.npmjs.org/sort-keys/-/sort-keys-4.2.0.tgz" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-4.2.0.tgz#6b7638cee42c506fff8c1cecde7376d21315be18" integrity sha512-aUYIEU/UviqPgc8mHR6IW1EGxkAXpeRETYcrzg8cLAvUPZcpAlleSXHV2mY7G12GphSH6Gzv+4MMVSSkbdteHg== dependencies: is-plain-obj "^2.0.0" @@ -9826,6 +10315,14 @@ source-map-support@^0.4.15: dependencies: source-map "^0.5.6" +source-map-support@^0.5.13: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + source-map-url@^0.4.0: version "0.4.1" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" @@ -9838,34 +10335,34 @@ source-map@^0.5.6, source-map@^0.5.7: source-map@^0.6.0, source-map@^0.6.1: version "0.6.1" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== spdx-correct@^3.0.0: version "3.2.0" - resolved "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.2.0.tgz#4f5ab0668f0059e34f9c00dce331784a12de4e9c" integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== dependencies: spdx-expression-parse "^3.0.0" spdx-license-ids "^3.0.0" spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + version "2.5.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz#5d607d27fc806f66d7b64a766650fa890f04ed66" + integrity sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w== spdx-expression-parse@^3.0.0: version "3.0.1" - resolved "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== dependencies: spdx-exceptions "^2.1.0" spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.14" - resolved "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.14.tgz" - integrity sha512-U0eS5wcpu/O2/QZk6PcAMOA8H3ZuvRe4mFHA3Q+LNl1SRDmfQ+mD3RoD6tItqnvqubJ32m/zV2Z/ikSmxccD1Q== + version "3.0.21" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz#6d6e980c9df2b6fc905343a3b2d702a6239536c3" + integrity sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg== split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" @@ -9876,38 +10373,36 @@ split-string@^3.0.1, split-string@^3.0.2: split2@^3.0.0, split2@^3.1.1: version "3.2.2" - resolved "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz" + resolved "https://registry.yarnpkg.com/split2/-/split2-3.2.2.tgz#bf2cf2a37d838312c249c89206fd7a17dd12365f" integrity sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg== dependencies: readable-stream "^3.0.0" split2@^4.0.0, split2@^4.1.0: version "4.2.0" - resolved "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz" + resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== split@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/split/-/split-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" integrity sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg== dependencies: through "2" +sprintf-js@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.3.tgz#4914b903a2f8b685d17fdf78a70e917e872e444a" + integrity sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA== + sprintf-js@~1.0.2: version "1.0.3" - resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== -ssri@^10.0.0: - version "10.0.5" - resolved "https://registry.npmjs.org/ssri/-/ssri-10.0.5.tgz" - integrity sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A== - dependencies: - minipass "^7.0.3" - ssri@^9.0.0, ssri@^9.0.1: version "9.0.1" - resolved "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-9.0.1.tgz#544d4c357a8d7b71a19700074b6883fcb4eae057" integrity sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q== dependencies: minipass "^3.1.1" @@ -9919,6 +10414,13 @@ stack-utils@^2.0.3: dependencies: escape-string-regexp "^2.0.0" +stacktrace-parser@^0.1.10: + version "0.1.11" + resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.11.tgz#c7c08f9b29ef566b9a6f7b255d7db572f66fabc4" + integrity sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg== + dependencies: + type-fest "^0.7.1" + static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" @@ -9929,17 +10431,17 @@ static-extend@^0.1.1: statuses@2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== -stream-shift@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz" - integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== +stream-shift@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.3.tgz#85b8fab4d71010fc3ba8772e8046cc49b8a3864b" + integrity sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ== string-argv@~0.3.1: version "0.3.2" - resolved "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz" + resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.2.tgz#2b6d0ef24b656274d957d54e0a4bbf6153dc02b6" integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q== string-format@^2.0.0: @@ -9957,21 +10459,21 @@ string-length@^4.0.1: string-similarity@^4.0.1: version "4.0.4" - resolved "https://registry.npmjs.org/string-similarity/-/string-similarity-4.0.4.tgz" + resolved "https://registry.yarnpkg.com/string-similarity/-/string-similarity-4.0.4.tgz#42d01ab0b34660ea8a018da8f56a3309bb8b2a5b" integrity sha512-/q/8Q4Bl4ZKAPjj8WerIBJWALKkaPRfrvhfF8k/B23i4nzrlRj2/go1m90In7nG/3XDSbOo0+pu6RvCTM9RGMQ== "string-width-cjs@npm:string-width@^4.2.0": version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: emoji-regex "^8.0.0" is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: emoji-regex "^8.0.0" @@ -9980,7 +10482,7 @@ string-similarity@^4.0.1: string-width@^2.1.1: version "2.1.1" - resolved "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== dependencies: is-fullwidth-code-point "^2.0.0" @@ -9988,30 +10490,39 @@ string-width@^2.1.1: string-width@^5.0.1, string-width@^5.1.2: version "5.1.2" - resolved "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== dependencies: eastasianwidth "^0.2.0" emoji-regex "^9.2.2" strip-ansi "^7.0.1" +string-width@^7.0.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-7.2.0.tgz#b5bb8e2165ce275d4d43476dd2700ad9091db6dc" + integrity sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ== + dependencies: + emoji-regex "^10.3.0" + get-east-asian-width "^1.0.0" + strip-ansi "^7.1.0" + string_decoder@^1.1.1: version "1.3.0" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== dependencies: safe-buffer "~5.2.0" string_decoder@~1.1.1: version "1.1.1" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== dependencies: safe-buffer "~5.1.0" "strip-ansi-cjs@npm:strip-ansi@^6.0.1": version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: ansi-regex "^5.0.1" @@ -10025,43 +10536,43 @@ strip-ansi@^3.0.0: strip-ansi@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" integrity sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow== dependencies: ansi-regex "^3.0.0" strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: ansi-regex "^5.0.1" -strip-ansi@^7.0.1: +strip-ansi@^7.0.1, strip-ansi@^7.1.0: version "7.1.0" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== dependencies: ansi-regex "^6.0.1" strip-bom@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== strip-bom@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== strip-final-newline@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== strip-indent@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ== dependencies: min-indent "^1.0.0" @@ -10073,7 +10584,7 @@ strip-json-comments@^3.1.1: strong-log-transformer@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz#0f5ed78d325e0421ac6f90f7f10e691d6ae3ae10" integrity sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA== dependencies: duplexer "^0.1.1" @@ -10087,19 +10598,19 @@ supports-color@^2.0.0: supports-color@^5.3.0: version "5.5.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== dependencies: has-flag "^3.0.0" supports-color@^7.1.0: version "7.2.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== dependencies: has-flag "^4.0.0" -supports-color@^8.0.0: +supports-color@^8.0.0, supports-color@^8.1.1, supports-color@~8.1.1: version "8.1.1" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== @@ -10108,7 +10619,7 @@ supports-color@^8.0.0: supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== table-layout@^1.0.2: @@ -10123,7 +10634,7 @@ table-layout@^1.0.2: table@6.7.5: version "6.7.5" - resolved "https://registry.npmjs.org/table/-/table-6.7.5.tgz" + resolved "https://registry.yarnpkg.com/table/-/table-6.7.5.tgz#f04478c351ef3d8c7904f0e8be90a1b62417d238" integrity sha512-LFNeryOqiQHqCVKzhkymKwt6ozeRhlm8IL1mE8rNUurkir4heF6PzMyRgaTa4tlyPTGGgXuvVOF/OLWiH09Lqw== dependencies: ajv "^8.0.1" @@ -10134,7 +10645,7 @@ table@6.7.5: tar-stream@~2.2.0: version "2.2.0" - resolved "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== dependencies: bl "^4.0.3" @@ -10144,9 +10655,9 @@ tar-stream@~2.2.0: readable-stream "^3.1.1" tar@^6.1.0, tar@^6.1.11, tar@^6.1.2: - version "6.2.0" - resolved "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz" - integrity sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ== + version "6.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a" + integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A== dependencies: chownr "^2.0.0" fs-minipass "^2.0.0" @@ -10157,14 +10668,14 @@ tar@^6.1.0, tar@^6.1.11, tar@^6.1.2: tdigest@^0.1.1: version "0.1.2" - resolved "https://registry.npmjs.org/tdigest/-/tdigest-0.1.2.tgz" + resolved "https://registry.yarnpkg.com/tdigest/-/tdigest-0.1.2.tgz#96c64bac4ff10746b910b0e23b515794e12faced" integrity sha512-+G0LLgjjo9BZX2MfdvPfH+MKLCrxlXSYec5DaPYP1fe6Iyhf0/fSmJ0bFiZ1F8BT6cGXl2LpltQptzjXKWEkKA== dependencies: bintrees "1.0.2" temp-dir@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" integrity sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ== test-exclude@^6.0.0: @@ -10178,7 +10689,7 @@ test-exclude@^6.0.0: text-extensions@^1.0.0: version "1.9.0" - resolved "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz" + resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26" integrity sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ== text-table@^0.2.0: @@ -10188,21 +10699,21 @@ text-table@^0.2.0: thread-stream@^0.13.0: version "0.13.2" - resolved "https://registry.npmjs.org/thread-stream/-/thread-stream-0.13.2.tgz" + resolved "https://registry.yarnpkg.com/thread-stream/-/thread-stream-0.13.2.tgz#de8ea87584baee625c631947ec73494aa86131c8" integrity sha512-woZFt0cLFkPdhsa+IGpRo1jiSouaHxMIljzTgt30CMjBWoUYbbcHqnunW5Yv+BXko9H05MVIcxMipI3Jblallw== dependencies: real-require "^0.1.0" thread-stream@^0.15.1: version "0.15.2" - resolved "https://registry.npmjs.org/thread-stream/-/thread-stream-0.15.2.tgz" + resolved "https://registry.yarnpkg.com/thread-stream/-/thread-stream-0.15.2.tgz#fb95ad87d2f1e28f07116eb23d85aba3bc0425f4" integrity sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA== dependencies: real-require "^0.1.0" through2@^2.0.0: version "2.0.5" - resolved "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== dependencies: readable-stream "~2.3.6" @@ -10210,7 +10721,7 @@ through2@^2.0.0: through2@^3.0.1: version "3.0.2" - resolved "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz" + resolved "https://registry.yarnpkg.com/through2/-/through2-3.0.2.tgz#99f88931cfc761ec7678b41d5d7336b5b6a07bf4" integrity sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ== dependencies: inherits "^2.0.4" @@ -10218,34 +10729,40 @@ through2@^3.0.1: through2@^4.0.0: version "4.0.2" - resolved "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz" + resolved "https://registry.yarnpkg.com/through2/-/through2-4.0.2.tgz#a7ce3ac2a7a8b0b966c80e7c49f0484c3b239764" integrity sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw== dependencies: readable-stream "3" through@2, "through@>=2.2.7 <3", through@^2.3.4, through@^2.3.6: version "2.3.8" - resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== tiny-lru@^7.0.0: version "7.0.6" - resolved "https://registry.npmjs.org/tiny-lru/-/tiny-lru-7.0.6.tgz" + resolved "https://registry.yarnpkg.com/tiny-lru/-/tiny-lru-7.0.6.tgz#b0c3cdede1e5882aa2d1ae21cb2ceccf2a331f24" integrity sha512-zNYO0Kvgn5rXzWpL0y3RS09sMK67eGaQj9805jlK9G6pSadfriTczzLHFXa/xcW4mIRfmlB9HyQ/+SgL0V1uow== -tmp@^0.0.33: +tinyglobby@^0.2.6: + version "0.2.13" + resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.13.tgz#a0e46515ce6cbcd65331537e57484af5a7b2ff7e" + integrity sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw== + dependencies: + fdir "^6.4.4" + picomatch "^4.0.2" + +tmp@0.0.33, tmp@^0.0.33: version "0.0.33" - resolved "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== dependencies: os-tmpdir "~1.0.2" tmp@~0.2.1: - version "0.2.1" - resolved "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz" - integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== - dependencies: - rimraf "^3.0.0" + version "0.2.3" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.3.tgz#eb783cc22bc1e8bebd0671476d46ea4eb32a79ae" + integrity sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w== tmpl@1.0.5: version "1.0.5" @@ -10257,11 +10774,6 @@ to-fast-properties@^1.0.3: resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" integrity sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og== -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== - to-object-path@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" @@ -10279,7 +10791,7 @@ to-regex-range@^2.1.0: to-regex-range@^5.0.1: version "5.0.1" - resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== dependencies: is-number "^7.0.0" @@ -10296,27 +10808,27 @@ to-regex@^3.0.1, to-regex@^3.0.2: toidentifier@1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== toposort-class@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/toposort-class/-/toposort-class-1.0.1.tgz#7ffd1f78c8be28c3ba45cd4e1a3f5ee193bd9988" integrity sha512-OsLcGGbYF3rMjPUf8oKktyvCiUxSbqMMS39m33MAjLTC1DVIH6x3WSt63/M77ihI09+Sdfk1AXvfhCEeUmC7mg== tr46@~0.0.3: version "0.0.3" - resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== treeverse@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/treeverse/-/treeverse-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/treeverse/-/treeverse-2.0.0.tgz#036dcef04bc3fd79a9b79a68d4da03e882d8a9ca" integrity sha512-N5gJCkLu1aXccpOTtqV6ddSEi6ZmGkh3hjmbu1IjcavJK4qyOVQmi0myQKM7z5jVGmD68SJoliaVrMmVObhj6A== trim-newlines@^3.0.0: version "3.0.1" - resolved "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144" integrity sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw== trim-right@^1.0.1: @@ -10325,9 +10837,9 @@ trim-right@^1.0.1: integrity sha512-WZGXGstmCWgeevgTL54hrCuw1dyMQIzWy7ZfqRJfSmJZBwklI15egmQytFP6bPidmw3M8d5yEowl1niq4vmqZw== ts-api-utils@^1.0.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1" - integrity sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ== + version "1.4.3" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.4.3.tgz#bfc2215fe6528fecab2b0fba570a2e8a4263b064" + integrity sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw== ts-command-line-args@^2.2.0: version "2.5.1" @@ -10341,7 +10853,7 @@ ts-command-line-args@^2.2.0: ts-custom-error@^3.3.1: version "3.3.1" - resolved "https://registry.npmjs.org/ts-custom-error/-/ts-custom-error-3.3.1.tgz" + resolved "https://registry.yarnpkg.com/ts-custom-error/-/ts-custom-error-3.3.1.tgz#8bd3c8fc6b8dc8e1cb329267c45200f1e17a65d1" integrity sha512-5OX1tzOjxWEgsr/YEUWSuPrQ00deKLh6D7OTWcvNHm12/7QPyRh8SYpyWvA4IZv8H/+GQWQEh/kwo95Q9OVW1A== ts-essentials@^7.0.1: @@ -10364,9 +10876,9 @@ ts-jest@29.1.1: yargs-parser "^21.0.1" ts-jest@^29.2.5: - version "29.2.5" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.2.5.tgz#591a3c108e1f5ebd013d3152142cb5472b399d63" - integrity sha512-KD8zB2aAZrcKIdGk4OwpJggeLcH1FgrICqDSROWqlnJXGCXK4Mn6FcdK2B6670Xr73lHMG1kHw8R87A0ecZ+vA== + version "29.3.3" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.3.3.tgz#c24c31a9d12268f88899e3eeb05912cab42c574c" + integrity sha512-y6jLm19SL4GroiBmHwFK4dSHUfDNmOrJbRfp6QmDIlI9p5tT5Q8ItccB4pTIslCIqOZuQnBwpTR0bQ5eUMYwkw== dependencies: bs-logger "^0.2.6" ejs "^3.1.10" @@ -10375,7 +10887,8 @@ ts-jest@^29.2.5: json5 "^2.2.3" lodash.memoize "^4.1.2" make-error "^1.3.6" - semver "^7.6.3" + semver "^7.7.2" + type-fest "^4.41.0" yargs-parser "^21.1.1" ts-node@10.7.0: @@ -10399,22 +10912,32 @@ ts-node@10.7.0: tsconfig-paths@^4.1.2: version "4.2.0" - resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz#ef78e19039133446d244beac0fd6a1632e2d107c" integrity sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg== dependencies: json5 "^2.2.2" minimist "^1.2.6" strip-bom "^3.0.0" +tslib@2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01" + integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA== + tslib@^1.9.3: version "1.14.1" - resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== tslib@^2.1.0, tslib@^2.3.0, tslib@^2.3.1, tslib@^2.4.0: - version "2.6.2" - resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz" - integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + version "2.8.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== + +tsort@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/tsort/-/tsort-0.0.1.tgz#e2280f5e817f8bf4275657fd0f9aebd44f5a2786" + integrity sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw== type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" @@ -10430,7 +10953,7 @@ type-detect@4.0.8: type-fest@^0.18.0: version "0.18.1" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.18.1.tgz#db4bc151a4a2cf4eebf9add5db75508db6cc841f" integrity sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw== type-fest@^0.20.2: @@ -10440,32 +10963,42 @@ type-fest@^0.20.2: type-fest@^0.21.3: version "0.21.3" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== type-fest@^0.4.1: version "0.4.1" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.4.1.tgz" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.4.1.tgz#8bdf77743385d8a4f13ba95f610f5ccd68c728f8" integrity sha512-IwzA/LSfD2vC1/YDYMv/zHP4rDF1usCwllsDpbolT3D4fUepIO7f9K70jjmUewU/LmGUKJcwcVtDCpnKk4BPMw== type-fest@^0.6.0: version "0.6.0" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== +type-fest@^0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" + integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== + type-fest@^0.8.1: version "0.8.1" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== type-fest@^2.0.0: version "2.19.0" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== +type-fest@^4.41.0: + version "4.41.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.41.0.tgz#6ae1c8e5731273c2bf1f58ad39cbae2c91a46c58" + integrity sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA== + type-is@~1.6.18: version "1.6.18" - resolved "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== dependencies: media-typer "0.3.0" @@ -10489,14 +11022,14 @@ typechain@8.0.0: typedarray-to-buffer@^3.1.5: version "3.1.5" - resolved "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== dependencies: is-typedarray "^1.0.0" typedarray@^0.0.6: version "0.0.6" - resolved "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== typescript@5.2.2: @@ -10506,7 +11039,7 @@ typescript@5.2.2: "typescript@^3 || ^4": version "4.9.5" - resolved "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== typical@^4.0.0: @@ -10520,13 +11053,13 @@ typical@^5.2.0: integrity sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg== uglify-js@^3.1.4: - version "3.17.4" - resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz" - integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== + version "3.19.3" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.19.3.tgz#82315e9bbc6f2b25888858acd1fff8441035b77f" + integrity sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ== umzug@3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/umzug/-/umzug-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/umzug/-/umzug-3.0.0.tgz#de19183c0bce7e79d432f746ad423b68b38d485a" integrity sha512-uHeJsOJ7qtoIkZmtknpg+iSlI25m7glBA237pYp5fMsEKnRfRY+F4FP8eGx28g6b0VujkniC6Zlz09lbDFuBbw== dependencies: "@rushstack/ts-command-line" "^4.7.7" @@ -10538,9 +11071,31 @@ umzug@3.0.0: verror "^1.10.0" underscore@^1.13.1: - version "1.13.6" - resolved "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz" - integrity sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A== + version "1.13.7" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.7.tgz#970e33963af9a7dda228f17ebe8399e5fbe63a10" + integrity sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g== + +undici-types@~6.19.2: + version "6.19.8" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" + integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== + +undici-types@~6.20.0: + version "6.20.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.20.0.tgz#8171bf22c1f588d1554d55bf204bc624af388433" + integrity sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg== + +undici-types@~6.21.0: + version "6.21.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.21.0.tgz#691d00af3909be93a7faa13be61b3a5b50ef12cb" + integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ== + +undici@^5.14.0: + version "5.29.0" + resolved "https://registry.yarnpkg.com/undici/-/undici-5.29.0.tgz#419595449ae3f2cdcba3580a2e8903399bd1f5a3" + integrity sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg== + dependencies: + "@fastify/busboy" "^2.0.0" union-value@^1.0.0: version "1.0.1" @@ -10554,36 +11109,22 @@ union-value@^1.0.0: unique-filename@^2.0.0: version "2.0.1" - resolved "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-2.0.1.tgz#e785f8675a9a7589e0ac77e0b5c34d2eaeac6da2" integrity sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A== dependencies: unique-slug "^3.0.0" -unique-filename@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz" - integrity sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g== - dependencies: - unique-slug "^4.0.0" - unique-slug@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-3.0.0.tgz#6d347cf57c8a7a7a6044aabd0e2d74e4d76dc7c9" integrity sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w== dependencies: imurmurhash "^0.1.4" -unique-slug@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz" - integrity sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ== - dependencies: - imurmurhash "^0.1.4" - universal-user-agent@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz" - integrity sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w== + version "6.0.1" + resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.1.tgz#15f20f55da3c930c57bddbf1734c6654d5fd35aa" + integrity sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ== universalify@^0.1.0: version "0.1.2" @@ -10591,13 +11132,13 @@ universalify@^0.1.0: integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== universalify@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz" - integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + version "2.0.1" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" + integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== unset-value@^1.0.0: @@ -10610,18 +11151,18 @@ unset-value@^1.0.0: upath@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/upath/-/upath-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/upath/-/upath-2.0.1.tgz#50c73dea68d6f6b990f51d279ce6081665d61a8b" integrity sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w== -update-browserslist-db@^1.0.13: - version "1.0.15" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.15.tgz#60ed9f8cba4a728b7ecf7356f641a31e3a691d97" - integrity sha512-K9HWH62x3/EalU1U6sjSZiylm9C8tgq2mSvshZpqc7QE69RaA2qjhkW2HlNA0tFpEbtyFz7HTqbSdN4MSwUodA== +update-browserslist-db@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz#348377dd245216f9e7060ff50b15a1b740b75420" + integrity sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw== dependencies: - escalade "^3.1.2" - picocolors "^1.0.0" + escalade "^3.2.0" + picocolors "^1.1.1" -uri-js@4.2.2, uri-js@^4.2.2: +uri-js@4.2.2, uri-js@^4.2.2, uri-js@^4.4.1: version "4.2.2" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== @@ -10645,17 +11186,17 @@ user-home@^1.1.1: util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" - resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== utils-merge@1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== uuid@^8.3.2: version "8.3.2" - resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== v8-compile-cache-lib@^3.0.0: @@ -10665,13 +11206,13 @@ v8-compile-cache-lib@^3.0.0: v8-compile-cache@2.3.0: version "2.3.0" - resolved "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== v8-to-istanbul@^9.0.1: - version "9.2.0" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz#2ed7644a245cddd83d4e087b9b33b3e62dfd10ad" - integrity sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA== + version "9.3.0" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz#b9572abfa62bd556c16d75fdebc1a411d5ff3175" + integrity sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA== dependencies: "@jridgewell/trace-mapping" "^0.3.12" "@types/istanbul-lib-coverage" "^2.0.1" @@ -10686,7 +11227,7 @@ v8flags@^2.1.1: validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: version "3.0.4" - resolved "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== dependencies: spdx-correct "^3.0.0" @@ -10694,31 +11235,31 @@ validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: validate-npm-package-name@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" integrity sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw== dependencies: builtins "^1.0.3" validate-npm-package-name@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-4.0.0.tgz#fe8f1c50ac20afdb86f177da85b3600f0ac0d747" integrity sha512-mzR0L8ZDktZjpX4OB46KT+56MAhl4EIazWP/+G/HPGuvfdaqg4YsCdtOm6U9+LOFyYDoh4dpnpxZRB9MQQns5Q== dependencies: builtins "^5.0.0" validator@^13.9.0: - version "13.11.0" - resolved "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz" - integrity sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ== + version "13.15.0" + resolved "https://registry.yarnpkg.com/validator/-/validator-13.15.0.tgz#2dc7ce057e7513a55585109eec29b2c8e8c1aefd" + integrity sha512-36B2ryl4+oL5QxZ3AzD0t5SsMNGvTtQHpjgFO5tbNxfXbMFkY822ktCDe1MnlqV3301QQI9SLHDNJokDI+Z9pA== vary@^1, vary@~1.1.2: version "1.1.2" - resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== verror@^1.10.0: version "1.10.1" - resolved "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.1.tgz#4bf09eeccf4563b109ed4b3d458380c972b0cdeb" integrity sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg== dependencies: assert-plus "^1.0.0" @@ -10727,7 +11268,7 @@ verror@^1.10.0: walk-up-path@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/walk-up-path/-/walk-up-path-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/walk-up-path/-/walk-up-path-1.0.0.tgz#d4745e893dd5fd0dbb58dd0a4c6a33d9c9fec53e" integrity sha512-hwj/qMDUEjCU5h0xr90KGCf0tg0/LgJbmOWgrWKYlcJZM7XvquvUJZ0G/HMGr7F7OQMOUuPHWP9JpriinkAlkg== walker@^1.0.8: @@ -10739,24 +11280,24 @@ walker@^1.0.8: wcwidth@^1.0.0, wcwidth@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" integrity sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg== dependencies: defaults "^1.0.3" webidl-conversions@^3.0.0: version "3.0.1" - resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== whatwg-fetch@^3.4.1: - version "3.6.19" - resolved "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.19.tgz" - integrity sha512-d67JP4dHSbm2TrpFj8AbO8DnL1JXL5J9u0Kq2xW6d0TFDbCA3Muhdt8orXC22utleTVj7Prqt82baN6RBvnEgw== + version "3.6.20" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz#580ce6d791facec91d37c72890995a0b48d31c70" + integrity sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg== whatwg-url@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== dependencies: tr46 "~0.0.3" @@ -10764,29 +11305,36 @@ whatwg-url@^5.0.0: which@^2.0.0, which@^2.0.1, which@^2.0.2: version "2.0.2" - resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" wide-align@^1.1.5: version "1.1.5" - resolved "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== dependencies: string-width "^1.0.2 || 2 || 3 || 4" +widest-line@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" + integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== + dependencies: + string-width "^4.0.0" + wkx@^0.5.0: version "0.5.0" - resolved "https://registry.npmjs.org/wkx/-/wkx-0.5.0.tgz" + resolved "https://registry.yarnpkg.com/wkx/-/wkx-0.5.0.tgz#c6c37019acf40e517cc6b94657a25a3d4aa33e8c" integrity sha512-Xng/d4Ichh8uN4l0FToV/258EjMGU9MGcA0HV2d9B/ZpZB3lqQm7nkOdZdm5GhKtLLhAE7PiVQwN4eN+2YJJUg== dependencies: "@types/node" "*" wonka@^6.0.0, wonka@^6.1.2: - version "6.3.4" - resolved "https://registry.yarnpkg.com/wonka/-/wonka-6.3.4.tgz#76eb9316e3d67d7febf4945202b5bdb2db534594" - integrity sha512-CjpbqNtBGNAeyNS/9W6q3kSkKE52+FjIj7AkFlLr11s/VWGUu6a2CdYSdGxocIhIVjaW/zchesBQUKPVU69Cqg== + version "6.3.5" + resolved "https://registry.yarnpkg.com/wonka/-/wonka-6.3.5.tgz#33fa54ea700ff3e87b56fe32202112a9e8fea1a2" + integrity sha512-SSil+ecw6B4/Dm7Pf2sAshKQ5hWFvfyGlfPbEd6A14dOH6VDjrmbY86u6nZvy9omGwwIPFR8V41+of1EezgoUw== word-wrap@^1.2.5: version "1.2.5" @@ -10795,7 +11343,7 @@ word-wrap@^1.2.5: wordwrap@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== wordwrapjs@^4.0.0: @@ -10806,18 +11354,32 @@ wordwrapjs@^4.0.0: reduce-flatten "^2.0.0" typical "^5.2.0" +workerpool@^6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.5.1.tgz#060f73b39d0caf97c6db64da004cd01b4c099544" + integrity sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA== + "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== dependencies: ansi-styles "^4.0.0" string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-9.0.0.tgz#1a3dc8b70d85eeb8398ddfb1e4a02cd186e58b3e" + integrity sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q== + dependencies: + ansi-styles "^6.2.1" + string-width "^7.0.0" + strip-ansi "^7.1.0" + wrap-ansi@^6.0.1: version "6.2.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== dependencies: ansi-styles "^4.0.0" @@ -10826,7 +11388,7 @@ wrap-ansi@^6.0.1: wrap-ansi@^7.0.0: version "7.0.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== dependencies: ansi-styles "^4.0.0" @@ -10835,7 +11397,7 @@ wrap-ansi@^7.0.0: wrap-ansi@^8.1.0: version "8.1.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== dependencies: ansi-styles "^6.1.0" @@ -10844,12 +11406,12 @@ wrap-ansi@^8.1.0: wrappy@1: version "1.0.2" - resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== write-file-atomic@^2.4.2: version "2.4.3" - resolved "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481" integrity sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ== dependencies: graceful-fs "^4.1.11" @@ -10858,7 +11420,7 @@ write-file-atomic@^2.4.2: write-file-atomic@^3.0.0: version "3.0.3" - resolved "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== dependencies: imurmurhash "^0.1.4" @@ -10868,7 +11430,7 @@ write-file-atomic@^3.0.0: write-file-atomic@^4.0.0, write-file-atomic@^4.0.1, write-file-atomic@^4.0.2: version "4.0.2" - resolved "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== dependencies: imurmurhash "^0.1.4" @@ -10876,7 +11438,7 @@ write-file-atomic@^4.0.0, write-file-atomic@^4.0.1, write-file-atomic@^4.0.2: write-json-file@^3.2.0: version "3.2.0" - resolved "https://registry.npmjs.org/write-json-file/-/write-json-file-3.2.0.tgz" + resolved "https://registry.yarnpkg.com/write-json-file/-/write-json-file-3.2.0.tgz#65bbdc9ecd8a1458e15952770ccbadfcff5fe62a" integrity sha512-3xZqT7Byc2uORAatYiP3DHUUAVEkNOswEWNs9H5KXiicRTvzYzYqKjYc4G7p+8pltvAw641lVByKVtMpf+4sYQ== dependencies: detect-indent "^5.0.0" @@ -10888,7 +11450,7 @@ write-json-file@^3.2.0: write-json-file@^4.3.0: version "4.3.0" - resolved "https://registry.npmjs.org/write-json-file/-/write-json-file-4.3.0.tgz" + resolved "https://registry.yarnpkg.com/write-json-file/-/write-json-file-4.3.0.tgz#908493d6fd23225344af324016e4ca8f702dd12d" integrity sha512-PxiShnxf0IlnQuMYOPPhPkhExoCQuTUNPOa/2JWCYTmBquU9njyyDuwRKN26IZBlp4yn1nt+Agh2HOOBl+55HQ== dependencies: detect-indent "^6.0.0" @@ -10900,31 +11462,31 @@ write-json-file@^4.3.0: write-pkg@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/write-pkg/-/write-pkg-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/write-pkg/-/write-pkg-4.0.0.tgz#675cc04ef6c11faacbbc7771b24c0abbf2a20039" integrity sha512-v2UQ+50TNf2rNHJ8NyWttfm/EJUBWMJcx6ZTYZr6Qp52uuegWw/lBkCtCbnYZEmPRNL61m+u67dAmGxo+HTULA== dependencies: sort-keys "^2.0.0" type-fest "^0.4.1" write-json-file "^3.2.0" -ws@7.4.6: - version "7.4.6" - resolved "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz" - integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== +ws@8.17.1: + version "8.17.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b" + integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ== -ws@^7.4.5: - version "7.5.9" - resolved "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz" - integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== +ws@^7.4.5, ws@^7.4.6: + version "7.5.10" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9" + integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== xtend@^4.0.0, xtend@~4.0.1: version "4.0.2" - resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== y18n@^5.0.5: version "5.0.8" - resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== yallist@^3.0.2: @@ -10934,7 +11496,7 @@ yallist@^3.0.2: yallist@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== yaml@1.10.0: @@ -10944,40 +11506,50 @@ yaml@1.10.0: yaml@1.10.2, yaml@^1.10.0, yaml@^1.7.2: version "1.10.2" - resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== yaml@^2.0.0-10: - version "2.3.2" - resolved "https://registry.npmjs.org/yaml/-/yaml-2.3.2.tgz" - integrity sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg== + version "2.8.0" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.8.0.tgz#15f8c9866211bdc2d3781a0890e44d4fa1a5fff6" + integrity sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ== yargs-parser@20.2.4: version "20.2.4" - resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== yargs-parser@21.1.1, yargs-parser@^21.0.0, yargs-parser@^21.0.1, yargs-parser@^21.1.1: version "21.1.1" - resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== yargs-parser@^16.1.0: version "16.1.0" - resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-16.1.0.tgz" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-16.1.0.tgz#73747d53ae187e7b8dbe333f95714c76ea00ecf1" integrity sha512-H/V41UNZQPkUMIT5h5hiwg4QKIY1RPvoBV4XcjUbRM8Bk2oKqqyZ0DIEbTFZB0XjbtSPG8SAa/0DxCQmiRgzKg== dependencies: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@^20.2.2, yargs-parser@^20.2.3: +yargs-parser@^20.2.2, yargs-parser@^20.2.3, yargs-parser@^20.2.9: version "20.2.9" - resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== +yargs-unparser@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== + dependencies: + camelcase "^6.0.0" + decamelize "^4.0.0" + flat "^5.0.2" + is-plain-obj "^2.1.0" + yargs@17.4.1: version "17.4.1" - resolved "https://registry.npmjs.org/yargs/-/yargs-17.4.1.tgz" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.4.1.tgz#ebe23284207bb75cee7c408c33e722bfb27b5284" integrity sha512-WSZD9jgobAg3ZKuCQZSa3g9QOJeCCqLoLAykiWgmXnDo9EPnn4RPf5qVTtzgOx66o6/oqhcA5tHtJXpG8pMt3g== dependencies: cliui "^7.0.2" @@ -10990,7 +11562,7 @@ yargs@17.4.1: yargs@^16.2.0: version "16.2.0" - resolved "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== dependencies: cliui "^7.0.2" @@ -11001,9 +11573,9 @@ yargs@^16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" -yargs@^17.3.1, yargs@^17.6.2: +yargs@^17.3.1, yargs@^17.6.2, yargs@^17.7.2: version "17.7.2" - resolved "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== dependencies: cliui "^8.0.1" @@ -11021,15 +11593,15 @@ yn@3.1.1: yocto-queue@^0.1.0: version "0.1.0" - resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== zod-validation-error@^1.3.0: version "1.5.0" - resolved "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-1.5.0.tgz" + resolved "https://registry.yarnpkg.com/zod-validation-error/-/zod-validation-error-1.5.0.tgz#2b355007a1c3b7fb04fa476bfad4e7b3fd5491e3" integrity sha512-/7eFkAI4qV0tcxMBB/3+d2c1P6jzzZYdYSlBuAklzMuCrJu5bzJfHS0yVAS87dRHVlhftd6RFJDIvv03JgkSbw== zod@^3.21.4: - version "3.22.2" - resolved "https://registry.npmjs.org/zod/-/zod-3.22.2.tgz" - integrity sha512-wvWkphh5WQsJbVk1tbx1l1Ly4yg+XecD+Mq280uBGt9wa5BKSWf4Mhp6GmrkPixhMxmabYY7RbzlwVP32pbGCg== + version "3.24.4" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.24.4.tgz#e2e2cca5faaa012d76e527d0d36622e0a90c315f" + integrity sha512-OdqJE9UDRPwWsrHjLN2F8bPxvwJBK22EHLWtanu0LSYr5YqzsaaW3RMgmjwr8Rypg5k+meEJdSPXJZXE/yqOMg==