diff --git a/CHANGELOG.md b/CHANGELOG.md index 260721b49..c2335fa07 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,35 +4,63 @@ All notable changes to this project will be documented in this file. The changelog format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [1.1.0] - NEXT + +**Milestone**: Mainnet(1.0.2.0) + +| Package | Version | Link | +| ---------------- | ------- | ------------------------------------------------------------------ | +| Symbol Bootstrap | v1.1.0 | [symbol-bootstrap](https://www.npmjs.com/package/symbol-bootstrap) | + +- Added `wizard` command. +- Added `pack` command. +- Added `modifyMultisig` command. +- Added `--serviceProviderPublicKey` to `link` command. +- Rest `2.3.8` upgrade. +- Explorer `1.1.0` upgrade. +- Faucet `1.0.1` upgrade. +- Removed node reward support. +- Removed unused `sshpk` service and dependency. +- Removed unused `forge` service and dependency. +- Changed `stop` command to run `docker-compose stop` instead of `docker-compose down` +- Added statistic service integration. +- Removed node static list from `mainnet` and `testnet` preset. The node lists are resolved using the statistic service. +- Updated explorer and faucet urls. +- Removed private and mijin network types support. + ## [1.0.9] - Sep-15-2021 **Milestone**: Mainnet(1.0.2.0) +| Package | Version | Link | +| ---------------- | ------- | ------------------------------------------------------------------ | +| Symbol Bootstrap | v1.0.9 | [symbol-bootstrap](https://www.npmjs.com/package/symbol-bootstrap) | + - Hot fix `updateVotingKeys` command bug. ## [1.0.8] - Sep-14-2021 **Milestone**: Mainnet(1.0.2.0) -- Fixed `updateVotingKeys` command when upgrading from `1.0.6`. -- Catapult `1.0.2.0` upgrade. -- Updated `minPartnerNodeVersion` to `1.0.1.0`. Older Catapult clients will be rejected. - | Package | Version | Link | | ---------------- | ------- | ------------------------------------------------------------------ | | Symbol Bootstrap | v1.0.8 | [symbol-bootstrap](https://www.npmjs.com/package/symbol-bootstrap) | +- Fixed `updateVotingKeys` command when upgrading from `1.0.6`. +- Catapult `1.0.2.0` upgrade. +- Updated `minPartnerNodeVersion` to `1.0.1.0`. Older Catapult clients will be rejected. + ## [1.0.7] - June-22-2021 **Milestone**: Mainnet(1.0.1.0) -- Added multi voting key file support. -- Added `updateVotingKeys` command. - | Package | Version | Link | | ---------------- | ------- | ------------------------------------------------------------------ | | Symbol Bootstrap | v1.0.7 | [symbol-bootstrap](https://www.npmjs.com/package/symbol-bootstrap) | +- Added multi voting key file support. +- Added `updateVotingKeys` command. + ## [1.0.6] - June-8-2021 **Milestone**: Mainnet(1.0.1.0) diff --git a/README.md b/README.md index 45420efa6..30a98398d 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,8 @@ Symbol CLI tool that allows you creating, configuring and running Symbol's c * [Concepts](#concepts) * [Requirements](#requirements) * [Usage](#usage) +* [General Usage](#general-usage) +* [Wizard](#wizard) * [E2E Testing support](#e2e-testing-support) * [Development](#development) * [Commands](#commands) @@ -135,7 +137,7 @@ $ npm install -g symbol-bootstrap $ symbol-bootstrap COMMAND running command... $ symbol-bootstrap (-v|--version|version) -symbol-bootstrap/1.0.9 linux-x64 node-v12.22.6 +symbol-bootstrap/1.1.0 linux-x64 node-v12.22.6 $ symbol-bootstrap --help [COMMAND] USAGE $ symbol-bootstrap COMMAND @@ -143,6 +145,8 @@ USAGE ``` +# General Usage + The general usage would be: ``` @@ -163,6 +167,14 @@ If you need to start fresh, you many need to sudo remove the target folder (dock sudo rm -rf ./target ``` +# Wizard + +If this is your first time creating a node, it's recommended to use the Wizard. Just follow the instructions: + +``` +symbol-bootstrap wizard +``` + # E2E Testing support One use case of this CLI is client E2E testing support. If you are coding a Symbol client, you (Travis or Jenkins) can run e2e tests like: @@ -268,10 +280,11 @@ General users should install this tool like any other node module. * [`symbol-bootstrap config`](docs/config.md) - Command used to set up the configuration files and the nemesis block for the current network * [`symbol-bootstrap decrypt`](docs/decrypt.md) - It decrypts a yml file using the provided password. The source file can be a custom preset file, a preset.yml file or an addresses.yml. * [`symbol-bootstrap encrypt`](docs/encrypt.md) - It encrypts a yml file using the provided password. The source files would be a custom preset file, a preset.yml file or an addresses.yml. -* [`symbol-bootstrap enrollRewardProgram`](docs/enrollRewardProgram.md) - It enrols the nodes in the rewards program by announcing the enroll transaction to the registration address. You can also use this command to update the program registration when you change the agent keys (changing the agent-ca-csr) or server host. * [`symbol-bootstrap healthCheck`](docs/healthCheck.md) - It checks if the services created with docker compose are up and running. * [`symbol-bootstrap help`](docs/help.md) - display help for symbol-bootstrap * [`symbol-bootstrap link`](docs/link.md) - It announces VRF and Voting Link transactions to the network for each node with 'Peer' or 'Voting' roles. This command finalizes the node registration to an existing network. +* [`symbol-bootstrap modifyMultisig`](docs/modifyMultisig.md) - Create or modify a multisig account +* [`symbol-bootstrap pack`](docs/pack.md) - It configures and packages your node into a zip file that can be uploaded to the final node machine. * [`symbol-bootstrap report`](docs/report.md) - it generates reStructuredText (.rst) reports describing the configuration of each node. * [`symbol-bootstrap resetData`](docs/resetData.md) - It removes the data keeping the generated configuration, certificates, keys and block 1. * [`symbol-bootstrap run`](docs/run.md) - It boots the network via docker using the generated `docker-compose.yml` file and configuration. The config and compose methods/commands need to be called before this method. This is just a wrapper for the `docker-compose up` bash call. @@ -279,6 +292,7 @@ General users should install this tool like any other node module. * [`symbol-bootstrap stop`](docs/stop.md) - It stops the docker-compose network if running (symbol-bootstrap started with --detached). This is just a wrapper for the `docker-compose down` bash call. * [`symbol-bootstrap updateVotingKeys`](docs/updateVotingKeys.md) - It updates the voting files containing the voting keys when required. * [`symbol-bootstrap verify`](docs/verify.md) - It tests the installed software in the current computer reporting if there is any missing dependency, invalid version, or software related issue. +* [`symbol-bootstrap wizard`](docs/wizard.md) - An utility command that will help you configuring node! diff --git a/cmds/config-testnet-supernode.sh b/cmds/config-testnet-supernode.sh deleted file mode 100755 index 89e0a2169..000000000 --- a/cmds/config-testnet-supernode.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -set -e -symbol-bootstrap config -p testnet -a dual -t target/testnet-supernode -c test/supernode.yml --password 1111 $1 $2 $3 diff --git a/cmds/enrollRewardProgram-testnet.sh b/cmds/enrollRewardProgram-testnet.sh deleted file mode 100755 index 674f1a516..000000000 --- a/cmds/enrollRewardProgram-testnet.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -set -e -symbol-bootstrap enrollRewardProgram -t target/testnet-supernode --useKnownRestGateways --password 1111 $1 $2 $3 diff --git a/cmds/link-testnet-supernode-external-node.sh b/cmds/link-testnet-supernode-external-node.sh deleted file mode 100755 index 5cbf55758..000000000 --- a/cmds/link-testnet-supernode-external-node.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -symbol-bootstrap link -t target/testnet-supernode --useKnownRestGateways --password 1111 $1 $2 $3 $4 $5 $6 $7 diff --git a/cmds/start-testnet-supernode-demo.sh b/cmds/start-testnet-supernode-demo.sh deleted file mode 100755 index e3b1176d1..000000000 --- a/cmds/start-testnet-supernode-demo.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -set -e -symbol-bootstrap start -p testnet -a demo -t target/testnet-supernode -c test/supernode.yml $1 $2 $3 diff --git a/cmds/start-testnet-supernode.sh b/cmds/start-testnet-supernode.sh deleted file mode 100755 index 750afeda0..000000000 --- a/cmds/start-testnet-supernode.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -set -e -symbol-bootstrap start -p testnet -a dual -t target/testnet-supernode -c test/supernode.yml -r --password 1111 $1 $2 $3 diff --git a/cmds/stop-testnet-supernode.sh b/cmds/stop-testnet-supernode.sh deleted file mode 100755 index 89faa5781..000000000 --- a/cmds/stop-testnet-supernode.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -set -e -# docker rm -f $(docker ps -aq) -symbol-bootstrap stop -t target/testnet-supernode diff --git a/cmds/upgradeVotingKeys-testnet-supernode.sh b/cmds/upgradeVotingKeys-testnet-supernode.sh deleted file mode 100755 index d46a00759..000000000 --- a/cmds/upgradeVotingKeys-testnet-supernode.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -set -e -symbol-bootstrap upgradeVotingKeys -t target/testnet-supernode $1 $2 $3 diff --git a/config/agent-cert/agent-ca.cnf b/config/agent-cert/agent-ca.cnf deleted file mode 100644 index 453557283..000000000 --- a/config/agent-cert/agent-ca.cnf +++ /dev/null @@ -1,20 +0,0 @@ -[ca] -default_ca = CA_default - -[CA_default] -new_certs_dir = ./new_certs -database = index.txt -serial = serial.dat -private_key = agent-ca.key.pem -certificate = agent-ca.crt.pem -policy = policy_catapult - -[policy_catapult] -commonName = supplied - -[req] -prompt = no -distinguished_name = dn - -[dn] -CN = Agent CA diff --git a/config/agent-cert/agent-comm.cnf b/config/agent-cert/agent-comm.cnf deleted file mode 100644 index 766f8efbc..000000000 --- a/config/agent-cert/agent-comm.cnf +++ /dev/null @@ -1,7 +0,0 @@ -[req] -prompt = no -distinguished_name = dn - -[dn] -CN = Agent communication cert - diff --git a/config/agent/agent.properties.mustache b/config/agent/agent.properties.mustache deleted file mode 100644 index 40d1d1a39..000000000 --- a/config/agent/agent.properties.mustache +++ /dev/null @@ -1,8 +0,0 @@ -CERTS_CONTROLLER_CA_CERT_FILE={{{rewardProgramCaFile}}} -CONTROLLER_API_URL={{rewardProgramControllerApiUrl}} -REST_GATEWAY_URL={{{restGatewayUrl}}} -REWARD_PROGRAM={{{rewardProgram}}} -MAIN_PUBLIC_KEY={{{mainPublicKey}}} -LOGGER_FILE=logs/agent.log -CERTS_AGENT_CA_KEY_FILE=agent-ca.key.pem -CERTS_AGENT_CA_CERT_FILE=agent-ca.csr.pem diff --git a/config/docker/explorer/run.sh.mustache b/config/docker/explorer/run.sh.mustache index ea5ba3fc8..668b69193 100644 --- a/config/docker/explorer/run.sh.mustache +++ b/config/docker/explorer/run.sh.mustache @@ -1,5 +1,6 @@ #!/bin/bash set -e echo "Starting explorer $1" -cp config.js /usr/share/nginx/html -nginx -g 'daemon off;' +cp default.json /app/src/config/default.json +cd /app +npm start diff --git a/config/explorer/config.js.mustache b/config/explorer/config.js.mustache deleted file mode 100644 index e2c0029cb..000000000 --- a/config/explorer/config.js.mustache +++ /dev/null @@ -1,21 +0,0 @@ -window.globalConfig = { - 'peersApi': { - 'defaultNode': '{{defaultNode}}', - 'nodes': [ -{{#restNodes}} - '{{{.}}}', -{{/restNodes}} - ] - }, - 'endpoints': { - 'marketData': 'https://min-api.cryptocompare.com/' - }, - 'networkConfig': { - 'namespaceName': '{{namespaceName}}', - 'mosaicId': '{{{toSimpleHex currencyMosaicId}}}', - 'divisibility': '{{maxMosaicDivisibility}}' - }, - 'footer': {{{toJson footer}}} -}; - -console.log('GLOBAL CONFIG LOADED!'); diff --git a/config/explorer/default.json.mustache b/config/explorer/default.json.mustache new file mode 100644 index 000000000..7ff35d8dc --- /dev/null +++ b/config/explorer/default.json.mustache @@ -0,0 +1,18 @@ +{ + "peersApi": { + "defaultNode": "{{defaultNode}}", + "nodes": {{{toJson restNodes}}} + }, + "endpoints": { + "marketData": "https://min-api.cryptocompare.com/" + }, + "networkConfig": { + "namespaceName": "{{namespaceName}}", + "mosaicId": "{{{toSimpleHex currencyMosaicId}}}", + "divisibility": "{{maxMosaicDivisibility}}", + "namespaceId": "{{{toSimpleHex namespaceId}}}", + "networkIdentifier": {{networkType}} + }, + "footer": {{{toJson footer}}} +} + diff --git a/config/node/resources/config-finalization.properties.mustache b/config/node/resources/config-finalization.properties.mustache index d23b46fe1..c0fd9fe50 100644 --- a/config/node/resources/config-finalization.properties.mustache +++ b/config/node/resources/config-finalization.properties.mustache @@ -14,3 +14,11 @@ maxHashesPerPoint = {{{toAmount maxHashesPerPoint}}} prevoteBlocksMultiple = {{{toAmount prevoteBlocksMultiple}}} unfinalizedBlocksDuration = {{{unfinalizedBlocksDuration}}} + +treasuryReissuanceEpoch = {{{treasuryReissuanceEpoch}}} + +[treasury_reissuance_epoch_ineligible_voter_addresses] + +{{#each treasuryReissuanceEpochIneligibleVoterAddresses}} +{{this}} = true +{{/each}} diff --git a/config/node/resources/config-network.properties.mustache b/config/node/resources/config-network.properties.mustache index 5e5dd074f..915501108 100644 --- a/config/node/resources/config-network.properties.mustache +++ b/config/node/resources/config-network.properties.mustache @@ -42,13 +42,13 @@ maxVotingKeyLifetime = {{{maxVotingKeyLifetime}}} harvestBeneficiaryPercentage = {{{harvestBeneficiaryPercentage}}} harvestNetworkPercentage = {{{harvestNetworkPercentage}}} +harvestNetworkFeeSinkAddressV1 = {{{harvestNetworkFeeSinkAddressV1}}} harvestNetworkFeeSinkAddress = {{{harvestNetworkFeeSinkAddress}}} maxTransactionsPerBlock = {{{toAmount maxTransactionsPerBlock}}} -[fork_heights] - -totalVotingBalanceCalculationFix = {{{toAmount totalVotingBalanceCalculationFix}}} +treasuryReissuanceBlockTransactionsHash = {{{treasuryReissuanceBlockTransactionsHash}}} +treasuryReissuanceFallbackBlockTransactionsHash = {{{treasuryReissuanceFallbackBlockTransactionsHash}}} [plugin:catapult.plugins.accountlink] @@ -86,6 +86,7 @@ maxMosaicsPerAccount = {{{toAmount maxMosaicsPerAccount}}} maxMosaicDuration = {{{maxMosaicDuration}}} maxMosaicDivisibility = {{{maxMosaicDivisibility}}} +mosaicRentalFeeSinkAddressV1 = {{{mosaicRentalFeeSinkAddressV1}}} mosaicRentalFeeSinkAddress = {{{mosaicRentalFeeSinkAddress}}} mosaicRentalFee = {{{mosaicRentalFee}}} @@ -107,6 +108,7 @@ maxNamespaceDuration = {{{maxNamespaceDuration}}} namespaceGracePeriodDuration = {{{namespaceGracePeriodDuration}}} reservedRootNamespaceNames = {{{reservedRootNamespaceNames}}} +namespaceRentalFeeSinkAddressV1 = {{{namespaceRentalFeeSinkAddressV1}}} namespaceRentalFeeSinkAddress = {{{namespaceRentalFeeSinkAddress}}} rootNamespaceRentalFeePerBlock = {{{rootNamespaceRentalFeePerBlock}}} childNamespaceRentalFee = {{{childNamespaceRentalFee}}} @@ -122,3 +124,20 @@ maxMosaicRestrictionValues = {{{maxMosaicRestrictionValues}}} [plugin:catapult.plugins.transfer] maxMessageSize = {{{maxMessageSize}}} + +[fork_heights] + +totalVotingBalanceCalculationFix = {{{toAmount totalVotingBalanceCalculationFix}}} +treasuryReissuance = {{{toAmount treasuryReissuance}}} + +[treasury_reissuance_transaction_signatures] + +{{#each treasuryReissuanceTransactionSignatures}} +{{this}} = true +{{/each}} + +[treasury_reissuance_fallback_transaction_signatures] + +{{#each treasuryReissuanceFallbackTransactionSignatures}} +{{this}} = true +{{/each}} diff --git a/config/rest-gateway/rest.json.mustache b/config/rest-gateway/rest.json.mustache index 045a000c5..4be203154 100644 --- a/config/rest-gateway/rest.json.mustache +++ b/config/rest-gateway/rest.json.mustache @@ -5,6 +5,10 @@ }, "port": 3000, + "protocol": "{{{restProtocol}}}", + "sslKeyPath": "{{{restSSLPath}}}/{{{restSSLKeyFileName}}}", + "sslCertificatePath": "{{{restSSLPath}}}/{{{restSSLCertificateFileName}}}", + "crossDomain": { "allowedHosts": ["*"], "allowedMethods": ["GET", "POST", "PUT", "OPTIONS"] diff --git a/docs/clean.md b/docs/clean.md index d8fb23ae0..ecf53ad68 100644 --- a/docs/clean.md +++ b/docs/clean.md @@ -21,4 +21,4 @@ EXAMPLE $ symbol-bootstrap clean ``` -_See code: [src/commands/clean.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.0.9/src/commands/clean.ts)_ +_See code: [src/commands/clean.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.0/src/commands/clean.ts)_ diff --git a/docs/compose.md b/docs/compose.md index 29bd95250..447c9305c 100644 --- a/docs/compose.md +++ b/docs/compose.md @@ -33,4 +33,4 @@ EXAMPLE $ symbol-bootstrap compose ``` -_See code: [src/commands/compose.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.0.9/src/commands/compose.ts)_ +_See code: [src/commands/compose.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.0/src/commands/compose.ts)_ diff --git a/docs/config.md b/docs/config.md index a8ed40ce5..0ded1c263 100644 --- a/docs/config.md +++ b/docs/config.md @@ -55,4 +55,4 @@ EXAMPLES $ echo "$MY_ENV_VAR_PASSWORD" | symbol-bootstrap config -p testnet -a dual ``` -_See code: [src/commands/config.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.0.9/src/commands/config.ts)_ +_See code: [src/commands/config.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.0/src/commands/config.ts)_ diff --git a/docs/decrypt.md b/docs/decrypt.md index 1fc4a17a5..15a6c7cf9 100644 --- a/docs/decrypt.md +++ b/docs/decrypt.md @@ -56,4 +56,4 @@ EXAMPLES plain-addresses.yml ``` -_See code: [src/commands/decrypt.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.0.9/src/commands/decrypt.ts)_ +_See code: [src/commands/decrypt.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.0/src/commands/decrypt.ts)_ diff --git a/docs/encrypt.md b/docs/encrypt.md index bee9ed6fb..7f3f64848 100644 --- a/docs/encrypt.md +++ b/docs/encrypt.md @@ -46,4 +46,4 @@ EXAMPLES encrypted-custom-preset.yml ``` -_See code: [src/commands/encrypt.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.0.9/src/commands/encrypt.ts)_ +_See code: [src/commands/encrypt.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.0/src/commands/encrypt.ts)_ diff --git a/docs/enrollRewardProgram.md b/docs/enrollRewardProgram.md deleted file mode 100644 index 67caffd93..000000000 --- a/docs/enrollRewardProgram.md +++ /dev/null @@ -1,57 +0,0 @@ -`symbol-bootstrap enrollRewardProgram` -====================================== - -It enrols the nodes in the rewards program by announcing the enroll transaction to the registration address. You can also use this command to update the program registration when you change the agent keys (changing the agent-ca-csr) or server host. - -Currently, the only program that can be enrolled post-launch is 'SuperNode'. - -* [`symbol-bootstrap enrollRewardProgram`](#symbol-bootstrap-enrollrewardprogram) - -## `symbol-bootstrap enrollRewardProgram` - -It enrols the nodes in the rewards program by announcing the enroll transaction to the registration address. You can also use this command to update the program registration when you change the agent keys (changing the agent-ca-csr) or server host. - -``` -USAGE - $ symbol-bootstrap enrollRewardProgram - -OPTIONS - -c, --customPreset=customPreset This command uses the encrypted addresses.yml to resolve the main private key. If the - main private is only stored in the custom preset, you can provide it using this - param. Otherwise, the command may ask for it when required. - - -h, --help It shows the help of this command. - - -t, --target=target [default: target] The target folder where the symbol-bootstrap network is generated - - -u, --url=url [default: http://localhost:3000] the network url - - --maxFee=maxFee the max fee used when announcing (absolute). The node min multiplier will be used if - it is not provided. - - --noPassword When provided, Bootstrap will not use a password, so private keys will be stored in - plain text. Use with caution. - - --password=password A password used to encrypt and decrypt private keys in preset files like - addresses.yml and preset.yml. Bootstrap prompts for a password by default, can be - provided in the command line (--password=XXXX) or disabled in the command line - (--noPassword). - - --ready If --ready is provided, the command will not ask for confirmation when announcing - transactions. - - --useKnownRestGateways Use the best NEM node available when announcing. Otherwise the command will use the - node provided by the --url parameter. - -DESCRIPTION - Currently, the only program that can be enrolled post-launch is 'SuperNode'. - -EXAMPLES - $ symbol-bootstrap enrollRewardProgram - $ symbol-bootstrap enrollRewardProgram --noPassword - $ symbol-bootstrap enrollRewardProgram --useKnownRestGateways - $ symbol-bootstrap enrollRewardProgram --password 1234 --url http://external-rest:3000 - $ echo "$MY_ENV_VAR_PASSWORD" | symbol-bootstrap enrollRewardProgram --url http://external-rest:3000 -``` - -_See code: [src/commands/enrollRewardProgram.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.0.9/src/commands/enrollRewardProgram.ts)_ diff --git a/docs/healthCheck.md b/docs/healthCheck.md index b8fa05e16..5b92f39b3 100644 --- a/docs/healthCheck.md +++ b/docs/healthCheck.md @@ -36,4 +36,4 @@ EXAMPLE $ symbol-bootstrap healthCheck ``` -_See code: [src/commands/healthCheck.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.0.9/src/commands/healthCheck.ts)_ +_See code: [src/commands/healthCheck.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.0/src/commands/healthCheck.ts)_ diff --git a/docs/link.md b/docs/link.md index ff2aa61f7..3ac72d25d 100644 --- a/docs/link.md +++ b/docs/link.md @@ -14,39 +14,45 @@ USAGE $ symbol-bootstrap link OPTIONS - -c, --customPreset=customPreset This command uses the encrypted addresses.yml to resolve the main private key. If the - main private is only stored in the custom preset, you can provide it using this - param. Otherwise, the command may ask for it when required. + -c, --customPreset=customPreset This command uses the encrypted addresses.yml to resolve the main + private key. If the main private is only stored in the custom + preset, you can provide it using this param. Otherwise, the + command may ask for it when required. - -h, --help It shows the help of this command. + -h, --help It shows the help of this command. - -t, --target=target [default: target] The target folder where the symbol-bootstrap network is generated + -t, --target=target [default: target] The target folder where the symbol-bootstrap + network is generated - -u, --url=url [default: http://localhost:3000] the network url + -u, --url=url [default: http://localhost:3000] the network url - --maxFee=maxFee the max fee used when announcing (absolute). The node min multiplier will be used if - it is not provided. + --maxFee=maxFee the max fee used when announcing (absolute). The node min + multiplier will be used if it is not provided. - --noPassword When provided, Bootstrap will not use a password, so private keys will be stored in - plain text. Use with caution. + --noPassword When provided, Bootstrap will not use a password, so private keys + will be stored in plain text. Use with caution. - --password=password A password used to encrypt and decrypt private keys in preset files like - addresses.yml and preset.yml. Bootstrap prompts for a password by default, can be - provided in the command line (--password=XXXX) or disabled in the command line - (--noPassword). + --password=password A password used to encrypt and decrypt private keys in preset + files like addresses.yml and preset.yml. Bootstrap prompts for a + password by default, can be provided in the command line + (--password=XXXX) or disabled in the command line (--noPassword). - --ready If --ready is provided, the command will not ask for confirmation when announcing - transactions. + --ready If --ready is provided, the command will not ask for confirmation + when announcing transactions. - --unlink Perform "Unlink" transactions unlinking the voting and VRF keys from the node signer - account + --serviceProviderPublicKey=serviceProviderPublicKey Public key of the service provider account, used when the + transaction announcer(service provider account) is different than + the main account private key holder - --useKnownRestGateways Use the best NEM node available when announcing. Otherwise the command will use the - node provided by the --url parameter. + --unlink Perform "Unlink" transactions unlinking the voting and VRF keys + from the node signer account + + --useKnownRestGateways Use the best NEM node available when announcing. Otherwise the + command will use the node provided by the --url parameter. EXAMPLES $ symbol-bootstrap link $ echo "$MY_ENV_VAR_PASSWORD" | symbol-bootstrap link --unlink --useKnownRestGateways ``` -_See code: [src/commands/link.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.0.9/src/commands/link.ts)_ +_See code: [src/commands/link.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.0/src/commands/link.ts)_ diff --git a/docs/modifyMultisig.md b/docs/modifyMultisig.md new file mode 100644 index 000000000..9caf4af08 --- /dev/null +++ b/docs/modifyMultisig.md @@ -0,0 +1,69 @@ +`symbol-bootstrap modifyMultisig` +================================= + +Create or modify a multisig account + +* [`symbol-bootstrap modifyMultisig`](#symbol-bootstrap-modifymultisig) + +## `symbol-bootstrap modifyMultisig` + +Create or modify a multisig account + +``` +USAGE + $ symbol-bootstrap modifyMultisig + +OPTIONS + -A, --addressAdditions=addressAdditions Cosignatory accounts addresses to be added (separated by a + comma). + + -D, --addressDeletions=addressDeletions Cosignatory accounts addresses to be removed (separated by a + comma). + + -a, --minApprovalDelta=minApprovalDelta Delta of signatures needed to approve a transaction. 0 means no + change, a positive(+) number means increment and a negative(-) + number means decrement to the actual value. + + -c, --customPreset=customPreset This command uses the encrypted addresses.yml to resolve the main + private key. If the main private is only stored in the custom + preset, you can provide it using this param. Otherwise, the + command may ask for it when required. + + -h, --help It shows the help of this command. + + -r, --minRemovalDelta=minRemovalDelta Delta of signatures needed to remove a cosignatory. 0 means no + change, a positive(+) number means increment and a negative(-) + number means decrement to the actual value. + + -t, --target=target [default: target] The target folder where the symbol-bootstrap + network is generated + + -u, --url=url [default: http://localhost:3000] the network url + + --maxFee=maxFee the max fee used when announcing (absolute). The node min + multiplier will be used if it is not provided. + + --noPassword When provided, Bootstrap will not use a password, so private keys + will be stored in plain text. Use with caution. + + --password=password A password used to encrypt and decrypt private keys in preset + files like addresses.yml and preset.yml. Bootstrap prompts for a + password by default, can be provided in the command line + (--password=XXXX) or disabled in the command line (--noPassword). + + --ready If --ready is provided, the command will not ask for confirmation + when announcing transactions. + + --serviceProviderPublicKey=serviceProviderPublicKey Public key of the service provider account, used when the + transaction announcer(service provider account) is different than + the main account private key holder + + --useKnownRestGateways Use the best NEM node available when announcing. Otherwise the + command will use the node provided by the --url parameter. + +EXAMPLES + $ symbol-bootstrap modifyMultisig + $ echo "$MY_ENV_VAR_PASSWORD" | symbol-bootstrap modifyMultisig --useKnownRestGateways +``` + +_See code: [src/commands/modifyMultisig.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.0/src/commands/modifyMultisig.ts)_ diff --git a/docs/pack.md b/docs/pack.md new file mode 100644 index 000000000..cb11f5ae6 --- /dev/null +++ b/docs/pack.md @@ -0,0 +1,62 @@ +`symbol-bootstrap pack` +======================= + +It configures and packages your node into a zip file that can be uploaded to the final node machine. + +* [`symbol-bootstrap pack`](#symbol-bootstrap-pack) + +## `symbol-bootstrap pack` + +It configures and packages your node into a zip file that can be uploaded to the final node machine. + +``` +USAGE + $ symbol-bootstrap pack + +OPTIONS + -a, --assembly=assembly (required) The assembly, example "dual" for testnet. + + -c, --customPreset=customPreset (required) External preset file. Values in this file will override the + provided presets + + -h, --help It shows the help of this command. + + -p, --preset=(bootstrap|testnet|mainnet) (required) The network preset, can be provided via custom preset or cli + parameter. + + -r, --reset It resets the configuration generating a new one + + -t, --target=target [default: target] The target folder where the symbol-bootstrap network is + generated + + -u, --user=user [default: current] User used to run docker images when creating + configuration files like certificates or nemesis block. "current" means the + current user. + + --noPassword When provided, Bootstrap will not use a password, so private keys will be + stored in plain text. Use with caution. + + --password=password A password used to encrypt and decrypt private keys in preset files like + addresses.yml and preset.yml. Bootstrap prompts for a password by default, + can be provided in the command line (--password=XXXX) or disabled in the + command line (--noPassword). + + --ready If --ready is provided, the command will not ask offline confirmation. + + --report It generates reStructuredText (.rst) reports describing the configuration of + each node. + + --upgrade It regenerates the configuration reusing the previous keys. Use this flag + when upgrading the version of bootstrap to keep your node up to date without + dropping the local data. The original preset (-t), assembly (-a), and custom + preset (-a) must be used. Backup the target folder before upgrading. + +EXAMPLES + $ symbol-bootstrap pack + $ symbol-bootstrap pack -p bootstrap -c custom-preset.yml + $ symbol-bootstrap pack -p testnet -a dual -c custom-preset.yml + $ symbol-bootstrap pack -p mainnet -a dual --password 1234 -c custom-preset.yml + $ echo "$MY_ENV_VAR_PASSWORD" | symbol-bootstrap pack -p mainnet -a dual -c custom-preset.yml +``` + +_See code: [src/commands/pack.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.0/src/commands/pack.ts)_ diff --git a/docs/presetGuides.md b/docs/presetGuides.md index 68397fbea..b9569b032 100644 --- a/docs/presetGuides.md +++ b/docs/presetGuides.md @@ -331,7 +331,7 @@ If this is you case, you can tell Bootstrap to not store these keys with the `pr The `privateKeySecurityMode` defines which Private Keys can be encrypted and stored in the `target/addresses.yml`: - `ENCRYPT`: All private Keys are encrypted and stored in the target's `addresses.yml` file. Bootstrap will have them to be used when required. This is Bootstrap's default behaviour. - `PROMPT_MAIN`: Main Private Keys are not stored in the target's `addresses.yml` file. Bootstrap will prompt for the Main Private Key when generating certificates, or transactions need to be signed in the `link` and `enrolProgram` commands. -- `PROMPT_MAIN_TRANSPORT`: Main and transport private keys are not stored in the target's `addresses.yml` file. Bootstrap will request the main private key when certificates are generated, or transactions need to be signed by the `link` and `enrolProgram` commands. The transport private key will be asked when upgrading supernode agents. +- `PROMPT_MAIN_TRANSPORT`: Main and transport private keys are not stored in the target's `addresses.yml` file. Bootstrap will request the main private key when certificates are generated, or transactions need to be signed by the `link` commands. - `PROMPT_ALL`: No Private Key is stored in the target's `addresses.yml` file. Bootstrap will prompt for the Private Keys when they are required in the different commands. When using the `PROMPT` security modes Bootstrap may ask for private keys when running the different commands. This may not be suitable for automatic scripting. diff --git a/docs/report.md b/docs/report.md index 20ed9db18..9c574b0d1 100644 --- a/docs/report.md +++ b/docs/report.md @@ -21,4 +21,4 @@ EXAMPLE $ symbol-bootstrap report ``` -_See code: [src/commands/report.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.0.9/src/commands/report.ts)_ +_See code: [src/commands/report.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.0/src/commands/report.ts)_ diff --git a/docs/resetData.md b/docs/resetData.md index 606cf256b..0c6d7a912 100644 --- a/docs/resetData.md +++ b/docs/resetData.md @@ -21,4 +21,4 @@ EXAMPLE $ symbol-bootstrap resetData ``` -_See code: [src/commands/resetData.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.0.9/src/commands/resetData.ts)_ +_See code: [src/commands/resetData.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.0/src/commands/resetData.ts)_ diff --git a/docs/run.md b/docs/run.md index ecd0216d8..9ad312f81 100644 --- a/docs/run.md +++ b/docs/run.md @@ -53,4 +53,4 @@ EXAMPLE $ symbol-bootstrap run ``` -_See code: [src/commands/run.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.0.9/src/commands/run.ts)_ +_See code: [src/commands/run.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.0/src/commands/run.ts)_ diff --git a/docs/start.md b/docs/start.md index 85b8a89aa..3ce607eb6 100644 --- a/docs/start.md +++ b/docs/start.md @@ -90,4 +90,4 @@ EXAMPLES $ echo "$MY_ENV_VAR_PASSWORD" | symbol-bootstrap start -p testnet -a dual ``` -_See code: [src/commands/start.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.0.9/src/commands/start.ts)_ +_See code: [src/commands/start.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.0/src/commands/start.ts)_ diff --git a/docs/stop.md b/docs/stop.md index 7fe7e71cc..69a2dfb04 100644 --- a/docs/stop.md +++ b/docs/stop.md @@ -21,4 +21,4 @@ EXAMPLE $ symbol-bootstrap stop ``` -_See code: [src/commands/stop.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.0.9/src/commands/stop.ts)_ +_See code: [src/commands/stop.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.0/src/commands/stop.ts)_ diff --git a/docs/updateVotingKeys.md b/docs/updateVotingKeys.md index f53fec9d3..ed1133178 100644 --- a/docs/updateVotingKeys.md +++ b/docs/updateVotingKeys.md @@ -44,4 +44,4 @@ EXAMPLE $ symbol-bootstrap updateVotingKeys ``` -_See code: [src/commands/updateVotingKeys.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.0.9/src/commands/updateVotingKeys.ts)_ +_See code: [src/commands/updateVotingKeys.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.0/src/commands/updateVotingKeys.ts)_ diff --git a/docs/verify.md b/docs/verify.md index 0c1bae170..f77d8cc59 100644 --- a/docs/verify.md +++ b/docs/verify.md @@ -20,4 +20,4 @@ EXAMPLE $ symbol-bootstrap verify ``` -_See code: [src/commands/verify.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.0.9/src/commands/verify.ts)_ +_See code: [src/commands/verify.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.0/src/commands/verify.ts)_ diff --git a/docs/wizard.md b/docs/wizard.md new file mode 100644 index 000000000..dd55b5a75 --- /dev/null +++ b/docs/wizard.md @@ -0,0 +1,39 @@ +`symbol-bootstrap wizard` +========================= + +An utility command that will help you configuring node! + +* [`symbol-bootstrap wizard`](#symbol-bootstrap-wizard) + +## `symbol-bootstrap wizard` + +An utility command that will help you configuring node! + +``` +USAGE + $ symbol-bootstrap wizard + +OPTIONS + -c, --customPreset=customPreset [default: custom-preset.yml] The custom preset to be created. + -h, --help It shows the help of this command. + + -t, --target=target [default: target] The target folder where the symbol-bootstrap network is + generated + + --network=mainnet|testnet|localNetwork The node or network you want to create + + --noPassword When provided, Bootstrap will not use a password, so private keys will be + stored in plain text. Use with caution. + + --password=password A password used to encrypt and decrypt private keys in preset files like + addresses.yml and preset.yml. Bootstrap prompts for a password by default, can + be provided in the command line (--password=XXXX) or disabled in the command + line (--noPassword). + + --ready If --ready is provided, the command will not ask offline confirmation. + +EXAMPLE + $ symbol-bootstrap wizard +``` + +_See code: [src/commands/wizard.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.0/src/commands/wizard.ts)_ diff --git a/package-lock.json b/package-lock.json index accf4bcc1..cd847c927 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,7043 +1,8 @@ { "name": "symbol-bootstrap", - "version": "1.0.10", - "lockfileVersion": 2, + "version": "1.1.0", + "lockfileVersion": 1, "requires": true, - "packages": { - "": { - "name": "symbol-bootstrap", - "version": "1.0.8", - "license": "Apache-2.0", - "dependencies": { - "@oclif/command": "^1.7.0", - "@oclif/config": "^1.16.0", - "@oclif/plugin-autocomplete": "^0.3.0", - "@oclif/plugin-help": "^3.1.0", - "figlet": "^1.2.4", - "handlebars": "^4.7.7", - "inquirer": "^7.3.3", - "js-yaml": "^3.14.0", - "lodash": "^4.17.21", - "memorystream": "^0.3.1", - "noble-ed25519": "^1.0.3", - "node-forge": "^0.10.0", - "rxjs": "^6.6.3", - "semver": "^7.3.5", - "shx": "^0.3.2", - "sshpk": "^1.16.1", - "symbol-sdk": "^1.0.1", - "tslib": "^1.13.0", - "utf8": "^2.1.2", - "winston": "^3.3.3" - }, - "bin": { - "symbol-bootstrap": "bin/run" - }, - "devDependencies": { - "@oclif/dev-cli": "^1.22.2", - "@oclif/test": "^1.2.8", - "@types/chai": "^4.2.12", - "@types/figlet": "^1.2.0", - "@types/handlebars": "^4.1.0", - "@types/inquirer": "^7.3.1", - "@types/js-yaml": "^3.12.5", - "@types/lodash": "^4.14.165", - "@types/memorystream": "^0.3.0", - "@types/mocha": "^8.2.2", - "@types/node": "^10.17.28", - "@types/node-forge": "^0.9.4", - "@types/semver": "^7.3.6", - "@types/sshpk": "^1.10.5", - "@types/winston": "^2.4.4", - "@typescript-eslint/eslint-plugin": "^3.7.1", - "@typescript-eslint/parser": "^3.7.1", - "chai": "^4.2.0", - "coveralls": "^3.1.0", - "create-ts-index": "^1.13.6", - "eslint": "^6.8.0", - "eslint-config-prettier": "^6.10.1", - "eslint-plugin-prettier": "^3.1.3", - "globby": "^10.0.2", - "marked": ">=2.0.0", - "mocha": "^8.3.2", - "mocha-lcov-reporter": "^1.3.0", - "nyc": "^15.1.0", - "prettier": "^2.0.5", - "prettier-plugin-organize-imports": "^1.1.1", - "ts-node": "^8.10.2", - "typedoc": "^0.20.34", - "typescript": "^3.9.7" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.12.tgz", - "integrity": "sha512-3eJJ841uKxeV8dcN/2yGEUy+RfgQspPEgQat85umsE1rotuquQ2AbIub4S6j7c50a2d+4myc+zSlnXeIHrOnhQ==", - "dev": true - }, - "node_modules/@babel/core": { - "version": "7.13.14", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.14.tgz", - "integrity": "sha512-wZso/vyF4ki0l0znlgM4inxbdrUvCb+cVz8grxDq+6C9k6qbqoIJteQOKicaKjCipU3ISV+XedCqpL2RJJVehA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.9", - "@babel/helper-compilation-targets": "^7.13.13", - "@babel/helper-module-transforms": "^7.13.14", - "@babel/helpers": "^7.13.10", - "@babel/parser": "^7.13.13", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.13", - "@babel/types": "^7.13.14", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "semver": "^6.3.0", - "source-map": "^0.5.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core/node_modules/@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.12.13" - } - }, - "node_modules/@babel/core/node_modules/@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", - "dev": true - }, - "node_modules/@babel/core/node_modules/@babel/highlight": { - "version": "7.13.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.10.tgz", - "integrity": "sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.12.11", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.13.9", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.9.tgz", - "integrity": "sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.13.0", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.13.13", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.13.tgz", - "integrity": "sha512-q1kcdHNZehBwD9jYPh3WyXcsFERi39X4I59I3NadciWtNDyZ6x+GboOxncFK0kXlKIv6BJm5acncehXWUjWQMQ==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.13.12", - "@babel/helper-validator-option": "^7.12.17", - "browserslist": "^4.14.5", - "semver": "^6.3.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", - "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", - "dev": true, - "dependencies": { - "@babel/helper-get-function-arity": "^7.12.13", - "@babel/template": "^7.12.13", - "@babel/types": "^7.12.13" - } - }, - "node_modules/@babel/helper-get-function-arity": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", - "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.12.13" - } - }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz", - "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.13.12" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz", - "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.13.12" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.13.14", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.13.14.tgz", - "integrity": "sha512-QuU/OJ0iAOSIatyVZmfqB0lbkVP0kDRiKj34xy+QNsnVZi/PA6BoSoreeqnxxa9EHFAIL0R9XOaAR/G9WlIy5g==", - "dev": true, - "dependencies": { - "@babel/helper-module-imports": "^7.13.12", - "@babel/helper-replace-supers": "^7.13.12", - "@babel/helper-simple-access": "^7.13.12", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/helper-validator-identifier": "^7.12.11", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.13", - "@babel/types": "^7.13.14" - } - }, - "node_modules/@babel/helper-module-transforms/node_modules/@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", - "dev": true - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", - "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.12.13" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz", - "integrity": "sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==", - "dev": true, - "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.13.12", - "@babel/helper-optimise-call-expression": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.12" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz", - "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.13.12" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", - "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.12.13" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", - "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", - "dev": true - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.12.17", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", - "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==", - "dev": true - }, - "node_modules/@babel/helpers": { - "version": "7.13.10", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.13.10.tgz", - "integrity": "sha512-4VO883+MWPDUVRF3PhiLBUFHoX/bsLTGFpFK/HqvvfBZz2D57u9XzPVNFVBTc0PW/CWR9BXTOKt8NF4DInUHcQ==", - "dev": true, - "dependencies": { - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.10.4", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.13.13", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.13.tgz", - "integrity": "sha512-OhsyMrqygfk5v8HmWwOzlYjJrtLaFhF34MrfG/Z73DgYCI6ojNUTUp2TYbtnjo8PegeJp12eamsNettCQjKjVw==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/template": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", - "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@babel/parser": "^7.12.13", - "@babel/types": "^7.12.13" - } - }, - "node_modules/@babel/template/node_modules/@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.12.13" - } - }, - "node_modules/@babel/template/node_modules/@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", - "dev": true - }, - "node_modules/@babel/template/node_modules/@babel/highlight": { - "version": "7.13.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.10.tgz", - "integrity": "sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.12.11", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.13.13", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.13.tgz", - "integrity": "sha512-CblEcwmXKR6eP43oQGG++0QMTtCjAsa3frUuzHoiIJWpaIIi8dwMyEFUJoXRLxagGqCK+jALRwIO+o3R9p/uUg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.9", - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.13.13", - "@babel/types": "^7.13.13", - "debug": "^4.1.0", - "globals": "^11.1.0" - } - }, - "node_modules/@babel/traverse/node_modules/@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.12.13" - } - }, - "node_modules/@babel/traverse/node_modules/@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", - "dev": true - }, - "node_modules/@babel/traverse/node_modules/@babel/highlight": { - "version": "7.13.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.10.tgz", - "integrity": "sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.12.11", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "node_modules/@babel/types": { - "version": "7.13.14", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.14.tgz", - "integrity": "sha512-A2aa3QTkWoyqsZZFl56MLUsfmh7O0gN41IPvXAE/++8ojpbz12SszD7JEGYVdn4f9Kt4amIei07swF1h4AqmmQ==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" - } - }, - "node_modules/@babel/types/node_modules/@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", - "dev": true - }, - "node_modules/@dabh/diagnostics": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.2.tgz", - "integrity": "sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q==", - "dependencies": { - "colorspace": "1.1.x", - "enabled": "2.0.x", - "kuler": "^2.0.0" - } - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@js-joda/core": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@js-joda/core/-/core-3.2.0.tgz", - "integrity": "sha512-PMqgJ0sw5B7FKb2d5bWYIoxjri+QlW/Pys7+Rw82jSH0QN3rB05jZ/VrrsUdh1w4+i2kw9JOejXGq/KhDOX7Kg==" - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", - "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", - "dependencies": { - "@nodelib/fs.stat": "2.0.3", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", - "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", - "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", - "dependencies": { - "@nodelib/fs.scandir": "2.1.3", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@oclif/command": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@oclif/command/-/command-1.7.0.tgz", - "integrity": "sha512-TkknFtWcZI8te0E8sW+ohiblExrLx73rIcV4KdIzDX01u+oTZWZaap51F6TSGFnR/Gey0WctaDvJhZlt4xgKdA==", - "dependencies": { - "@oclif/config": "^1.15.1", - "@oclif/errors": "^1.3.3", - "@oclif/parser": "^3.8.3", - "@oclif/plugin-help": "^3", - "debug": "^4.1.1", - "semver": "^5.6.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@oclif/command/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/@oclif/config": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/@oclif/config/-/config-1.16.0.tgz", - "integrity": "sha512-vOnMPQcHokC03WBCuLipTxksTwgZcmDOnH2H0UHqndfKKN9GVDzpZTH6zaFVQBdjTME5VtRzg9A2UaNmq6OXWw==", - "dependencies": { - "@oclif/errors": "^1.3.3", - "@oclif/parser": "^3.8.0", - "debug": "^4.1.1", - "globby": "^11.0.1", - "is-wsl": "^2.1.1", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@oclif/config/node_modules/globby": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", - "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@oclif/dev-cli": { - "version": "1.22.2", - "resolved": "https://registry.npmjs.org/@oclif/dev-cli/-/dev-cli-1.22.2.tgz", - "integrity": "sha512-c7633R37RxrQIpwqPKxjNRm6/jb1yuG8fd16hmNz9Nw+/MUhEtQtKHSCe9ScH8n5M06l6LEo4ldk9LEGtpaWwA==", - "dev": true, - "dependencies": { - "@oclif/command": "^1.5.13", - "@oclif/config": "^1.12.12", - "@oclif/errors": "^1.2.2", - "@oclif/plugin-help": "^2.1.6", - "cli-ux": "^5.2.1", - "debug": "^4.1.1", - "fs-extra": "^7.0.1", - "github-slugger": "^1.2.1", - "lodash": "^4.17.11", - "normalize-package-data": "^2.5.0", - "qqjs": "^0.3.10", - "tslib": "^1.9.3" - }, - "bin": { - "oclif-dev": "bin/run" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/@oclif/dev-cli/node_modules/@oclif/plugin-help": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@oclif/plugin-help/-/plugin-help-2.2.3.tgz", - "integrity": "sha512-bGHUdo5e7DjPJ0vTeRBMIrfqTRDBfyR5w0MP41u0n3r7YG5p14lvMmiCXxi6WDaP2Hw5nqx3PnkAIntCKZZN7g==", - "dev": true, - "dependencies": { - "@oclif/command": "^1.5.13", - "chalk": "^2.4.1", - "indent-string": "^4.0.0", - "lodash.template": "^4.4.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0", - "widest-line": "^2.0.1", - "wrap-ansi": "^4.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@oclif/dev-cli/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/@oclif/dev-cli/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@oclif/dev-cli/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@oclif/dev-cli/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "node_modules/@oclif/dev-cli/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "node_modules/@oclif/dev-cli/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@oclif/dev-cli/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@oclif/dev-cli/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@oclif/dev-cli/node_modules/wrap-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-4.0.0.tgz", - "integrity": "sha512-uMTsj9rDb0/7kk1PbcbCcwvHUxp60fGDB/NNXpVa0Q+ic/e7y5+BwTxKfQ33VYgDppSwi/FBzpetYzo8s6tfbg==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@oclif/dev-cli/node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@oclif/dev-cli/node_modules/wrap-ansi/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@oclif/dev-cli/node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@oclif/errors": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@oclif/errors/-/errors-1.3.3.tgz", - "integrity": "sha512-EJR6AIOEkt/NnARNIVAskPDVtdhtO5TTNXmhDrGqMoWVsr0R6DkkLrMyq95BmHvlVWM1nduoq4fQPuCyuF2jaA==", - "dependencies": { - "clean-stack": "^3.0.0", - "fs-extra": "^9.0.1", - "indent-string": "^4.0.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@oclif/errors/node_modules/fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^1.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@oclif/linewrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@oclif/linewrap/-/linewrap-1.0.0.tgz", - "integrity": "sha512-Ups2dShK52xXa8w6iBWLgcjPJWjais6KPJQq3gQ/88AY6BXoTX+MIGFPrWQO1KLMiQfoTpcLnUwloN4brrVUHw==" - }, - "node_modules/@oclif/parser": { - "version": "3.8.5", - "resolved": "https://registry.npmjs.org/@oclif/parser/-/parser-3.8.5.tgz", - "integrity": "sha512-yojzeEfmSxjjkAvMRj0KzspXlMjCfBzNRPkWw8ZwOSoNWoJn+OCS/m/S+yfV6BvAM4u2lTzX9Y5rCbrFIgkJLg==", - "dependencies": { - "@oclif/errors": "^1.2.2", - "@oclif/linewrap": "^1.0.0", - "chalk": "^2.4.2", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@oclif/plugin-autocomplete": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@oclif/plugin-autocomplete/-/plugin-autocomplete-0.3.0.tgz", - "integrity": "sha512-gCuIUCswvoU1BxDDvHSUGxW8rFagiacle8jHqE49+WnuniXD/N8NmJvnzmlNyc8qLE192CnKK+qYyAF+vaFQBg==", - "dependencies": { - "@oclif/command": "^1.5.13", - "@oclif/config": "^1.13.0", - "chalk": "^4.1.0", - "cli-ux": "^5.2.1", - "debug": "^4.0.0", - "fs-extra": "^9.0.1", - "moment": "^2.22.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@oclif/plugin-autocomplete/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@oclif/plugin-autocomplete/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@oclif/plugin-autocomplete/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@oclif/plugin-autocomplete/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@oclif/plugin-autocomplete/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/@oclif/plugin-help": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@oclif/plugin-help/-/plugin-help-3.1.0.tgz", - "integrity": "sha512-orSWpXGlJaX16eSjAtI8scA8QhrjQOaCSHodEx52t18JKbIVzG8jcngugyWAOB/V4jhPl0rdiVk9XFsaIIiG2g==", - "dependencies": { - "@oclif/command": "^1.5.20", - "@oclif/config": "^1.15.1", - "chalk": "^2.4.1", - "indent-string": "^4.0.0", - "lodash.template": "^4.4.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0", - "widest-line": "^2.0.1", - "wrap-ansi": "^4.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@oclif/plugin-help/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/@oclif/plugin-help/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@oclif/plugin-help/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@oclif/plugin-help/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "node_modules/@oclif/plugin-help/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "node_modules/@oclif/plugin-help/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "engines": { - "node": ">=4" - } - }, - "node_modules/@oclif/plugin-help/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@oclif/plugin-help/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@oclif/plugin-help/node_modules/wrap-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-4.0.0.tgz", - "integrity": "sha512-uMTsj9rDb0/7kk1PbcbCcwvHUxp60fGDB/NNXpVa0Q+ic/e7y5+BwTxKfQ33VYgDppSwi/FBzpetYzo8s6tfbg==", - "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@oclif/plugin-help/node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "engines": { - "node": ">=4" - } - }, - "node_modules/@oclif/plugin-help/node_modules/wrap-ansi/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@oclif/plugin-help/node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@oclif/screen": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@oclif/screen/-/screen-1.0.4.tgz", - "integrity": "sha512-60CHpq+eqnTxLZQ4PGHYNwUX572hgpMHGPtTWMjdTMsAvlm69lZV/4ly6O3sAYkomo4NggGcomrDpBe34rxUqw==", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@oclif/test": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@oclif/test/-/test-1.2.8.tgz", - "integrity": "sha512-HCh0qPge1JCqTEw4s2ScnicEZd4Ro4/0VvdjpsfCiX6fuDV53fRZ2uqLTgxKGHrVoqOZnVrRZHyhFyEsFGs+zQ==", - "dev": true, - "dependencies": { - "fancy-test": "^1.4.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@types/chai": { - "version": "4.2.12", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.12.tgz", - "integrity": "sha512-aN5IAC8QNtSUdQzxu7lGBgYAOuU1tmRU4c9dIq5OKGf/SBVjXo+ffM2wEjudAWbgpOhy60nLoAGH1xm8fpCKFQ==", - "dev": true - }, - "node_modules/@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" - }, - "node_modules/@types/eslint-visitor-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", - "dev": true - }, - "node_modules/@types/figlet": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@types/figlet/-/figlet-1.2.0.tgz", - "integrity": "sha512-TDZkNpYfkc3X8yv7w1QBziZmmxzNfGKX+YjeNkMpmSiNV0QOdNf9G5cEZB3FH1/oaqpSQEdxuDzURdju2L3lng==", - "dev": true - }, - "node_modules/@types/glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==", - "dev": true, - "dependencies": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "node_modules/@types/handlebars": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@types/handlebars/-/handlebars-4.1.0.tgz", - "integrity": "sha512-gq9YweFKNNB1uFK71eRqsd4niVkXrxHugqWFQkeLRJvGjnxsLr16bYtcsG4tOFwmYi0Bax+wCkbf1reUfdl4kA==", - "dev": true, - "dependencies": { - "handlebars": "*" - } - }, - "node_modules/@types/inquirer": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/@types/inquirer/-/inquirer-7.3.1.tgz", - "integrity": "sha512-osD38QVIfcdgsPCT0V3lD7eH0OFurX71Jft18bZrsVQWVRt6TuxRzlr0GJLrxoHZR2V5ph7/qP8se/dcnI7o0g==", - "dev": true, - "dependencies": { - "@types/through": "*", - "rxjs": "^6.4.0" - } - }, - "node_modules/@types/js-yaml": { - "version": "3.12.5", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.5.tgz", - "integrity": "sha512-JCcp6J0GV66Y4ZMDAQCXot4xprYB+Zfd3meK9+INSJeVZwJmHAW30BBEEkPzXswMXuiyReUGOP3GxrADc9wPww==", - "dev": true - }, - "node_modules/@types/json-schema": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz", - "integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==", - "dev": true - }, - "node_modules/@types/lodash": { - "version": "4.14.165", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.165.tgz", - "integrity": "sha512-tjSSOTHhI5mCHTy/OOXYIhi2Wt1qcbHmuXD1Ha7q70CgI/I71afO4XtLb/cVexki1oVYchpul/TOuu3Arcdxrg==", - "dev": true - }, - "node_modules/@types/memorystream": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@types/memorystream/-/memorystream-0.3.0.tgz", - "integrity": "sha512-gzh6mqZcLryYHn4g2MuMWjo9J1+Py/XYwITyZmUxV7ZoBIi7bTbBgSiuC5tcm3UL3gmaiYssQFDlXr/3fK94cw==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "node_modules/@types/mocha": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.2.tgz", - "integrity": "sha512-Lwh0lzzqT5Pqh6z61P3c3P5nm6fzQK/MMHl9UKeneAeInVflBSz1O2EkX6gM6xfJd7FBXBY5purtLx7fUiZ7Hw==", - "dev": true - }, - "node_modules/@types/node": { - "version": "10.17.28", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.28.tgz", - "integrity": "sha512-dzjES1Egb4c1a89C7lKwQh8pwjYmlOAG9dW1pBgxEk57tMrLnssOfEthz8kdkNaBd7lIqQx7APm5+mZ619IiCQ==", - "dev": true - }, - "node_modules/@types/node-forge": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-0.9.4.tgz", - "integrity": "sha512-uFhaKXdhhrLNzfNhXbXJqDwF3jXMzN9qfkdW+IAMnAfwqNZhBcE/cciMITLT0Sg6ls6JYHo3xVWNXAG1g9tm8A==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/semver": { - "version": "7.3.6", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.6.tgz", - "integrity": "sha512-0caWDWmpCp0uifxFh+FaqK3CuZ2SkRR/ZRxAV5+zNdC3QVUi6wyOJnefhPvtNt8NQWXB5OA93BUvZsXpWat2Xw==", - "dev": true - }, - "node_modules/@types/sinon": { - "version": "9.0.11", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-9.0.11.tgz", - "integrity": "sha512-PwP4UY33SeeVKodNE37ZlOsR9cReypbMJOhZ7BVE0lB+Hix3efCOxiJWiE5Ia+yL9Cn2Ch72EjFTRze8RZsNtg==", - "dev": true, - "dependencies": { - "@types/sinonjs__fake-timers": "*" - } - }, - "node_modules/@types/sinonjs__fake-timers": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.2.tgz", - "integrity": "sha512-dIPoZ3g5gcx9zZEszaxLSVTvMReD3xxyyDnQUjA6IYDG9Ba2AV0otMPs+77sG9ojB4Qr2N2Vk5RnKeuA0X/0bg==", - "dev": true - }, - "node_modules/@types/sshpk": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/@types/sshpk/-/sshpk-1.10.5.tgz", - "integrity": "sha512-5EKeKE0YmM2F5xjhk5k6mgL9tx5XpHPqKVaN5c1zCBGSFv4VPRqp1fhGKjo1lkyb7kmvchjgWB8TPAT14+JiRg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/through": { - "version": "0.0.30", - "resolved": "https://registry.npmjs.org/@types/through/-/through-0.0.30.tgz", - "integrity": "sha512-FvnCJljyxhPM3gkRgWmxmDZyAQSiBQQWLI0A0VFL0K7W1oRUrPJSqNO0NvTnLkBcotdlp3lKvaT0JrnyRDkzOg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/winston": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/@types/winston/-/winston-2.4.4.tgz", - "integrity": "sha512-BVGCztsypW8EYwJ+Hq+QNYiT/MUyCif0ouBH+flrY66O5W+KIXAMML6E/0fJpm7VjIzgangahl5S03bJJQGrZw==", - "dev": true, - "dependencies": { - "winston": "*" - } - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.8.0.tgz", - "integrity": "sha512-lFb4VCDleFSR+eo4Ew+HvrJ37ZH1Y9ZyE+qyP7EiwBpcCVxwmUc5PAqhShCQ8N8U5vqYydm74nss+a0wrrCErw==", - "dev": true, - "dependencies": { - "@typescript-eslint/experimental-utils": "3.8.0", - "debug": "^4.1.1", - "functional-red-black-tree": "^1.0.1", - "regexpp": "^3.0.0", - "semver": "^7.3.2", - "tsutils": "^3.17.1" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/@typescript-eslint/experimental-utils": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.8.0.tgz", - "integrity": "sha512-o8T1blo1lAJE0QDsW7nSyvZHbiDzQDjINJKyB44Z3sSL39qBy5L10ScI/XwDtaiunoyKGLiY9bzRk4YjsUZl8w==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/types": "3.8.0", - "@typescript-eslint/typescript-estree": "3.8.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^2.0.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-3.8.0.tgz", - "integrity": "sha512-u5vjOBaCsnMVQOvkKCXAmmOhyyMmFFf5dbkM3TIbg3MZ2pyv5peE4gj81UAbTHwTOXEwf7eCQTUMKrDl/+qGnA==", - "dev": true, - "dependencies": { - "@types/eslint-visitor-keys": "^1.0.0", - "@typescript-eslint/experimental-utils": "3.8.0", - "@typescript-eslint/types": "3.8.0", - "@typescript-eslint/typescript-estree": "3.8.0", - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-3.8.0.tgz", - "integrity": "sha512-8kROmEQkv6ss9kdQ44vCN1dTrgu4Qxrd2kXr10kz2NP5T8/7JnEfYNxCpPkArbLIhhkGLZV3aVMplH1RXQRF7Q==", - "dev": true, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.8.0.tgz", - "integrity": "sha512-MTv9nPDhlKfclwnplRNDL44mP2SY96YmPGxmMbMy6x12I+pERcxpIUht7DXZaj4mOKKtet53wYYXU0ABaiXrLw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "3.8.0", - "@typescript-eslint/visitor-keys": "3.8.0", - "debug": "^4.1.1", - "glob": "^7.1.6", - "is-glob": "^4.0.1", - "lodash": "^4.17.15", - "semver": "^7.3.2", - "tsutils": "^3.17.1" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-3.8.0.tgz", - "integrity": "sha512-gfqQWyVPpT9NpLREXNR820AYwgz+Kr1GuF3nf1wxpHD6hdxI62tq03ToomFnDxY0m3pUB39IF7sil7D5TQexLA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - } - }, - "node_modules/@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true - }, - "node_modules/acorn": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz", - "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", - "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", - "dev": true - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/aggregate-error/node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ajv": { - "version": "6.12.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz", - "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", - "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", - "dependencies": { - "type-fest": "^0.11.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dependencies": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansicolors": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", - "integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=" - }, - "node_modules/anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/append-transform": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", - "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", - "dev": true, - "dependencies": { - "default-require-extensions": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", - "dev": true - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/async": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", - "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", - "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==", - "dev": true - }, - "node_modules/balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "node_modules/base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, - "node_modules/bcrypt-pbkdf/node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "node_modules/bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", - "engines": { - "node": "*" - } - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/bl": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", - "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", - "dev": true, - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, - "node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" - }, - "node_modules/browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "node_modules/browserslist": { - "version": "4.16.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", - "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", - "dev": true, - "dependencies": { - "caniuse-lite": "^1.0.30001219", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.723", - "escalade": "^3.1.1", - "node-releases": "^1.1.71" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/buffer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", - "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", - "dev": true, - "dependencies": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "node_modules/buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "node_modules/buffer-reverse": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-reverse/-/buffer-reverse-1.0.1.tgz", - "integrity": "sha1-SSg8jvpvkBvAH6MwTQYCeXGuL2A=" - }, - "node_modules/buffer-to-arraybuffer": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", - "integrity": "sha1-YGSkD6dutDxyOrqe+PbhIW0QURo=" - }, - "node_modules/caching-transform": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", - "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", - "dev": true, - "dependencies": { - "hasha": "^5.0.0", - "make-dir": "^3.0.0", - "package-hash": "^4.0.0", - "write-file-atomic": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001235", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001235.tgz", - "integrity": "sha512-zWEwIVqnzPkSAXOUlQnPW2oKoYb2aLQ4Q5ejdjBcnH63rfypaW34CxaeBn1VMya2XaEU3P/R2qHpWyj+l0BT1A==", - "dev": true - }, - "node_modules/cardinal": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", - "integrity": "sha1-fMEFXYItISlU0HsIXeolHMe8VQU=", - "dependencies": { - "ansicolors": "~0.3.2", - "redeyed": "~2.1.0" - }, - "bin": { - "cdl": "bin/cdl.js" - } - }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, - "node_modules/catbuffer-typescript": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/catbuffer-typescript/-/catbuffer-typescript-0.1.1.tgz", - "integrity": "sha512-r/z3UKG3YCCdsTEHRXGe3IQxA8OaBRBE31e9du2LOaLStGxYCmxUjfRtJ/DyKfgpS55fJPl3w/VFMnsfwIHmkA==" - }, - "node_modules/chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chalk/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chalk/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/chalk/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "node_modules/chalk/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" - }, - "node_modules/check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", - "dev": true, - "dependencies": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.1" - } - }, - "node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "node_modules/clean-stack": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-3.0.0.tgz", - "integrity": "sha512-RHxtgFvXsRQ+1AM7dlozLDY7ssmvUUh0XEnfnyhYgJTO6beNZHBogiaCwGM9Q3rFrUkYxOtsZRC0zAturg5bjg==", - "dependencies": { - "escape-string-regexp": "4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-progress": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.8.2.tgz", - "integrity": "sha512-qRwBxLldMSfxB+YGFgNRaj5vyyHe1yMpVeDL79c+7puGujdKJHQHydgqXDcrkvQgJ5U/d3lpf6vffSoVVUftVQ==", - "dependencies": { - "colors": "^1.1.2", - "string-width": "^4.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cli-ux": { - "version": "5.4.9", - "resolved": "https://registry.npmjs.org/cli-ux/-/cli-ux-5.4.9.tgz", - "integrity": "sha512-4yCKJbFQqNQxf1v0E5T5aBJLt3SbW6dXc/R7zHp4ycdPMg9fAy5f2vhPsWgXEGCMQg+fgN0Sp7EYcZ1XGkFyUA==", - "dependencies": { - "@oclif/command": "^1.6.0", - "@oclif/errors": "^1.2.1", - "@oclif/linewrap": "^1.0.0", - "@oclif/screen": "^1.0.3", - "ansi-escapes": "^4.3.0", - "ansi-styles": "^4.2.0", - "cardinal": "^2.1.1", - "chalk": "^3.0.0", - "clean-stack": "^3.0.0", - "cli-progress": "^3.4.0", - "extract-stack": "^2.0.0", - "fs-extra": "^9.0.1", - "hyperlinker": "^1.0.0", - "indent-string": "^4.0.0", - "is-wsl": "^2.2.0", - "js-yaml": "^3.13.1", - "lodash": "^4.17.11", - "natural-orderby": "^2.0.1", - "object-treeify": "^1.1.4", - "password-prompt": "^1.1.2", - "semver": "^5.6.0", - "string-width": "^4.2.0", - "strip-ansi": "^5.1.0", - "supports-color": "^7.1.0", - "supports-hyperlinks": "^1.0.1", - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/cli-ux/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/cli-ux/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-ux/node_modules/fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^1.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cli-ux/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-ux/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/cli-ux/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/cli-ux/node_modules/supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-ux/node_modules/tslib": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.0.tgz", - "integrity": "sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g==" - }, - "node_modules/cli-width": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "node_modules/cliui/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/color": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz", - "integrity": "sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w==", - "dependencies": { - "color-convert": "^1.9.1", - "color-string": "^1.5.2" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/color-string": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", - "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", - "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "node_modules/color/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "node_modules/colorette": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", - "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", - "dev": true - }, - "node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/colorspace": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.2.tgz", - "integrity": "sha512-vt+OoIP2d76xLhjwbBaucYlNSpPsrJWPlBTtwCpQKIu6/CSMutyzX93O/Do0qzpH3YoHEes8YEFXyZ797rEhzQ==", - "dependencies": { - "color": "3.0.x", - "text-hex": "1.0.x" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "node_modules/content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.1" - } - }, - "node_modules/convert-source-map/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "node_modules/coveralls": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.1.0.tgz", - "integrity": "sha512-sHxOu2ELzW8/NC1UP5XVLbZDzO4S3VxfFye3XYCznopHy02YjNkHcj5bKaVw2O7hVaBdBjEdQGpie4II1mWhuQ==", - "dev": true, - "dependencies": { - "js-yaml": "^3.13.1", - "lcov-parse": "^1.0.0", - "log-driver": "^1.2.7", - "minimist": "^1.2.5", - "request": "^2.88.2" - }, - "bin": { - "coveralls": "bin/coveralls.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/create-ts-index": { - "version": "1.13.6", - "resolved": "https://registry.npmjs.org/create-ts-index/-/create-ts-index-1.13.6.tgz", - "integrity": "sha512-vBcuficF62laj/wZv01D4YBz1TXTtEM8hsUq7J1k1uyPUHYq3YTWTVQlmlp+Y311KdM6HhPQeC2aHktvQR8u3w==", - "dev": true, - "dependencies": { - "chalk": "^2.4.1", - "commander": "^2.19.0", - "dayjs": "^1.8.14", - "debug": "^4.1.1", - "deepmerge": "^4.2.2", - "fast-glob": "^3.2.2", - "glob": "^7.1.3", - "json5": "^2.1.3", - "merge": "^1.2.1", - "minimatch": "^3.0.4", - "my-easy-fp": "^0.5.1", - "tslib": "^1.10.0", - "yargs": "^15.3.1" - }, - "bin": { - "cti": "dist/cti.js" - } - }, - "node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/cross-spawn/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/crypto-js": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.0.0.tgz", - "integrity": "sha512-bzHZN8Pn+gS7DQA6n+iUmBfl0hO5DJq++QP3U6uTucDtk/0iGpXd/Gg7CGR0p8tJhofJyaKoWBuJI4eAO00BBg==" - }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/dayjs": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.4.tgz", - "integrity": "sha512-RI/Hh4kqRc1UKLOAf/T5zdMMX5DQIlDxwUe3wSyMMnEbGunnpENCdbUgM+dW7kXidZqCttBrmw7BhN4TMddkCw==", - "dev": true - }, - "node_modules/debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "dependencies": { - "mimic-response": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "node_modules/deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/default-require-extensions": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", - "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", - "dev": true, - "dependencies": { - "strip-bom": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/detect-indent": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", - "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dom-walk": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" - }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.3.749", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.749.tgz", - "integrity": "sha512-F+v2zxZgw/fMwPz/VUGIggG4ZndDsYy0vlpthi3tjmDZlcfbhN5mYW0evXUsBr2sUtuDANFtle410A9u/sd/4A==", - "dev": true - }, - "node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/enabled": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", - "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true - }, - "node_modules/es6-object-assign": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", - "integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=" - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", - "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.10.0", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^1.4.3", - "eslint-visitor-keys": "^1.1.0", - "espree": "^6.1.2", - "esquery": "^1.0.1", - "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "inquirer": "^7.0.0", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.14", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.3", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^6.1.2", - "strip-ansi": "^5.2.0", - "strip-json-comments": "^3.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - } - }, - "node_modules/eslint-config-prettier": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz", - "integrity": "sha512-oB8cpLWSAjOVFEJhhyMZh6NOEOtBVziaqdDQ86+qhDHFbZXoRTM7pNSvFRfW/W/L/LrQ38C99J5CGuRBBzBsdA==", - "dev": true, - "dependencies": { - "get-stdin": "^6.0.0" - }, - "bin": { - "eslint-config-prettier-check": "bin/cli.js" - } - }, - "node_modules/eslint-plugin-prettier": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.4.tgz", - "integrity": "sha512-jZDa8z76klRqo+TdGDTFJSavwbnWK2ZpqGKNZ+VvweMW516pDUMmQ2koXvxEE4JhzNvTv+radye/bWGBmA6jmg==", - "dev": true, - "dependencies": { - "prettier-linter-helpers": "^1.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", - "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", - "dev": true, - "dependencies": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/eslint/node_modules/eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eslint/node_modules/globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", - "dev": true, - "dependencies": { - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/eslint/node_modules/regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", - "dev": true, - "engines": { - "node": ">=6.5.0" - } - }, - "node_modules/eslint/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eslint/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/espree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", - "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", - "dev": true, - "dependencies": { - "acorn": "^7.1.1", - "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", - "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz", - "integrity": "sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "dependencies": { - "estraverse": "^4.1.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "node_modules/ethereum-bloom-filters": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.9.tgz", - "integrity": "sha512-GiK/RQkAkcVaEdxKVkPcG07PQ5vD7v2MFSHgZmBJSfMzNRHimntdBithsHAT89tAXnIpzVDWt8iaCD1DvkaxGg==", - "dependencies": { - "js-sha3": "^0.8.0" - } - }, - "node_modules/ethjs-unit": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", - "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=", - "dependencies": { - "bn.js": "4.11.6", - "number-to-bn": "1.7.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/ethjs-unit/node_modules/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" - }, - "node_modules/execa": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", - "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", - "dev": true, - "dependencies": { - "cross-spawn": "^6.0.0", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/execa/node_modules/get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "node_modules/external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dependencies": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/external-editor/node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/extract-stack": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/extract-stack/-/extract-stack-2.0.0.tgz", - "integrity": "sha512-AEo4zm+TenK7zQorGK1f9mJ8L14hnTDi2ZQPR+Mub1NX8zimka1mXpV5LpH8x9HoUmFSHZCfLHqWvp0Y4FxxzQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true, - "engines": [ - "node >=0.6.0" - ] - }, - "node_modules/fancy-test": { - "version": "1.4.10", - "resolved": "https://registry.npmjs.org/fancy-test/-/fancy-test-1.4.10.tgz", - "integrity": "sha512-AaUX6wKS7D5OP2YK2q5G7c8PGx2lgoyLUD7Bbg8z323sb9aebBqzb9UN6phzI73UgO/ViihmNfOxF3kdfZLhew==", - "dev": true, - "dependencies": { - "@types/chai": "*", - "@types/lodash": "*", - "@types/node": "*", - "@types/sinon": "*", - "lodash": "^4.17.13", - "mock-stdin": "^1.0.0", - "nock": "^13.0.0", - "stdout-stderr": "^0.1.9" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", - "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", - "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "node_modules/fast-safe-stringify": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", - "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==" - }, - "node_modules/fastq": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", - "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fecha": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.0.tgz", - "integrity": "sha512-aN3pcx/DSmtyoovUudctc8+6Hl4T+hI9GBBHLjA76jdZl7+b1sgh5g4k+u/GL3dTy1/pnYzKp69FpJ0OicE3Wg==" - }, - "node_modules/figlet": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/figlet/-/figlet-1.5.0.tgz", - "integrity": "sha512-ZQJM4aifMpz6H19AW1VqvZ7l4pOE9p7i/3LyxgO2kp+PO/VcDYNqIHEMtkccqIhTXMKci4kjueJr/iCQEaT/Ww==", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/figures/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", - "dev": true, - "dependencies": { - "flat-cache": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-cache-dir": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", - "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", - "dev": true, - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "bin": { - "flat": "cli.js" - } - }, - "node_modules/flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dev": true, - "dependencies": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", - "dev": true - }, - "node_modules/fn.name": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", - "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" - }, - "node_modules/foreground-child": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/foreground-child/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/foreground-child/node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/foreground-child/node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/foreground-child/node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/foreground-child/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/fromentries": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", - "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", - "dev": true - }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "node_modules/fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/fs-extra/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/fs-extra/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "node_modules/futoin-hkdf": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/futoin-hkdf/-/futoin-hkdf-1.3.3.tgz", - "integrity": "sha512-oR75fYk3B3X9/B02Y6vusrBKucrpC6VjxhRL+C6B7FwUpuSRHbhBNG3AZbcE/xPyJmEQWsyqUFp3VeNNbA3S7A==", - "engines": { - "node": ">=8" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/get-stdin": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", - "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dependencies": { - "assert-plus": "^1.0.0" - } - }, - "node_modules/github-slugger": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.3.0.tgz", - "integrity": "sha512-gwJScWVNhFYSRDvURk/8yhcFBee6aFjye2a7Lhb2bUyRulpIoek9p0I9Kt7PT67d/nUlZbFu8L9RLiA0woQN8Q==", - "dev": true, - "dependencies": { - "emoji-regex": ">=6.0.0 <=6.1.1" - } - }, - "node_modules/github-slugger/node_modules/emoji-regex": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.1.1.tgz", - "integrity": "sha1-xs0OwbBkLio8Z6ETfvxeeW2k+I4=", - "dev": true - }, - "node_modules/glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/global": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "dependencies": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/globby": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", - "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", - "dev": true, - "dependencies": { - "@types/glob": "^7.1.1", - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" - }, - "node_modules/growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true, - "engines": { - "node": ">=4.x" - } - }, - "node_modules/handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", - "dependencies": { - "minimist": "^1.2.5", - "neo-async": "^2.6.0", - "source-map": "^0.6.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "handlebars": "bin/handlebars" - }, - "engines": { - "node": ">=0.4.7" - }, - "optionalDependencies": { - "uglify-js": "^3.1.4" - } - }, - "node_modules/handlebars/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "dev": true, - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "engines": { - "node": ">=4" - } - }, - "node_modules/hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/hasha": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", - "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", - "dev": true, - "dependencies": { - "is-stream": "^2.0.0", - "type-fest": "^0.8.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/hasha/node_modules/is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/hasha/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "bin": { - "he": "bin/he" - } - }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "node_modules/http-call": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/http-call/-/http-call-5.3.0.tgz", - "integrity": "sha512-ahwimsC23ICE4kPl9xTBjKB4inbRaeLyZeRunC/1Jy/Z6X8tv22MEAjK+KBOMSVLaqXPTTmd8638waVIKLGx2w==", - "dev": true, - "dependencies": { - "content-type": "^1.0.4", - "debug": "^4.1.1", - "is-retry-allowed": "^1.1.0", - "is-stream": "^2.0.0", - "parse-json": "^4.0.0", - "tunnel-agent": "^0.6.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/http-call/node_modules/is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, - "node_modules/hyperlinker": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hyperlinker/-/hyperlinker-1.0.0.tgz", - "integrity": "sha512-Ty8UblRWFEcfSuIaajM34LdPXIhbs1ajEX/BBPv24J+enSVaEVY63xQ6lTO9VRYS5LAoghIG0IDJ+p+IPzKUQQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "node_modules/ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", - "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/inquirer": { - "version": "7.3.3", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", - "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", - "dependencies": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.19", - "mute-stream": "0.0.8", - "run-async": "^2.4.0", - "rxjs": "^6.6.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/inquirer/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/inquirer/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/inquirer/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-docker": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz", - "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-function": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", - "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==" - }, - "node_modules/is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-hex-prefixed": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=", - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-retry-allowed": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", - "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-hook": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", - "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", - "dev": true, - "dependencies": { - "append-transform": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "dev": true, - "dependencies": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/istanbul-lib-processinfo": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", - "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", - "dev": true, - "dependencies": { - "archy": "^1.0.0", - "cross-spawn": "^7.0.0", - "istanbul-lib-coverage": "^3.0.0-alpha.1", - "make-dir": "^3.0.0", - "p-map": "^3.0.0", - "rimraf": "^3.0.0", - "uuid": "^3.3.3" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-processinfo/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/istanbul-lib-processinfo/node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-processinfo/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/istanbul-lib-processinfo/node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-processinfo/node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-processinfo/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dev": true, - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", - "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-source-maps/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/istanbul-reports": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", - "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", - "dev": true, - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/js-sha256": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", - "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==" - }, - "node_modules/js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" - }, - "node_modules/js-sha512": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha512/-/js-sha512-0.8.0.tgz", - "integrity": "sha512-PWsmefG6Jkodqt+ePTvBZCSMFgN7Clckjd0O7su3I0+BW2QWUTJNzjktHsztGLhncP2h8mcF9V9Y2Ha59pAViQ==" - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "node_modules/json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "node_modules/json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", - "dependencies": { - "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" - } - }, - "node_modules/jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "node_modules/kuler": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", - "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" - }, - "node_modules/lcov-parse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz", - "integrity": "sha1-6w1GtUER68VhrLTECO+TY73I9+A=", - "dev": true, - "bin": { - "lcov-parse": "bin/cli.js" - } - }, - "node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", - "dev": true - }, - "node_modules/load-json-file": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-6.2.0.tgz", - "integrity": "sha512-gUD/epcRms75Cw8RT1pUdHugZYM5ce64ucs2GEISABwkRsOQr0q2wm/MV2TKThycIe5e0ytRweW2RZxclogCdQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.15", - "parse-json": "^5.0.0", - "strip-bom": "^4.0.0", - "type-fest": "^0.6.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/load-json-file/node_modules/parse-json": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.1.tgz", - "integrity": "sha512-ztoZ4/DYeXQq4E21v169sC8qWINGpcosGv9XhTDvg9/hWvx/zrFkc9BiWxR58OJLHGk28j5BL0SDLeV2WmFZlQ==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/load-json-file/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" - }, - "node_modules/lodash.flattendeep": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", - "dev": true - }, - "node_modules/lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=", - "dev": true - }, - "node_modules/lodash.template": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", - "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", - "dependencies": { - "lodash._reinterpolate": "^3.0.0", - "lodash.templatesettings": "^4.0.0" - } - }, - "node_modules/lodash.templatesettings": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", - "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", - "dependencies": { - "lodash._reinterpolate": "^3.0.0" - } - }, - "node_modules/log-driver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", - "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", - "dev": true, - "engines": { - "node": ">=0.8.6" - } - }, - "node_modules/log-symbols": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", - "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/log-symbols/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/log-symbols/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/log-symbols/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/logform": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.2.0.tgz", - "integrity": "sha512-N0qPlqfypFx7UHNn4B3lzS/b0uLqt2hmuoa+PpuXNYgozdJYAyauF5Ky0BWVjrxDlMWiT3qN4zPq3vVAfZy7Yg==", - "dependencies": { - "colors": "^1.2.1", - "fast-safe-stringify": "^2.0.4", - "fecha": "^4.2.0", - "ms": "^2.1.1", - "triple-beam": "^1.3.0" - } - }, - "node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/lunr": { - "version": "2.3.9", - "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", - "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", - "dev": true - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "node_modules/marked": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-2.0.0.tgz", - "integrity": "sha512-NqRSh2+LlN2NInpqTQnS614Y/3NkVMFFU6sJlRFEpxJ/LHuK/qJECH7/fXZjk4VZstPW/Pevjil/VtSONsLc7Q==", - "dev": true, - "bin": { - "marked": "bin/marked" - }, - "engines": { - "node": ">= 8.16.2" - } - }, - "node_modules/memorystream": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=", - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/merge": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.1.tgz", - "integrity": "sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==", - "dev": true - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/merkletreejs": { - "version": "0.2.18", - "resolved": "https://registry.npmjs.org/merkletreejs/-/merkletreejs-0.2.18.tgz", - "integrity": "sha512-f8bSFaUDPZhot94xkjb83XbG1URaiNLxZy6LWTw2IzbQeCA4YX/UxublGxXdLQIYXbWkDghq6EqwG5u4I7ELmA==", - "dependencies": { - "bignumber.js": "^9.0.1", - "buffer-reverse": "^1.0.1", - "crypto-js": "^3.1.9-1", - "treeify": "^1.1.0", - "web3-utils": "^1.3.4" - }, - "engines": { - "node": ">= 7.6.0" - } - }, - "node_modules/merkletreejs/node_modules/crypto-js": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.3.0.tgz", - "integrity": "sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q==" - }, - "node_modules/micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/mime-db": { - "version": "1.44.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", - "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.27", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", - "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", - "dev": true, - "dependencies": { - "mime-db": "1.44.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", - "dependencies": { - "dom-walk": "^0.1.0" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, - "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true - }, - "node_modules/mocha": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.3.2.tgz", - "integrity": "sha512-UdmISwr/5w+uXLPKspgoV7/RXZwKRTiTjJ2/AC5ZiEztIoOYdfKb19+9jNmEInzx5pBsCyJQzarAxqIGBNYJhg==", - "dev": true, - "dependencies": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.1", - "debug": "4.3.1", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.1.6", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "4.0.0", - "log-symbols": "4.0.0", - "minimatch": "3.0.4", - "ms": "2.1.3", - "nanoid": "3.1.20", - "serialize-javascript": "5.0.1", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "which": "2.0.2", - "wide-align": "1.1.3", - "workerpool": "6.1.0", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha" - }, - "engines": { - "node": ">= 10.12.0" - } - }, - "node_modules/mocha-lcov-reporter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/mocha-lcov-reporter/-/mocha-lcov-reporter-1.3.0.tgz", - "integrity": "sha1-Rpve9PivyaEWBW8HnfYYLQr7A4Q=", - "dev": true, - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/mocha/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/mocha/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/mocha/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/mocha/node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/mocha/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/mocha/node_modules/js-yaml": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", - "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/mocha/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/mocha/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/mocha/node_modules/y18n": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", - "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/mock-stdin": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mock-stdin/-/mock-stdin-1.0.0.tgz", - "integrity": "sha512-tukRdb9Beu27t6dN+XztSRHq9J0B/CoAOySGzHfn8UTfmqipA5yNT/sDUEyYdAV3Hpka6Wx6kOMxuObdOex60Q==", - "dev": true - }, - "node_modules/moment": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", - "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==", - "engines": { - "node": "*" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" - }, - "node_modules/my-easy-fp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/my-easy-fp/-/my-easy-fp-0.5.1.tgz", - "integrity": "sha512-musRCJYBnEDDzod5ugUykOqHoZYudhtC90J536tFrMqXfjpBzb0PRzLkadM2chgNFsCebzm9GtC+qjQ7xKgpGg==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "tslib": "1.11.1" - } - }, - "node_modules/my-easy-fp/node_modules/tslib": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", - "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==", - "dev": true - }, - "node_modules/nanoid": { - "version": "3.1.20", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", - "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", - "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "node_modules/natural-orderby": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/natural-orderby/-/natural-orderby-2.0.3.tgz", - "integrity": "sha512-p7KTHxU0CUrcOXe62Zfrb5Z13nLvPhSWR/so3kFulUQU0sgUll2Z0LwpsLN351eOOD+hRGu/F1g+6xDfPeD++Q==", - "engines": { - "node": "*" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" - }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node_modules/noble-ed25519": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/noble-ed25519/-/noble-ed25519-1.0.3.tgz", - "integrity": "sha512-6pOngnpa/GVYURFvE7igoRKm3RrNwQykVLjSCjTvmUdAyOokes75trVDYoi+CGwF8/jh9hWl2zF4ix9OlB9OIQ==" - }, - "node_modules/nock": { - "version": "13.0.11", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.11.tgz", - "integrity": "sha512-sKZltNkkWblkqqPAsjYW0bm3s9DcHRPiMOyKO/PkfJ+ANHZ2+LA2PLe22r4lLrKgXaiSaDQwW3qGsJFtIpQIeQ==", - "dev": true, - "dependencies": { - "debug": "^4.1.0", - "json-stringify-safe": "^5.0.1", - "lodash.set": "^4.3.2", - "propagate": "^2.0.0" - }, - "engines": { - "node": ">= 10.13" - } - }, - "node_modules/node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", - "engines": { - "node": "4.x || >=6.0.0" - } - }, - "node_modules/node-forge": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", - "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/node-preload": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", - "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", - "dev": true, - "dependencies": { - "process-on-spawn": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/node-releases": { - "version": "1.1.73", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz", - "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==", - "dev": true - }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "dependencies": { - "path-key": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/number-to-bn": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", - "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=", - "dependencies": { - "bn.js": "4.11.6", - "strip-hex-prefix": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/number-to-bn/node_modules/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" - }, - "node_modules/nyc": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", - "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", - "dev": true, - "dependencies": { - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "caching-transform": "^4.0.0", - "convert-source-map": "^1.7.0", - "decamelize": "^1.2.0", - "find-cache-dir": "^3.2.0", - "find-up": "^4.1.0", - "foreground-child": "^2.0.0", - "get-package-type": "^0.1.0", - "glob": "^7.1.6", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-hook": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", - "istanbul-lib-processinfo": "^2.0.2", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "make-dir": "^3.0.0", - "node-preload": "^0.2.1", - "p-map": "^3.0.0", - "process-on-spawn": "^1.0.0", - "resolve-from": "^5.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "spawn-wrap": "^2.0.0", - "test-exclude": "^6.0.0", - "yargs": "^15.0.2" - }, - "bin": { - "nyc": "bin/nyc.js" - }, - "engines": { - "node": ">=8.9" - } - }, - "node_modules/nyc/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-treeify": { - "version": "1.1.26", - "resolved": "https://registry.npmjs.org/object-treeify/-/object-treeify-1.1.26.tgz", - "integrity": "sha512-0WTfU7SGM8umY4YPpOg+oHXL66E6dPVCr+sMR6KitPmvg8CkVrHUUZYEFtx0+5Wb0HjFEsBwBYXyGRNeX7c/oQ==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/one-time": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", - "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", - "dependencies": { - "fn.name": "1.x.x" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/onigasm": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/onigasm/-/onigasm-2.2.5.tgz", - "integrity": "sha512-F+th54mPc0l1lp1ZcFMyL/jTs2Tlq4SqIHKIXGZOR/VkHkF9A7Fr5rRr5+ZG/lWeRsyrClLYRq7s/yFQ/XhWCA==", - "dev": true, - "dependencies": { - "lru-cache": "^5.1.1" - } - }, - "node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", - "dev": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/package-hash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", - "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.15", - "hasha": "^5.0.0", - "lodash.flattendeep": "^4.4.0", - "release-zalgo": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-headers": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.3.tgz", - "integrity": "sha512-QhhZ+DCCit2Coi2vmAKbq5RGTRcQUOE2+REgv8vdyu7MnYx2eZztegqtTx99TZ86GTIwqiy3+4nQTWZ2tgmdCA==" - }, - "node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/password-prompt": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/password-prompt/-/password-prompt-1.1.2.tgz", - "integrity": "sha512-bpuBhROdrhuN3E7G/koAju0WjVw9/uQOG5Co5mokNj0MiOSBVZS1JTwM4zl55hu0WFmIEFvO9cU9sJQiBIYeIA==", - "dependencies": { - "ansi-escapes": "^3.1.0", - "cross-spawn": "^6.0.5" - } - }, - "node_modules/password-prompt/node_modules/ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "engines": { - "node": ">=4" - } - }, - "node_modules/path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true - }, - "node_modules/picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "engines": { - "node": ">=8.6" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz", - "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==", - "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "dev": true, - "dependencies": { - "fast-diff": "^1.1.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/prettier-plugin-organize-imports": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-1.1.1.tgz", - "integrity": "sha512-rFA1lnek1FYkMGthm4xBKME41qUKItTovuo24bCGZu/Vu1n3gW71UPLAkIdwewwkZCe29gRVweSOPXvAdckFuw==", - "dev": true - }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "node_modules/process-on-spawn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", - "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", - "dev": true, - "dependencies": { - "fromentries": "^1.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/propagate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", - "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/qqjs": { - "version": "0.3.11", - "resolved": "https://registry.npmjs.org/qqjs/-/qqjs-0.3.11.tgz", - "integrity": "sha512-pB2X5AduTl78J+xRSxQiEmga1jQV0j43jOPs/MTgTLApGFEOn6NgdE2dEjp7nvDtjkIOZbvFIojAiYUx6ep3zg==", - "dev": true, - "dependencies": { - "chalk": "^2.4.1", - "debug": "^4.1.1", - "execa": "^0.10.0", - "fs-extra": "^6.0.1", - "get-stream": "^5.1.0", - "glob": "^7.1.2", - "globby": "^10.0.1", - "http-call": "^5.1.2", - "load-json-file": "^6.2.0", - "pkg-dir": "^4.2.0", - "tar-fs": "^2.0.0", - "tmp": "^0.1.0", - "write-json-file": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/qqjs/node_modules/fs-extra": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz", - "integrity": "sha512-GnyIkKhhzXZUWFCaJzvyDLEEgDkPfb4/TPvJCJVuS8MWZgoSsErf++QpiAlDnKFcqhRlm+tIOcencCjyJE6ZCA==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "node_modules/qqjs/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/qqjs/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/query-string": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", - "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", - "dependencies": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "dependencies": { - "resolve": "^1.1.6" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/redeyed": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", - "integrity": "sha1-iYS1gV2ZyyIEacme7v/jiRPmzAs=", - "dependencies": { - "esprima": "~4.0.0" - } - }, - "node_modules/regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/release-zalgo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", - "dev": true, - "dependencies": { - "es6-error": "^4.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "dev": true, - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "node_modules/resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dependencies": { - "path-parse": "^1.0.6" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "node_modules/run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/run-parallel": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", - "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==" - }, - "node_modules/rxjs": { - "version": "6.6.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz", - "integrity": "sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==", - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, - "node_modules/rxjs-compat": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs-compat/-/rxjs-compat-6.6.7.tgz", - "integrity": "sha512-szN4fK+TqBPOFBcBcsR0g2cmTTUF/vaFEOZNuSdfU8/pGFnNmmn2u8SystYXG1QMrjOPBc6XTKHMVfENDf6hHw==" - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/shelljs": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz", - "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==", - "dependencies": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - }, - "bin": { - "shjs": "bin/shjs" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/shiki": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.9.3.tgz", - "integrity": "sha512-NEjg1mVbAUrzRv2eIcUt3TG7X9svX7l3n3F5/3OdFq+/BxUdmBOeKGiH4icZJBLHy354Shnj6sfBTemea2e7XA==", - "dev": true, - "dependencies": { - "onigasm": "^2.2.5", - "vscode-textmate": "^5.2.0" - } - }, - "node_modules/shx": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/shx/-/shx-0.3.2.tgz", - "integrity": "sha512-aS0mWtW3T2sHAenrSrip2XGv39O9dXIFUqxAEWHEOS1ePtGIBavdPJY1kE2IHl14V/4iCbUiNDPGdyYTtmhSoA==", - "dependencies": { - "es6-object-assign": "^1.0.3", - "minimist": "^1.2.0", - "shelljs": "^0.8.1" - }, - "bin": { - "shx": "lib/cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" - }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" - }, - "node_modules/simple-get": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz", - "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==", - "dependencies": { - "decompress-response": "^3.3.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "node_modules/simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", - "dependencies": { - "is-arrayish": "^0.3.1" - } - }, - "node_modules/simple-swizzle/node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/slice-ansi/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/slice-ansi/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/sort-keys": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-4.0.0.tgz", - "integrity": "sha512-hlJLzrn/VN49uyNkZ8+9b+0q9DjmmYcYOnbMQtpkLrYpPwRApDPZfmqbUfJnAA3sb/nRib+nDot7Zi/1ER1fuA==", - "dev": true, - "dependencies": { - "is-plain-obj": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/spawn-wrap": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", - "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", - "dev": true, - "dependencies": { - "foreground-child": "^2.0.0", - "is-windows": "^1.0.2", - "make-dir": "^3.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "which": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/spawn-wrap/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/spawn-wrap/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", - "dev": true - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "node_modules/sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sshpk/node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "node_modules/stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", - "engines": { - "node": "*" - } - }, - "node_modules/stdout-stderr": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/stdout-stderr/-/stdout-stderr-0.1.13.tgz", - "integrity": "sha512-Xnt9/HHHYfjZ7NeQLvuQDyL1LnbsbddgMFKCuaQKwGCdJm8LnstZIXop+uOY36UR1UXXoHXfMbC1KlVdVd2JLA==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dependencies": { - "ansi-regex": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-hex-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", - "dependencies": { - "is-hex-prefixed": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/supports-hyperlinks": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-1.0.1.tgz", - "integrity": "sha512-HHi5kVSefKaJkGYXbDuKbUGRVxqnWGn3J2e39CYcNJEfWciGq2zYtOhXLTlvrOZW1QU7VX67w7fMmWafHX9Pfw==", - "dependencies": { - "has-flag": "^2.0.0", - "supports-color": "^5.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/supports-hyperlinks/node_modules/has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/symbol-openapi-typescript-fetch-client": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/symbol-openapi-typescript-fetch-client/-/symbol-openapi-typescript-fetch-client-0.11.2.tgz", - "integrity": "sha512-A1MAN8/UWlaCEibBf6zxkduZwDNSvWwLPp6JB0GeYI/FAOrw/9nLyuS/NJQ3siGAUclnuejH1wG7KdUg0/4RSw==" - }, - "node_modules/symbol-sdk": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/symbol-sdk/-/symbol-sdk-1.0.1.tgz", - "integrity": "sha512-G4sdGBfggTSqKs9XchMQAtOfl80Z2eARafxZnzje5qxzfUSQUCFYdBP7IJiA2PDoeyfXJJpzWWTlgq9EzvKm1A==", - "dependencies": { - "@js-joda/core": "^3.2.0", - "bluebird": "^3.7.2", - "catbuffer-typescript": "0.1.1", - "crypto-js": "^4.0.0", - "diff": "^4.0.2", - "futoin-hkdf": "^1.3.2", - "js-sha256": "^0.9.0", - "js-sha3": "^0.8.0", - "js-sha512": "^0.8.0", - "long": "^4.0.0", - "merkletreejs": "^0.2.9", - "minimist": "^1.2.5", - "node-fetch": "^2.6.0", - "ripemd160": "^2.0.2", - "rxjs": "^6.6.3", - "rxjs-compat": "^6.6.3", - "symbol-openapi-typescript-fetch-client": "0.11.2", - "tweetnacl": "^1.0.3", - "utf8": "^2.1.2", - "ws": "^7.3.1" - } - }, - "node_modules/symbol-sdk/node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", - "dev": true, - "dependencies": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/table/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/table/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "node_modules/table/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/table/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/table/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tar-fs": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.0.tgz", - "integrity": "sha512-9uW5iDvrIMCVpvasdFHW0wJPez0K4JnMZtsuIeDI7HyMGJNxmDZDOCQROr7lXyS+iL/QMpj07qcjGYTSdRFXUg==", - "dev": true, - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.0.0" - } - }, - "node_modules/tar-stream": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.3.tgz", - "integrity": "sha512-Z9yri56Dih8IaK8gncVPx4Wqt86NDmQTSh49XLZgjWpGZL9GK9HKParS2scqHCC4w6X9Gh2jwaU45V47XTKwVA==", - "dev": true, - "dependencies": { - "bl": "^4.0.1", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/text-hex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", - "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "node_modules/timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tmp": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.1.0.tgz", - "integrity": "sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==", - "dev": true, - "dependencies": { - "rimraf": "^2.6.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/treeify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz", - "integrity": "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/triple-beam": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", - "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" - }, - "node_modules/ts-node": { - "version": "8.10.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", - "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", - "dev": true, - "dependencies": { - "arg": "^4.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "source-map-support": "^0.5.17", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/ts-node/node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/tslib": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", - "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==" - }, - "node_modules/tsutils": { - "version": "3.17.1", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", - "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" - }, - "node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", - "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/typedoc": { - "version": "0.20.34", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.20.34.tgz", - "integrity": "sha512-es+N/KyGPcHl9cAuYh1Z5m7HzwcmfNLghkmb2pzGz7HRDS5GS2uA3hu/c2cv4gCxDsw8pPUPCOvww+Hzf48Kug==", - "dev": true, - "dependencies": { - "colors": "^1.4.0", - "fs-extra": "^9.1.0", - "handlebars": "^4.7.7", - "lodash": "^4.17.21", - "lunr": "^2.3.9", - "marked": "^2.0.1", - "minimatch": "^3.0.0", - "progress": "^2.0.3", - "shelljs": "^0.8.4", - "shiki": "^0.9.3", - "typedoc-default-themes": "^0.12.9" - }, - "bin": { - "typedoc": "bin/typedoc" - }, - "engines": { - "node": ">= 10.8.0" - } - }, - "node_modules/typedoc-default-themes": { - "version": "0.12.10", - "resolved": "https://registry.npmjs.org/typedoc-default-themes/-/typedoc-default-themes-0.12.10.tgz", - "integrity": "sha512-fIS001cAYHkyQPidWXmHuhs8usjP5XVJjWB8oZGqkTowZaz3v7g3KDZeeqE82FBrmkAnIBOY3jgy7lnPnqATbA==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/typedoc/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/typedoc/node_modules/marked": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/marked/-/marked-2.0.1.tgz", - "integrity": "sha512-5+/fKgMv2hARmMW7DOpykr2iLhl0NgjyELk5yn92iE7z8Se1IS9n3UsFm86hFXIkvMBmVxki8+ckcpjBeyo/hw==", - "dev": true, - "bin": { - "marked": "bin/marked" - }, - "engines": { - "node": ">= 8.16.2" - } - }, - "node_modules/typedoc/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/typescript": { - "version": "3.9.7", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz", - "integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/uglify-js": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.10.1.tgz", - "integrity": "sha512-RjxApKkrPJB6kjJxQS3iZlf///REXWYxYJxO/MpmlQzVkDWVI3PSnCBWezMecmTU/TRkNxrl8bmsfFQCp+LO+Q==", - "optional": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/underscore": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", - "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==" - }, - "node_modules/universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/url-set-query": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", - "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=" - }, - "node_modules/utf8": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.2.tgz", - "integrity": "sha1-H6DZJw6b6FDZsFAn9jUZv0ZFfZY=" - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true, - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/v8-compile-cache": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", - "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==", - "dev": true - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/vscode-textmate": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.4.0.tgz", - "integrity": "sha512-c0Q4zYZkcLizeYJ3hNyaVUM2AA8KDhNCA3JvXY8CeZSJuBdAy3bAvSbv46RClC4P3dSO9BdwhnKEx2zOo6vP/w==", - "dev": true - }, - "node_modules/web3-utils": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.3.6.tgz", - "integrity": "sha512-hHatFaQpkQgjGVER17gNx8u1qMyaXFZtM0y0XLGH1bzsjMPlkMPLRcYOrZ00rOPfTEuYFOdrpGOqZXVmGrMZRg==", - "dependencies": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "underscore": "1.12.1", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-utils/node_modules/utf8": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", - "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==" - }, - "node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "node_modules/wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "dependencies": { - "string-width": "^1.0.2 || 2" - } - }, - "node_modules/wide-align/node_modules/ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/widest-line": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", - "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", - "dependencies": { - "string-width": "^2.1.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/widest-line/node_modules/ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "engines": { - "node": ">=4" - } - }, - "node_modules/widest-line/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "engines": { - "node": ">=4" - } - }, - "node_modules/widest-line/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/widest-line/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/winston": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.3.3.tgz", - "integrity": "sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw==", - "dependencies": { - "@dabh/diagnostics": "^2.0.2", - "async": "^3.1.0", - "is-stream": "^2.0.0", - "logform": "^2.2.0", - "one-time": "^1.0.0", - "readable-stream": "^3.4.0", - "stack-trace": "0.0.x", - "triple-beam": "^1.3.0", - "winston-transport": "^4.4.0" - }, - "engines": { - "node": ">= 6.4.0" - } - }, - "node_modules/winston-transport": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.4.0.tgz", - "integrity": "sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw==", - "dependencies": { - "readable-stream": "^2.3.7", - "triple-beam": "^1.2.0" - }, - "engines": { - "node": ">= 6.4.0" - } - }, - "node_modules/winston-transport/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/winston-transport/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/winston-transport/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/winston/node_modules/is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" - }, - "node_modules/workerpool": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", - "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", - "dev": true - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "node_modules/write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "dependencies": { - "mkdirp": "^0.5.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/write-json-file": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/write-json-file/-/write-json-file-4.3.0.tgz", - "integrity": "sha512-PxiShnxf0IlnQuMYOPPhPkhExoCQuTUNPOa/2JWCYTmBquU9njyyDuwRKN26IZBlp4yn1nt+Agh2HOOBl+55HQ==", - "dev": true, - "dependencies": { - "detect-indent": "^6.0.0", - "graceful-fs": "^4.1.15", - "is-plain-obj": "^2.0.0", - "make-dir": "^3.0.0", - "sort-keys": "^4.0.0", - "write-file-atomic": "^3.0.0" - }, - "engines": { - "node": ">=8.3" - } - }, - "node_modules/ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", - "engines": { - "node": ">=8.3.0" - } - }, - "node_modules/xhr": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", - "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", - "dependencies": { - "global": "~4.4.0", - "is-function": "^1.0.1", - "parse-headers": "^2.0.0", - "xtend": "^4.0.0" - } - }, - "node_modules/xhr-request": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", - "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", - "dependencies": { - "buffer-to-arraybuffer": "^0.0.5", - "object-assign": "^4.1.1", - "query-string": "^5.0.1", - "simple-get": "^2.7.0", - "timed-out": "^4.0.1", - "url-set-query": "^1.0.0", - "xhr": "^2.0.4" - } - }, - "node_modules/xhr-request-promise": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz", - "integrity": "sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==", - "dependencies": { - "xhr-request": "^1.1.0" - } - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "engines": { - "node": ">=0.4" - } - }, - "node_modules/y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", - "dev": true - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "dependencies": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser/node_modules/camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser/node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - } - } - }, "dependencies": { "@babel/code-frame": { "version": "7.10.4", @@ -7851,6 +816,50 @@ "fancy-test": "^1.4.3" } }, + "@sinonjs/commons": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz", + "integrity": "sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "@sinonjs/samsam": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.0.2.tgz", + "integrity": "sha512-jxPRPp9n93ci7b8hMfJOFDPRLFYadN6FSpeROFTR4UNF4i5b+EK6m4QXPO46BDhFgRy1JuS87zAnFOzCUwMJcQ==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.6.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + } + }, + "@sinonjs/text-encoding": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", + "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "dev": true + }, + "@types/archiver": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/archiver/-/archiver-5.1.0.tgz", + "integrity": "sha512-baFOhanb/hxmcOd1Uey2TfFg43kTSmM6py1Eo7Rjbv/ivcl7PXLhY0QgXGf50Hx/eskGCFqPfhs/7IZLb15C5g==", + "dev": true, + "requires": { + "@types/glob": "*" + } + }, "@types/chai": { "version": "4.2.12", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.12.tgz", @@ -7948,15 +957,6 @@ "integrity": "sha512-dzjES1Egb4c1a89C7lKwQh8pwjYmlOAG9dW1pBgxEk57tMrLnssOfEthz8kdkNaBd7lIqQx7APm5+mZ619IiCQ==", "dev": true }, - "@types/node-forge": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-0.9.4.tgz", - "integrity": "sha512-uFhaKXdhhrLNzfNhXbXJqDwF3jXMzN9qfkdW+IAMnAfwqNZhBcE/cciMITLT0Sg6ls6JYHo3xVWNXAG1g9tm8A==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, "@types/semver": { "version": "7.3.6", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.6.tgz", @@ -7964,27 +964,12 @@ "dev": true }, "@types/sinon": { - "version": "9.0.11", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-9.0.11.tgz", - "integrity": "sha512-PwP4UY33SeeVKodNE37ZlOsR9cReypbMJOhZ7BVE0lB+Hix3efCOxiJWiE5Ia+yL9Cn2Ch72EjFTRze8RZsNtg==", - "dev": true, - "requires": { - "@types/sinonjs__fake-timers": "*" - } - }, - "@types/sinonjs__fake-timers": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.2.tgz", - "integrity": "sha512-dIPoZ3g5gcx9zZEszaxLSVTvMReD3xxyyDnQUjA6IYDG9Ba2AV0otMPs+77sG9ojB4Qr2N2Vk5RnKeuA0X/0bg==", - "dev": true - }, - "@types/sshpk": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/@types/sshpk/-/sshpk-1.10.5.tgz", - "integrity": "sha512-5EKeKE0YmM2F5xjhk5k6mgL9tx5XpHPqKVaN5c1zCBGSFv4VPRqp1fhGKjo1lkyb7kmvchjgWB8TPAT14+JiRg==", + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.4.tgz", + "integrity": "sha512-fOYjrxQv8zJsqOY6V6ecP4eZhQBxtY80X0er1VVnUIAIZo74jHm8e1vguG5Yt4Iv8W2Wr7TgibB8MfRe32k9pA==", "dev": true, "requires": { - "@types/node": "*" + "@sinonjs/fake-timers": "^7.1.0" } }, "@types/through": { @@ -8176,6 +1161,66 @@ "default-require-extensions": "^3.0.0" } }, + "archiver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.0.tgz", + "integrity": "sha512-iUw+oDwK0fgNpvveEsdQ0Ase6IIKztBJU2U0E9MzszMfmVVUyv1QJhS2ITW9ZCqx8dktAxVAjWWkKehuZE8OPg==", + "requires": { + "archiver-utils": "^2.1.0", + "async": "^3.2.0", + "buffer-crc32": "^0.2.1", + "readable-stream": "^3.6.0", + "readdir-glob": "^1.0.0", + "tar-stream": "^2.2.0", + "zip-stream": "^4.1.0" + } + }, + "archiver-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", + "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", + "requires": { + "glob": "^7.1.4", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^2.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", @@ -8205,6 +1250,7 @@ "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, "requires": { "safer-buffer": "~2.1.0" } @@ -8212,7 +1258,8 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true }, "assertion-error": { "version": "1.1.0", @@ -8262,13 +1309,13 @@ "base64-js": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==" }, "bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, "requires": { "tweetnacl": "^0.14.3" }, @@ -8276,7 +1323,8 @@ "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true } } }, @@ -8295,7 +1343,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", - "dev": true, "requires": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -8357,12 +1404,16 @@ "version": "5.6.0", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", - "dev": true, "requires": { "base64-js": "^1.0.2", "ieee754": "^1.1.4" } }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" + }, "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", @@ -8697,9 +1748,9 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "color-string": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", - "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.6.0.tgz", + "integrity": "sha512-c/hGS+kRWJutUBEngKKmk4iH3sD59MBkoxVapS/0wgpCz2u7XsNloxknyvBhzwEs1IbV36D9PwqLPJ2DTu3vMA==", "requires": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" @@ -8746,6 +1797,17 @@ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, + "compress-commons": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.1.tgz", + "integrity": "sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ==", + "requires": { + "buffer-crc32": "^0.2.13", + "crc32-stream": "^4.0.2", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + } + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -8792,6 +1854,24 @@ "request": "^2.88.2" } }, + "crc-32": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.0.tgz", + "integrity": "sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==", + "requires": { + "exit-on-epipe": "~1.0.1", + "printj": "~1.1.0" + } + }, + "crc32-stream": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.2.tgz", + "integrity": "sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==", + "requires": { + "crc-32": "^1.2.0", + "readable-stream": "^3.4.0" + } + }, "create-ts-index": { "version": "1.13.6", "resolved": "https://registry.npmjs.org/create-ts-index/-/create-ts-index-1.13.6.tgz", @@ -8813,6 +1893,14 @@ "yargs": "^15.3.1" } }, + "cross-fetch": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz", + "integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==", + "requires": { + "node-fetch": "2.6.1" + } + }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -8841,6 +1929,7 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, "requires": { "assert-plus": "^1.0.0" } @@ -8952,6 +2041,7 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, "requires": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -8991,7 +2081,6 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, "requires": { "once": "^1.4.0" } @@ -9285,6 +2374,11 @@ } } }, + "exit-on-epipe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", + "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==" + }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -9569,8 +2663,7 @@ "fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, "fs-extra": { "version": "7.0.1", @@ -9666,6 +2759,7 @@ "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, "requires": { "assert-plus": "^1.0.0" } @@ -9910,8 +3004,7 @@ "ieee754": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" }, "ignore": { "version": "5.1.8", @@ -10301,7 +3394,8 @@ "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true }, "jsesc": { "version": "2.5.2", @@ -10369,11 +3463,54 @@ "verror": "1.10.0" } }, + "just-extend": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", + "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", + "dev": true + }, "kuler": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" }, + "lazystream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", + "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "requires": { + "readable-stream": "^2.0.5" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "lcov-parse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz", @@ -10447,12 +3584,38 @@ "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" }, + "lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=" + }, + "lodash.difference": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=" + }, + "lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" + }, "lodash.flattendeep": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "dev": true }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" + }, "lodash.set": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", @@ -10476,6 +3639,11 @@ "lodash._reinterpolate": "^3.0.0" } }, + "lodash.union": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", + "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=" + }, "log-driver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", @@ -10938,15 +4106,28 @@ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" }, + "nise": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.0.tgz", + "integrity": "sha512-W5WlHu+wvo3PaKLsJJkgPup2LrsXCcm7AWwyNZkUnn5rwPkuPBi3Iwk5SQtN0mv+K65k7nKKjwNQ30wg3wLAQQ==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0", + "@sinonjs/fake-timers": "^7.0.4", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "path-to-regexp": "^1.7.0" + } + }, "noble-ed25519": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/noble-ed25519/-/noble-ed25519-1.0.3.tgz", "integrity": "sha512-6pOngnpa/GVYURFvE7igoRKm3RrNwQykVLjSCjTvmUdAyOokes75trVDYoi+CGwF8/jh9hWl2zF4ix9OlB9OIQ==" }, "nock": { - "version": "13.0.11", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.11.tgz", - "integrity": "sha512-sKZltNkkWblkqqPAsjYW0bm3s9DcHRPiMOyKO/PkfJ+ANHZ2+LA2PLe22r4lLrKgXaiSaDQwW3qGsJFtIpQIeQ==", + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/nock/-/nock-13.1.1.tgz", + "integrity": "sha512-YKTR9MjfK3kS9/l4nuTxyYm30cgOExRHzkLNhL8nhEUyU4f8Za/dRxOqjhVT1vGs0svWo3dDnJTUX1qxYeWy5w==", "dev": true, "requires": { "debug": "^4.1.0", @@ -10960,11 +4141,6 @@ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" }, - "node-forge": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", - "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==" - }, "node-preload": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", @@ -10980,6 +4156,11 @@ "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==", "dev": true }, + "node-stream-zip": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/node-stream-zip/-/node-stream-zip-1.13.5.tgz", + "integrity": "sha512-Lfi9xhSNvnJU35+4ZFlECXKJ70etAgJYWAVCdcEpksPnMrgwNqwkCJqdunoViVoFFV38C7AIodYE+2apuoK9Gw==" + }, "normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -11003,8 +4184,7 @@ "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, "npm-run-path": { "version": "2.0.2", @@ -11259,9 +4439,26 @@ "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" }, "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dev": true, + "requires": { + "isarray": "0.0.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + } + } }, "path-type": { "version": "4.0.0", @@ -11321,6 +4518,11 @@ "integrity": "sha512-rFA1lnek1FYkMGthm4xBKME41qUKItTovuo24bCGZu/Vu1n3gW71UPLAkIdwewwkZCe29gRVweSOPXvAdckFuw==", "dev": true }, + "printj": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz", + "integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==" + }, "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -11457,6 +4659,14 @@ "util-deprecate": "^1.0.1" } }, + "readdir-glob": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.1.tgz", + "integrity": "sha512-91/k1EzZwDx6HbERR+zucygRFfiPl2zkIYZtv3Jjr6Mn7SkKcVct8aVO+sSRiGMc6fLf72du3d92/uY63YPdEA==", + "requires": { + "minimatch": "^3.0.4" + } + }, "readdirp": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", @@ -11732,6 +4942,37 @@ } } }, + "sinon": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-11.1.2.tgz", + "integrity": "sha512-59237HChms4kg7/sXhiRcUzdSkKuydDeTiamT/jesUVHshBgL8XAmhgFo0GfK6RruMDM/iRSij1EybmMog9cJw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.8.3", + "@sinonjs/fake-timers": "^7.1.2", + "@sinonjs/samsam": "^6.0.2", + "diff": "^5.0.0", + "nise": "^5.1.0", + "supports-color": "^7.2.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -11888,6 +5129,7 @@ "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, "requires": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -11903,7 +5145,8 @@ "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true } } }, @@ -11927,14 +5170,6 @@ "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, "string-width": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", @@ -11945,6 +5180,14 @@ "strip-ansi": "^6.0.0" } }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", @@ -12039,9 +5282,22 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" + }, + "node-fetch": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz", + "integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==", + "requires": { + "whatwg-url": "^5.0.0" + } } } }, + "symbol-statistics-service-typescript-fetch-client": { + "version": "1.1.1-SNAPSHOT.202110302303", + "resolved": "https://registry.npmjs.org/symbol-statistics-service-typescript-fetch-client/-/symbol-statistics-service-typescript-fetch-client-1.1.1-SNAPSHOT.202110302303.tgz", + "integrity": "sha512-rFhjyOzkerFCk5S7enq6ugSf72Pa5ck3Cna6lXOBFFEiIKVkecQKm/anrcNFhs1ijhY53N6cJta/45mMJGXgiw==" + }, "table": { "version": "5.4.6", "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", @@ -12107,12 +5363,11 @@ } }, "tar-stream": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.3.tgz", - "integrity": "sha512-Z9yri56Dih8IaK8gncVPx4Wqt86NDmQTSh49XLZgjWpGZL9GK9HKParS2scqHCC4w6X9Gh2jwaU45V47XTKwVA==", - "dev": true, + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "requires": { - "bl": "^4.0.1", + "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", @@ -12184,6 +5439,11 @@ "punycode": "^2.1.1" } }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, "treeify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz", @@ -12430,6 +5690,20 @@ } } }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -12772,6 +6046,16 @@ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true + }, + "zip-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.0.tgz", + "integrity": "sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==", + "requires": { + "archiver-utils": "^2.1.0", + "compress-commons": "^4.1.0", + "readable-stream": "^3.6.0" + } } } } diff --git a/package.json b/package.json index d4243d05f..a86ced77e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "symbol-bootstrap", "description": "Symbol tool that allows you creating, configuring and running Symbol's networks", - "version": "1.0.10", + "version": "1.1.0", "author": "Fernando Boucquez ", "bin": { "symbol-bootstrap": "bin/run" @@ -12,6 +12,8 @@ "@oclif/config": "^1.16.0", "@oclif/plugin-autocomplete": "^0.3.0", "@oclif/plugin-help": "^3.1.0", + "archiver": "^5.2.0", + "cross-fetch": "^3.1.4", "figlet": "^1.2.4", "handlebars": "^4.7.7", "inquirer": "^7.3.3", @@ -19,12 +21,12 @@ "lodash": "^4.17.21", "memorystream": "^0.3.1", "noble-ed25519": "^1.0.3", - "node-forge": "^0.10.0", + "node-stream-zip": "^1.12.0", "rxjs": "^6.6.3", "semver": "^7.3.5", "shx": "^0.3.2", - "sshpk": "^1.16.1", "symbol-sdk": "^1.0.1", + "symbol-statistics-service-typescript-fetch-client": "^1.1.1-SNAPSHOT.202110302303", "tslib": "^1.13.0", "utf8": "^2.1.2", "winston": "^3.3.3" @@ -32,6 +34,7 @@ "devDependencies": { "@oclif/dev-cli": "^1.22.2", "@oclif/test": "^1.2.8", + "@types/archiver": "^5.1.0", "@types/chai": "^4.2.12", "@types/figlet": "^1.2.0", "@types/handlebars": "^4.1.0", @@ -41,9 +44,8 @@ "@types/memorystream": "^0.3.0", "@types/mocha": "^8.2.2", "@types/node": "^10.17.28", - "@types/node-forge": "^0.9.4", "@types/semver": "^7.3.6", - "@types/sshpk": "^1.10.5", + "@types/sinon": "^10.0.4", "@types/winston": "^2.4.4", "@typescript-eslint/eslint-plugin": "^3.7.1", "@typescript-eslint/parser": "^3.7.1", @@ -57,9 +59,14 @@ "marked": ">=2.0.0", "mocha": "^8.3.2", "mocha-lcov-reporter": "^1.3.0", + "mock-stdin": "^1.0.0", + "nock": "^13.1.1", "nyc": "^15.1.0", "prettier": "^2.0.5", "prettier-plugin-organize-imports": "^1.1.1", + "rxjs": "^6.6.3", + "rxjs-compat": "^6.6.3", + "sinon": "^11.1.2", "ts-node": "^8.10.2", "typedoc": "^0.20.34", "typescript": "^3.9.7" @@ -93,14 +100,18 @@ "scripts": { "doc": "typedoc --out \"ts-docs\" src && touch ./ts-docs/.nojekyll", "lint": "eslint --cache src/ test/ --ext .ts", + "clean": "npx shx rm -rf ./lib", "lint:fix": "eslint src/ test/ --ext .ts --fix", "prettier": "prettier --write ./src ./test", "style:fix": "npm run create-index-files && npm run prettier && npm run lint:fix && npm run oclif-doc", "create-index-files": "cti create ./src -b -n -e commands", - "postpack": "shx rm -f oclif.manifest.json", + "postpack": "npx shx rm -f oclif.manifest.json", "posttest": "eslint src/ test/ --ext .ts", "oclif-doc": "oclif-dev manifest && oclif-dev readme --multi", - "prepack": "shx rm -rf lib && tsc -b && npm run oclif-doc", + "watch": "tsc -b -w", + "compile": "tsc -b", + "build": "npm run clean && npm run compile", + "prepack": "npm run build && npm run oclif-doc", "test": "nyc --reporter=lcov --extension .ts mocha -r ts-node/register --timeout 900000 --forbid-only \"test/**/*.test.ts\"", "e2e": "nyc --reporter=lcov --extension .ts mocha -r ts-node/register --timeout 900000 --forbid-only \"test/**/*.e2e.ts\"", "coveralls-report": "cat ./coverage/lcov.info | coveralls", diff --git a/presets/bootstrap/network.yml b/presets/bootstrap/network.yml index e99b05c17..3c0fc73c0 100644 --- a/presets/bootstrap/network.yml +++ b/presets/bootstrap/network.yml @@ -124,6 +124,14 @@ faucets: BLACKLIST_MOSAIC_IDS: '[]' EXPLORER_URL: 'http://localhost:{{add $index 90}}/' openPort: '{{add $index 100}}' +httpsProxies: + - name: 'https-proxy' + excludeDockerService: true #disabled as default + openPort: 3001 + #domains: 'symbol-node.example.com -> http://rest-gateway:3000' + stage: 'production' + webSocket: 'true' + serverNamesHashBucketSize: 128 inflation: starting-at-height-1: 0 starting-at-height-10000: 0 diff --git a/presets/mainnet/assembly-api.yml b/presets/mainnet/assembly-api.yml index 4d54d6670..c536ba752 100644 --- a/presets/mainnet/assembly-api.yml +++ b/presets/mainnet/assembly-api.yml @@ -20,3 +20,11 @@ gateways: databaseHost: 'db' openPort: true ipv4_address: 172.20.0.25 +httpsProxies: + - name: 'https-proxy' + excludeDockerService: true #disabled as default + openPort: 3001 + #domains: 'symbol-node.example.com -> http://rest-gateway:3000' + stage: 'production' + webSocket: 'true' + serverNamesHashBucketSize: 128 diff --git a/presets/mainnet/assembly-dual.yml b/presets/mainnet/assembly-dual.yml index 104f965cb..9b955d9c8 100644 --- a/presets/mainnet/assembly-dual.yml +++ b/presets/mainnet/assembly-dual.yml @@ -20,3 +20,11 @@ gateways: databaseHost: 'db' openPort: true ipv4_address: 172.20.0.25 +httpsProxies: + - name: 'https-proxy' + excludeDockerService: true #disabled as default + openPort: 3001 + #domains: 'symbol-node.example.com -> http://rest-gateway:3000' + stage: 'production' + webSocket: 'true' + serverNamesHashBucketSize: 128 diff --git a/presets/mainnet/network.yml b/presets/mainnet/network.yml index 6602be75b..07170c66f 100644 --- a/presets/mainnet/network.yml +++ b/presets/mainnet/network.yml @@ -13,15 +13,16 @@ maxMosaicAtomicUnits: 8999999999000000 minHarvesterBalance: 10000000000 minVoterBalance: 3000000000000 nemesisGenerationHashSeed: 57F7DA205008026C776CB6AED843393F04CD458E0AA2D9F1D5F31A402072B2D6 -harvestNetworkFeeSinkAddress: NBUTOBVT5JQDCV6UEPCPFHWWOAOPOCLA5AY5FLI -namespaceRentalFeeSinkAddress: NBDTBUD6R32ZYJWDEWLJM4YMOX3OOILHGDUMTSA -mosaicRentalFeeSinkAddress: NC733XE7DF46Q7QYLIIZBBSCJN2BEEP5FQ6PAYA +harvestNetworkFeeSinkAddressV1: NBUTOBVT5JQDCV6UEPCPFHWWOAOPOCLA5AY5FLI +harvestNetworkFeeSinkAddress: NAVORTEX3IPBAUWQBBI3I3BDIOS4AVHPZLCFC7Y +namespaceRentalFeeSinkAddressV1: NBDTBUD6R32ZYJWDEWLJM4YMOX3OOILHGDUMTSA +namespaceRentalFeeSinkAddress: NCVORTEX4XD5IQASZQEHDWUXT33XBOTBMKFDCLI +mosaicRentalFeeSinkAddressV1: NC733XE7DF46Q7QYLIIZBBSCJN2BEEP5FQ6PAYA +mosaicRentalFeeSinkAddress: NCVORTEX4XD5IQASZQEHDWUXT33XBOTBMKFDCLI +treasuryReissuanceBlockTransactionsHash: 1A95DA607D545C7E5103EC8D3411E6E505D5B7567E8F3857CD6AEBAD90D3B07F +treasuryReissuanceFallbackBlockTransactionsHash: E1DFEA3F15CDB974EA621A4A9E60B2EC676802DEAA542FE665D2FA364BB4C13D nemesisSignerPublicKey: BE0B4CF546B7B4F4BBFCFF9F574FDA527C07A53D3FC76F8BB7DB746F8E8E0A9F networkType: 104 -rewardProgramCaFile: >- - LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJZVENDQVJNQ0ZHVWJMZ1FuUEU4azc2VUczNWNGME9yNWh6M1RNQVVHQXl0bGNEQlRNUm93R0FZRFZRUUsKREJGT1JVMGdSM0p2ZFhBZ1RHbHRhWFJsWkRFYk1Ca0dBMVVFQXd3U2MzbHRZbTlzY0d4aGRHWnZjbTB1WTI5dApNUmd3RmdZRFZRUUxEQTlTWlhkaGNtUnpJRkJ5YjJkeVlXMHdIaGNOTWpFd05ESTJNVFV4TlRVMFdoY05OREV3Ck5ESXhNVFV4TlRVMFdqQlRNUm93R0FZRFZRUUtEQkZPUlUwZ1IzSnZkWEFnVEdsdGFYUmxaREViTUJrR0ExVUUKQXd3U2MzbHRZbTlzY0d4aGRHWnZjbTB1WTI5dE1SZ3dGZ1lEVlFRTERBOVNaWGRoY21SeklGQnliMmR5WVcwdwpLakFGQmdNclpYQURJUUNGMEJ5NENlTTV3MWxoZWU3YVlzb0YvbEJMT29kZDI0ZWhqa3k0NnV4djREQUZCZ01yClpYQURRUURneUhSeU1zbVpCV3pFZWlDczJWMVZ1dHFaNWxzZ2tWN0w4K2dxZ3NQTmpCajRlaUpWaDdHUWV0SEcKZXlFaWZoUXFwdnpqWmQycW9MWUNrYWV3TUNRRQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== -rewardProgramEnrollmentAddress: NDG2F6IHON7EDOXZCHSTSJ2YMUHDFXAQ2EUZHFA -rewardProgramControllerApiUrl: 'http://node-monitoring.symbolblockchain.io:7890' totalChainImportance: 7842928625000000 initialCurrencyAtomicUnits: 7842928625000000 importanceGrouping: 720 @@ -30,7 +31,7 @@ minVotingKeyLifetime: 112 maxVotingKeyLifetime: 360 votingKeyDesiredLifetime: 360 votingKeyDesiredFutureLifetime: 60 -lastKnownNetworkEpoch: 181 +lastKnownNetworkEpoch: 467 stepDuration: 5m maxBlockFutureTime: 300ms maxAccountRestrictionValues: 100 @@ -43,6 +44,7 @@ defaultDynamicFeeMultiplier: 100 rootNamespaceRentalFeePerBlock: 2 childNamespaceRentalFee: 100000 totalVotingBalanceCalculationFix: 528000 +treasuryReissuance: 689761 mosaicRentalFee: 500000 throttlingBurst: 80 throttlingRate: 60 @@ -51,860 +53,87 @@ minProofSize: 0 syncTimeout: 5m maxChildNamespaces: 100 nonVotingUnfinalizedBlocksDuration: 10m +treasuryReissuanceEpoch: 481 +treasuryReissuanceEpochIneligibleVoterAddresses: + - ND6667LJBJJ6UMJSZKN2BLHQCS3WNZ3W4UGCFKI + - NCKAC225JEFJTB3EO64MIVYF5D7YGZM2ZFXRJNI + - NACXOOKIDID7S75S4FFSC7KBBIBHOBUXB5VSE7A + - NCVQPB2LZ6UCYKGYJAMCC7V4JGXA35BBY44BMHY + - NDSQX6J2QALD2XTU5NQ4FWA2MMEFKBOBEB2BIOQ + - NDLFVQ3C25P5VO2VWP6AMHPIJT6FZYTXNJD4ZAY + - NCXX3KEIEZ3NABMUU45GM7X7BLMPMQHFOZMMF4Q + - NDF4ZCXFKIU5DSJEVBOOI2BDZMDKJTGJVBD6JRY + - NCTTMDTZUUQVN4OKTSF3FTEHJQL2QOGAV25MDCA + - NDLORKVADZSXTIVAA2FYLDMM7I32AIWE7HDWGUQ + - NCQADXOA7ZHLUW2567H33HNNEKCOCN2OJ53PXIQ + - NDX4GP6OL32EOSGXSB5FTGKXDJZP4D535ZZYDFI + - NCE3EP762222D5D2UAF6KIFL7XZ7U4TPFWBYVHA + - NDRLHNV4W7W2M527QOIP35OI3HOMAGTCJDPFDEQ + - NDNGH7WJHSMULMCKYE333V6WU4CQDWXZIJK2VCY + - NB5NIEQF7FM7LLSFASHOQF4X3F6IPDYSIGR3UVA + - NDC3U2UERNMRYFQA45XC74TEEETTZPRUVWKFPAY + - NBNCW3DUUHGBCVJ53LYSYYNMKJ52TLR33C5U53A + - NCAXT7RH6SUPXEU75EIPAPF7DM4VWUBC5AW2L4Q + - NALOQMBU45WOLZ4BCBYZX3N2Y2VSYQFOXGAO34A + - NA2KVKEQDZZMM3NGXYVBHZ46JHM46UWIX3KJ4AY + - NBI2NEBVAD45WWV44H3A53AQ5675Z4G3ZDGDYLI + - NB5ORUTTH2QYHEVTDBB5WPQI4US22FNMODFRK5Y + - NDMR4GMUWGMODWY4FF2VZ3CEC2F56HTD3T6EJYY + - NCBLL63WUAL7FBNPZQISGJR4WZNB7RVWCWG25MI + - NBGGUKW3GEUFHKTO4DYSGDTHIVPKAME3T2XSCGY + - NCASTBFHXMHGQB2UJVUDSW7ZI4N2FDW54OTSHKQ + - ND726EB3B2VG77J3EEQSGNGUX3SS6L2IEBS7PIY + - ND2MRMODKMLCFJWPFJ4MDFI76R7FLZVKIIVKD3A + - NDG6ORUW4PVWVQJRQ5AXADQBUQVL3KBX7AW7MUY + - NBQS3VKGOJ3YNIABN4Y4SFUDBDQHARUIVS6IMGQ + - NCC3VKV3V2HCAP2KTXJUWSXCJ3B6U32EKR6VU5I + - NBUW4OTD42VHELNPCLPQCUHNBHR47PQKLP2EKXA + - NDBKLXZWYBMUUTNRRZ5ESRAJYMQIMHGLGAYLTGY + - NABH3A5VDLYAVA73OV246JTVMAIPD2WEMAQL27I + - NCVG74MGUGR3PLVBWVNNACD6R37JA4RCQMXY3DY + - NDQLBLKXVOK2YS5G7J3AYYKTNW3S3RRK6RQONAQ + - NDTNPG2NUA3MPVDXHLC6D5PSKM4JLLTMQJ5HEDY + - ND4MLYCECHPACYSDDQUFMPXONSIQLPAWNVBWSIA + - NCNRS6KDPHV4MNMXOEGYD6LNRBMWUR7NT4SZI7I + - NBRENIWJUCSUU7RJ5S2DEJVXAOJOTZZDKEFOC3I + - NA7YZPY222RVYQMUM65ZSVFSPAHL55UWO3S35FY + - NCVR72OUOHVGTVLYBKI7PLUDTIAYPRUWPMJJP3Q + - NDE57ICE4UOAPUV3E4CYU3PBA2X4ABUGRGKDFBA + - NBBBCIKJV45U7PNYTNXETH2UFZLJ3C6TJKLJDQQ + - NCRLDB2O2QDPU57PEG3D3AIFSGPGCZU7VVTKBUY + - NC7QENF6OO2FRYV7Q4B5Q74LRSC54Y3YNYN5O3Y + - NAL4XHZU6MANNNFQI4Z2WNMU3KRI2YW2MRRMHLI + - NC5CFRDWEZVCMGQ4Y77OEFSQLMQ3V4EL7JERY2A + - NAIPUZBSDXZIHQKKILAFT3F43IQPS4LOZCH2H4Q + - ND6ZNSQG3I7VWLWSJ3DTYVPEZSJRGSEERW2F7DI + - NC54KVIISZCMMB3ABAMV6NQ6DAUIYYVKQ23S73Q + - NBNRFJSGE53UNHBGZIHYZXPG7SHLQISJN5REGIY + - NCFFJV3VTAK6BJZNV6ZRUZKUJPOWST6MYFAAK5A + - NAAZKYH4V6SARDIJRGFXYEZIHVRWY7R2T62QFYA + - NAGCLXJZHZSBM5ILN4LQBDKU4NYVHB6ZLGRTKJI + - NBGEJ36QK43DR4MYB6XFUFLSVFLULX3HBVNRCVY + - NCGCVCURBA2GCKPEGEA2Q6HKFEHYITKUNWRLMEA + - NA5ZUGHBUUHO63E5OQQND7CYK7UZ3HVQONR2O6Y + - NC2GXL6FQXZY3FXZAYJLBDQHBKSANZLGP4PL7VA + - NB3WMVRI4RM3O3NUSWBZM7U4EZMKADSOFDPPJRQ + - NCFH35TMUJ5QJL6LTBYRBO7ERMM4NIBH7TL6TFY votingUnfinalizedBlocksDuration: 0m timeSynchronizationMinImportance: 10000000000 restExtensions: 'accountLink, aggregate, lockHash, lockSecret, mosaic, metadata, multisig, namespace, receipts, restrictions, transfer, cmc' -knownRestGateways: - - 'http://ngl-dual-001.symbolblockchain.io:3000' - - 'http://ngl-dual-002.symbolblockchain.io:3000' - - 'http://ngl-dual-003.symbolblockchain.io:3000' - - 'http://ngl-dual-004.symbolblockchain.io:3000' - - 'http://ngl-dual-101.symbolblockchain.io:3000' - - 'http://ngl-dual-102.symbolblockchain.io:3000' - - 'http://ngl-dual-103.symbolblockchain.io:3000' - - 'http://ngl-dual-104.symbolblockchain.io:3000' - - 'http://ngl-dual-201.symbolblockchain.io:3000' - - 'http://ngl-dual-202.symbolblockchain.io:3000' - - 'http://ngl-dual-203.symbolblockchain.io:3000' - - 'http://ngl-dual-204.symbolblockchain.io:3000' - - 'http://ngl-dual-301.symbolblockchain.io:3000' - - 'http://ngl-dual-302.symbolblockchain.io:3000' - - 'http://ngl-dual-303.symbolblockchain.io:3000' - - 'http://ngl-dual-304.symbolblockchain.io:3000' - - 'http://ngl-dual-401.symbolblockchain.io:3000' - - 'http://ngl-dual-402.symbolblockchain.io:3000' - - 'http://ngl-dual-403.symbolblockchain.io:3000' - - 'http://ngl-dual-404.symbolblockchain.io:3000' - - 'http://ngl-dual-501.symbolblockchain.io:3000' - - 'http://ngl-dual-502.symbolblockchain.io:3000' - - 'http://ngl-dual-503.symbolblockchain.io:3000' - - 'http://ngl-dual-504.symbolblockchain.io:3000' - - 'http://ngl-dual-601.symbolblockchain.io:3000' - - 'http://ngl-dual-602.symbolblockchain.io:3000' - - 'http://ngl-dual-603.symbolblockchain.io:3000' - - 'http://ngl-dual-604.symbolblockchain.io:3000' - - 'http://ngl-dual-005.symbolblockchain.io:3000' - - 'http://ngl-dual-006.symbolblockchain.io:3000' - - 'http://ngl-dual-105.symbolblockchain.io:3000' - - 'http://ngl-dual-106.symbolblockchain.io:3000' - - 'http://ngl-dual-205.symbolblockchain.io:3000' - - 'http://ngl-dual-206.symbolblockchain.io:3000' - - 'http://ngl-dual-305.symbolblockchain.io:3000' - - 'http://ngl-dual-306.symbolblockchain.io:3000' - - 'http://ngl-dual-405.symbolblockchain.io:3000' - - 'http://ngl-dual-406.symbolblockchain.io:3000' - - 'http://ngl-dual-505.symbolblockchain.io:3000' - - 'http://ngl-dual-506.symbolblockchain.io:3000' - - 'http://ngl-dual-605.symbolblockchain.io:3000' - - 'http://ngl-dual-606.symbolblockchain.io:3000' - - 'http://ngl-api-001.symbolblockchain.io:3000' - - 'http://ngl-api-301.symbolblockchain.io:3000' - - 'http://ngl-api-401.symbolblockchain.io:3000' - - 'http://ngl-api-501.symbolblockchain.io:3000' - - 'http://ngl-api-601.symbolblockchain.io:3000' -knownPeers: - api-node: - - - publicKey: C7BEA9036ECFA79CB081184CFA0E524E7D567A5127C55360D9FF1D2FC1AC4FDD - endpoint: - host: ngl-dual-001.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-001 - roles: 'Api,Peer,Voting' - - - publicKey: CE0AC3FC879B190220A95A67CAC855251EA599F11FA05A77CC02BC32F8228610 - endpoint: - host: ngl-dual-002.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-002 - roles: 'Api,Peer,Voting' - - - publicKey: B36DE7C3B39B225FEF7FC37D40863A2C9AD90EAFDFD79C630BBFF3883CABD929 - endpoint: - host: ngl-dual-003.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-003 - roles: 'Api,Peer,Voting' - - - publicKey: 86C31F2136FB5EB07147E883ACECB891D2D4734E363B26033B1230D8ACF8BBBE - endpoint: - host: ngl-dual-004.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-004 - roles: 'Api,Peer,Voting' - - - publicKey: 6E81088A2E2504C4F91E3DC9C2517FAB99574D71EF5D9F74031FB394CCA7AF3B - endpoint: - host: ngl-dual-101.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-101 - roles: 'Api,Peer,Voting' - - - publicKey: D1BD3577079DD8CFA5073615B7053712C7B4D4B12899C31D1FB34219145298A2 - endpoint: - host: ngl-dual-102.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-102 - roles: 'Api,Peer,Voting' - - - publicKey: DCC6C941EE95967B47433EA3241D53594364A34DB33A9BDC0D668C457002E0F1 - endpoint: - host: ngl-dual-103.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-103 - roles: 'Api,Peer,Voting' - - - publicKey: 3A98603E293DCE7CBF5EE860A00670E3025D3E880D3CC339C926217C36FE6436 - endpoint: - host: ngl-dual-104.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-104 - roles: 'Api,Peer,Voting' - - - publicKey: 7E1101CFD5E64D6CA4A55B70E24412365BD1658E767F23AF9E9777410C116D89 - endpoint: - host: ngl-dual-201.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-201 - roles: 'Api,Peer,Voting' - - - publicKey: 3820C4CFB4BA94F62A982991CB2618EC5E1CFF2C11AD34EFA2254F4305013C1D - endpoint: - host: ngl-dual-202.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-202 - roles: 'Api,Peer,Voting' - - - publicKey: 256AA91283F23168C538F3155DEE946A2B0E7207FBDC369E5C5415F7EE1DE592 - endpoint: - host: ngl-dual-203.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-203 - roles: 'Api,Peer,Voting' - - - publicKey: 6830127294F7C50FE91625076A0D1CCE910A084B032252CDD005C4148ED11A3D - endpoint: - host: ngl-dual-204.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-204 - roles: 'Api,Peer,Voting' - - - publicKey: 92D05B749D6300C4CDCD13A58BF37B7C82B471AB2DFD1A7A6E8C1584620594CA - endpoint: - host: ngl-dual-301.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-301 - roles: 'Api,Peer,Voting' - - - publicKey: 5446DA4D21D5809A3C8492C9083743F4349690A21CB5FF0D6621CC78A6FEE979 - endpoint: - host: ngl-dual-302.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-302 - roles: 'Api,Peer,Voting' - - - publicKey: 4C48C2A708CC1857405C9C48C4D7A69AA5F0FBB7FB8323C967E1BC644A4417E9 - endpoint: - host: ngl-dual-303.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-303 - roles: 'Api,Peer,Voting' - - - publicKey: DEC3292B6ABFAC6687C37FA8963B84715C6E736F6CA27DD50249638D9DF967B1 - endpoint: - host: ngl-dual-304.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-304 - roles: 'Api,Peer,Voting' - - - publicKey: 9D50238B795818044CB330DC5FBA485C7B20EBD38E1A7DBE248555AD70AB4F19 - endpoint: - host: ngl-dual-401.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-401 - roles: 'Api,Peer,Voting' - - - publicKey: 474C5CD5F0B24BCD769DBE99B37C80F4D60B89E28946E126BE23E1EFD5AAA369 - endpoint: - host: ngl-dual-402.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-402 - roles: 'Api,Peer,Voting' - - - publicKey: EF1209DC3C42B6450BEF658D404252DF2E26784CECD35FAEB19D929AE030A198 - endpoint: - host: ngl-dual-403.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-403 - roles: 'Api,Peer,Voting' - - - publicKey: E335B45C9FA2666121D81ACDC8007DF0C958D48A0E1ADD34D22894D85B3EA3BC - endpoint: - host: ngl-dual-404.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-404 - roles: 'Api,Peer,Voting' - - - publicKey: 606BF668BBD9EA1AFCD9E37A2C18C05BE39CC00752AAD99A0E22A79071CCAA7D - endpoint: - host: ngl-dual-501.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-501 - roles: 'Api,Peer,Voting' - - - publicKey: 428F68595322EADDCC0722F024FB0FAD7D35F40C50F1E99AE8FBC8B7EC68E7F2 - endpoint: - host: ngl-dual-502.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-502 - roles: 'Api,Peer,Voting' - - - publicKey: C5B4653E6EE56B7E9C1F87D4F0C712B00378D2828CF7AC73F6BE19F8B1B04B4B - endpoint: - host: ngl-dual-503.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-503 - roles: 'Api,Peer,Voting' - - - publicKey: E74C655E5A4E72E13EE86B8AE7051EEAAF9AD871D5750A04AB360A3FEFD03440 - endpoint: - host: ngl-dual-504.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-504 - roles: 'Api,Peer,Voting' - - - publicKey: 90009F2C2D396A6B788D6DBAB8F075CB20549A50BBA5259D382618FD86F1419A - endpoint: - host: ngl-dual-601.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-601 - roles: 'Api,Peer,Voting' - - - publicKey: E0AB078AC2F363DE0D6823D2A9B5229C092FFB8CB2735D72BE63B8AF94367CB6 - endpoint: - host: ngl-dual-602.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-602 - roles: 'Api,Peer,Voting' - - - publicKey: F8C70778B37A989480969CB44F509509D1372049E821CA6F0A759FC50E03ADBF - endpoint: - host: ngl-dual-603.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-603 - roles: 'Api,Peer,Voting' - - - publicKey: 9F62586518D1707CA57004EF38135509EAE9E9D2933A73041B6171EC0B3F50DF - endpoint: - host: ngl-dual-604.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-604 - roles: 'Api,Peer,Voting' - - - publicKey: BA3E425DA3D32458F8A36C8FCBD6DEDBF5E7A9D8E56A7962EA55AD5125C425B1 - endpoint: - host: ngl-dual-005.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-005 - roles: 'Api,Peer' - - - publicKey: 3FDFCB4F510E81A4A44B044298974DAA34F3B6FC9D24B6D5CE90FFA933C11F51 - endpoint: - host: ngl-dual-006.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-006 - roles: 'Api,Peer' - - - publicKey: 9266C64CDEE62F2AF54806F0CBF2A53D9144CB02AA10B7F7DDEAEAF483E87591 - endpoint: - host: ngl-dual-105.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-105 - roles: 'Api,Peer' - - - publicKey: AC63FD2AAA53B73B4E515F73077522925C8502BFC13B073A520B4BA2F3026BC8 - endpoint: - host: ngl-dual-106.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-106 - roles: 'Api,Peer' - - - publicKey: 7811A94C2BF3CE9E7E1933DF9E9D0C3A7C09DAEF5A3CAC23960B252BDB8D52D3 - endpoint: - host: ngl-dual-205.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-205 - roles: 'Api,Peer' - - - publicKey: 02A55829A1A10542C460A87C4D2C39D03DCCA3F53692B5095C424CCDC21E64A6 - endpoint: - host: ngl-dual-206.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-206 - roles: 'Api,Peer' - - - publicKey: 36CAF133D574DB99B4392D76959488D5B91BD71545039DC80249CFD1FC536795 - endpoint: - host: ngl-dual-305.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-305 - roles: 'Api,Peer' - - - publicKey: 9B302ABCE3CD5783D79AD522B1769DA9AAA10A69E1930B998C2675AA105356FA - endpoint: - host: ngl-dual-306.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-306 - roles: 'Api,Peer' - - - publicKey: 4C85111B10EFB6A25FB77C8A2675C5A92DA5FF36686C4CCE24F887B16342CC95 - endpoint: - host: ngl-dual-405.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-405 - roles: 'Api,Peer' - - - publicKey: 0AF73C5CAC76624DB9B51560820F8DFC88120994143C6DB344A035EBFF707A2F - endpoint: - host: ngl-dual-406.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-406 - roles: 'Api,Peer' - - - publicKey: E060CA383C533273DB4B3CE7AD964E0E3A2B17018B19ABF830590D5FB9338B29 - endpoint: - host: ngl-dual-505.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-505 - roles: 'Api,Peer' - - - publicKey: B1D2AA01E51A81E84CBB2919C0E6AFBBC1383A2760370E60A93C335245A6CB9C - endpoint: - host: ngl-dual-506.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-506 - roles: 'Api,Peer' - - - publicKey: 4F014A430E69EFC422AD8B440FA4D312CBDE9803BB857A0736F38E62CE4CF571 - endpoint: - host: ngl-dual-605.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-605 - roles: 'Api,Peer' - - - publicKey: E32504B5590B9927CA5509FAA0C0CA63DB3479095C2DB73D0150FB862AA0E1FC - endpoint: - host: ngl-dual-606.symbolblockchain.io - port: 7900 - metadata: - name: ngl-dual-606 - roles: 'Api,Peer' - - - publicKey: 47AC3041A5CA98EEA123C64CB7420ADA7F45355CF1993ECA8639891536958011 - endpoint: - host: ngl-api-001.symbolblockchain.io - port: 7900 - metadata: - name: ngl-api-001 - roles: Api - - - publicKey: FE0186777D17DD57CAE5E3D9531EC8E70F1F452ED777910E96A9F44D889D9684 - endpoint: - host: ngl-api-301.symbolblockchain.io - port: 7900 - metadata: - name: ngl-api-301 - roles: Api - - - publicKey: 642197D9D5B283252BFCBC2FEF8B2EE1A7B3383DCD964D159CBF135CA31DC22B - endpoint: - host: ngl-api-401.symbolblockchain.io - port: 7900 - metadata: - name: ngl-api-401 - roles: Api - - - publicKey: E1640F016401E1A8644614B1707D878992DB01B480B55AEDE0EA1A986067ED79 - endpoint: - host: ngl-api-501.symbolblockchain.io - port: 7900 - metadata: - name: ngl-api-501 - roles: Api - - - publicKey: 0282991F51E91F8994F1B3FD4A7D1CDE39F6B828A5D419150D6E07925CFFD27C - endpoint: - host: ngl-api-601.symbolblockchain.io - port: 7900 - metadata: - name: ngl-api-601 - roles: Api - peer-node: - - - publicKey: FA9F3974FE3B15585E6B72672C7D8BEAE27D1EDF6C4752BAFDB8B2FEA601C0CF - endpoint: - host: ngl-beacon-001.symbolblockchain.io - port: 7900 - metadata: - name: ngl-beacon-001 - roles: 'Peer,Voting' - - - publicKey: AFF16052217A847A6A71B326FEA9073CFF70D07FC5BA9026B3E05FB453C950DF - endpoint: - host: ngl-beacon-101.symbolblockchain.io - port: 7900 - metadata: - name: ngl-beacon-101 - roles: 'Peer,Voting' - - - publicKey: D237B4C5964183141868F90ABEF557F751FFB973E7CFF59CCC1B00C504E048F0 - endpoint: - host: ngl-beacon-201.symbolblockchain.io - port: 7900 - metadata: - name: ngl-beacon-201 - roles: 'Peer,Voting' - - - publicKey: 78480D48CC2AA6988E2FD05C884EE0525ACF6DC78766492034EA08CC1ADF788C - endpoint: - host: ngl-beacon-301.symbolblockchain.io - port: 7900 - metadata: - name: ngl-beacon-301 - roles: 'Peer,Voting' - - - publicKey: 9261DB223A28A3DB05315235DF2186260951B66515B17A6B890BBCE3EE9E3FE7 - endpoint: - host: ngl-beacon-401.symbolblockchain.io - port: 7900 - metadata: - name: ngl-beacon-401 - roles: 'Peer,Voting' - - - publicKey: B1B60E982CF0DE72584BED82EDCFAF5F187D24B21DECFA814F69605B5DE4A7C1 - endpoint: - host: ngl-beacon-501.symbolblockchain.io - port: 7900 - metadata: - name: ngl-beacon-501 - roles: 'Peer,Voting' - - - publicKey: 9785B471C23994341159DB2E66853F6B0EAEA1E6E2A838A020965F4B8E29D03A - endpoint: - host: ngl-beacon-601.symbolblockchain.io - port: 7900 - metadata: - name: ngl-beacon-601 - roles: 'Peer,Voting' - - - publicKey: EA77478068E3266CFA478E39AF1FDCD67EA512381889717AA8B66BFC4D01701F - endpoint: - host: ngl-beacon-002.symbolblockchain.io - port: 7900 - metadata: - name: ngl-beacon-002 - roles: 'Peer,Voting' - - - publicKey: D5A40927DDCCD657F52F4C53FE682B07FC2E375040E0CAC50D8FE060024BB775 - endpoint: - host: ngl-beacon-102.symbolblockchain.io - port: 7900 - metadata: - name: ngl-beacon-102 - roles: 'Peer,Voting' - - - publicKey: AF42867433DCAAA560A8A83A923822D55751F360BA385EDF21A932C33F3AEDD0 - endpoint: - host: ngl-beacon-202.symbolblockchain.io - port: 7900 - metadata: - name: ngl-beacon-202 - roles: 'Peer,Voting' - - - publicKey: EF14DAE981FBD1E697CCD551DB9146B379CA4FD153C84016E7DA7A1930AD2395 - endpoint: - host: ngl-beacon-302.symbolblockchain.io - port: 7900 - metadata: - name: ngl-beacon-302 - roles: 'Peer,Voting' - - - publicKey: 3F880DE47D4EB16D1871B1DED95F081151C9BF910EF682EDF202E8CA904B0CB9 - endpoint: - host: ngl-beacon-402.symbolblockchain.io - port: 7900 - metadata: - name: ngl-beacon-402 - roles: 'Peer,Voting' - - - publicKey: 47704C18AC5F0C50A92B3763049EA91D84B17FAC0D86D9A9340AF98E3F610058 - endpoint: - host: ngl-beacon-502.symbolblockchain.io - port: 7900 - metadata: - name: ngl-beacon-502 - roles: 'Peer,Voting' - - - publicKey: DE26F36D5426EC7B91200CB8C0DB70F4D82CD15F7FAFCE48A2174781D72CE6AD - endpoint: - host: ngl-beacon-602.symbolblockchain.io - port: 7900 - metadata: - name: ngl-beacon-602 - roles: 'Peer,Voting' - - - publicKey: 533F75316C28E09B652232D1F48468D19EC88AB5125E947873AA3E150E2DD217 - endpoint: - host: ngl-beacon-003.symbolblockchain.io - port: 7900 - metadata: - name: ngl-beacon-003 - roles: Peer - - - publicKey: DEE480BD3CA0B2E928543F087A28234E565FF6EDBBBC5B961F8302C16ACEB202 - endpoint: - host: ngl-beacon-004.symbolblockchain.io - port: 7900 - metadata: - name: ngl-beacon-004 - roles: Peer - - - publicKey: F925F965D66E2928DDF2C27BB3AB69781C92D0E414C84AE963A505686C66445A - endpoint: - host: ngl-beacon-103.symbolblockchain.io - port: 7900 - metadata: - name: ngl-beacon-103 - roles: Peer - - - publicKey: 4D0AAE4583FDA3BA3CFFA00F9C684A701C360E59DDD14EF3992233D20C59585A - endpoint: - host: ngl-beacon-104.symbolblockchain.io - port: 7900 - metadata: - name: ngl-beacon-104 - roles: Peer - - - publicKey: EEA3B0D28CAEF4A6354F65D7D7F4947145D6FD9FF9F36CA87856CB44A7B1531E - endpoint: - host: ngl-beacon-203.symbolblockchain.io - port: 7900 - metadata: - name: ngl-beacon-203 - roles: Peer - - - publicKey: 2D310E377C0CC84A945E8C9CFDB799F7FDE5F88EE07BBF90D5CED2BFCE27445B - endpoint: - host: ngl-beacon-204.symbolblockchain.io - port: 7900 - metadata: - name: ngl-beacon-204 - roles: Peer - - - publicKey: C1BD10D1320BB22F66692AE002129028BEE7D78E3AA991B12525AD5D3E1BE7DA - endpoint: - host: ngl-beacon-303.symbolblockchain.io - port: 7900 - metadata: - name: ngl-beacon-303 - roles: Peer - - - publicKey: 082F46AEAD35E6C3E443542616F41AAA992389035CAC2DD8807B8321C585E6BB - endpoint: - host: ngl-beacon-304.symbolblockchain.io - port: 7900 - metadata: - name: ngl-beacon-304 - roles: Peer - - - publicKey: 11D6421BC726D684614038B5A0E48D6723CA7C53CDF3A7F9305582227988B3A1 - endpoint: - host: ngl-beacon-403.symbolblockchain.io - port: 7900 - metadata: - name: ngl-beacon-403 - roles: Peer - - - publicKey: 66C2A930320B7A00D0A2653588F65967C73222A8356781DD5AB98F9E759AEF27 - endpoint: - host: ngl-beacon-404.symbolblockchain.io - port: 7900 - metadata: - name: ngl-beacon-404 - roles: Peer - - - publicKey: C08E5DD1539AA29F1408B288550BCBC27BEA447E97E31C5976E58067CD69F655 - endpoint: - host: ngl-beacon-503.symbolblockchain.io - port: 7900 - metadata: - name: ngl-beacon-503 - roles: Peer - - - publicKey: BADFA53EDBFC6B57511A836057DABAE9FF1669027EC37A5A188CCFB81A033C07 - endpoint: - host: ngl-beacon-504.symbolblockchain.io - port: 7900 - metadata: - name: ngl-beacon-504 - roles: Peer - - - publicKey: 5A85331AB54F8B296EC69F7ABF05E133907D6B87F658E43D09E5E9F6E7FDFB6A - endpoint: - host: ngl-beacon-603.symbolblockchain.io - port: 7900 - metadata: - name: ngl-beacon-603 - roles: Peer - - - publicKey: 00FB938646A8A458C55036682AEFAD6733DAEB86DDF19404DEED680FE79B1C39 - endpoint: - host: ngl-beacon-604.symbolblockchain.io - port: 7900 - metadata: - name: ngl-beacon-604 - roles: Peer - - - publicKey: AA91F88DF6D80A9FA097E2FD2A6FCC9CC937177FE0D8933D64B16C5C442B2691 - endpoint: - host: ngl-peer-001.symbolblockchain.io - port: 7900 - metadata: - name: ngl-peer-001 - roles: Peer - - - publicKey: 990B2E1DD730964E62250A7DB1EC2EFCAEE8EE0FA9B2B5368CB4102964C4A822 - endpoint: - host: ngl-peer-301.symbolblockchain.io - port: 7900 - metadata: - name: ngl-peer-301 - roles: Peer - - - publicKey: 1F39352BDBFDBDE4FAE4C58A51140C0843A1B8EE1D62B4297BCC7F6ECE47F489 - endpoint: - host: ngl-peer-401.symbolblockchain.io - port: 7900 - metadata: - name: ngl-peer-401 - roles: Peer - - - publicKey: D12440291B4BD458FE6BAFAA67C502A638777462654C59C7070BE0B5215FF510 - endpoint: - host: ngl-peer-601.symbolblockchain.io - port: 7900 - metadata: - name: ngl-peer-601 - roles: Peer - - - publicKey: 92AD7B4E370A7499F1449C1BA2863C5E484B584B59B148724F5970C6EFD6F806 - endpoint: - host: ngl-peer-501.symbolblockchain.io - port: 7900 - metadata: - name: ngl-peer-501 - roles: Peer - - - publicKey: DEE184EB07DD52A171AA3381F5E7047AE3B830D2A99B7A9027461EA5CB6B878D - endpoint: - host: ngl-peer-002.symbolblockchain.io - port: 7900 - metadata: - name: ngl-peer-002 - roles: 'Peer,Voting' - - - publicKey: 7080531438D8E76B732D76ECB936E74AEAAF3F9491A85691791BB41462EC2DD0 - endpoint: - host: ngl-peer-003.symbolblockchain.io - port: 7900 - metadata: - name: ngl-peer-003 - roles: 'Peer,Voting' - - - publicKey: E4797E4362B7DE5E4EE834DE4EAAA1036B8F035F6A5352FD5BB85664B41633AE - endpoint: - host: ngl-peer-004.symbolblockchain.io - port: 7900 - metadata: - name: ngl-peer-004 - roles: 'Peer,Voting' - - - publicKey: FEC90947D0AF30CB32BC6018928AA6CEC96ED9861DD0608DAFC69131BFDD971A - endpoint: - host: ngl-peer-101.symbolblockchain.io - port: 7900 - metadata: - name: ngl-peer-101 - roles: 'Peer,Voting' - - - publicKey: E6C6D041D77590295432EDC5DC8D1019D4F1F0C002C37909EB4837FF03B139CD - endpoint: - host: ngl-peer-102.symbolblockchain.io - port: 7900 - metadata: - name: ngl-peer-102 - roles: 'Peer,Voting' - - - publicKey: FC8C66547D7C20CD6CBF7F31DC5657247351AF8C12188E56F885FF012431B8C1 - endpoint: - host: ngl-peer-103.symbolblockchain.io - port: 7900 - metadata: - name: ngl-peer-103 - roles: 'Peer,Voting' - - - publicKey: 0E8D31F20B4119D8AE8176970727A37247764CCCE966C72A5809685717FDEA0F - endpoint: - host: ngl-peer-201.symbolblockchain.io - port: 7900 - metadata: - name: ngl-peer-201 - roles: 'Peer,Voting' - - - publicKey: ABCB18959666D248D8B3677D6E673F3EB7A217DEFC5C31B4EDAEB5D111321DDF - endpoint: - host: ngl-peer-202.symbolblockchain.io - port: 7900 - metadata: - name: ngl-peer-202 - roles: 'Peer,Voting' - - - publicKey: 5F32F1AAE8934112A9627EFF43414D9E5DA93CFDB5B5149864FBF76BC2EAA09C - endpoint: - host: ngl-peer-302.symbolblockchain.io - port: 7900 - metadata: - name: ngl-peer-302 - roles: 'Peer,Voting' - - - publicKey: 504699E3C142DD465C5B46BCD7F43ABE232741F4AD82DFB66808E2A338B77EEB - endpoint: - host: ngl-peer-303.symbolblockchain.io - port: 7900 - metadata: - name: ngl-peer-303 - roles: 'Peer,Voting' - - - publicKey: D2C9A5ECDF0FFBDAC5F9D54EDE06848450798086206C3B5E8D9C7737AC5BF4E7 - endpoint: - host: ngl-peer-304.symbolblockchain.io - port: 7900 - metadata: - name: ngl-peer-304 - roles: 'Peer,Voting' - - - publicKey: 729073C51675055556F67BC1C4FD065A12ABDEEBB9455B835382BEA701B6B644 - endpoint: - host: ngl-peer-402.symbolblockchain.io - port: 7900 - metadata: - name: ngl-peer-402 - roles: 'Peer,Voting' - - - publicKey: 8C63F371ECBEC388A14117662F3CB7456D5EA7449779D20DDC259F084203B9DD - endpoint: - host: ngl-peer-403.symbolblockchain.io - port: 7900 - metadata: - name: ngl-peer-403 - roles: 'Peer,Voting' - - - publicKey: 22719E8A14770A076A81A3BD9A02847E0E198AA0D8E8D8E7CC0B359CA80CD73D - endpoint: - host: ngl-peer-404.symbolblockchain.io - port: 7900 - metadata: - name: ngl-peer-404 - roles: 'Peer,Voting' - - - publicKey: 00794D10A9BDEC3E431A8165782D59D54A3EDA682FC50EA31B03BE46E3508D86 - endpoint: - host: ngl-peer-502.symbolblockchain.io - port: 7900 - metadata: - name: ngl-peer-502 - roles: 'Peer,Voting' - - - publicKey: E6051F40218A770C56B170F27E2C031B61C19EB7EAF6D17CEE7854D3A3F264BF - endpoint: - host: ngl-peer-503.symbolblockchain.io - port: 7900 - metadata: - name: ngl-peer-503 - roles: 'Peer,Voting' - - - publicKey: 4EF71A6C97ADD6A2C07568C38130A7CD7768F3E0F4E5E651A72119DDFF1F74A2 - endpoint: - host: ngl-peer-504.symbolblockchain.io - port: 7900 - metadata: - name: ngl-peer-504 - roles: 'Peer,Voting' - - - publicKey: 98ECC6FFF03B4AB7C687A27C0DB120E3B0ECDFEAFECC54E10D8AA59409890170 - endpoint: - host: ngl-peer-602.symbolblockchain.io - port: 7900 - metadata: - name: ngl-peer-602 - roles: 'Peer,Voting' - - - publicKey: 8EA3F1718C0C8DF68FB3B53702C8B3C44FEB88FA7018CAF0C52D163974CAECD2 - endpoint: - host: ngl-peer-603.symbolblockchain.io - port: 7900 - metadata: - name: ngl-peer-603 - roles: 'Peer,Voting' - - - publicKey: 9C59D2235888E6FE638A9F4E3F6977C230836A9902929F1884220CF2F1A40B85 - endpoint: - host: ngl-peer-604.symbolblockchain.io - port: 7900 - metadata: - name: ngl-peer-604 - roles: 'Peer,Voting' +explorerUrl: 'https://symbol.fyi' +statisticsServiceUrl: 'https://symbol.services' +knownRestGateways: [] +knownPeers: [] +treasuryReissuanceTransactionSignatures: + - 0BBEADD37539444D75C09A245102D2B883267925398504623835DCD625290DEE4FA2371341050C49C001DEDD1C9FE241EA4A7DB335B2069FD4DAFF77AF734C03 + - 89447704270E8B2F8EED19526587DB58870D90A02ACEF8AE2A54311DEB95C227201CD39662A0229D5746FFB84074EA6C7DD9620A2CE5AA69065C508DC0335201 + - D19BCD440545CF785D88F903141DE794F2D57012509BC224B25BFCA220267D1ADD42182702F50C1A4E95D0F21604E4F9EEEEF329932FCD0C76B43992B0D90B0D + - C478DB6053C639AFC96F5D965159DC95449E5EE69A62E5FA28DF42D85C031B3A131B3AC403D9BFF27E1E64FD8012D05C720F0D2A8654D9F4BC48C8DD2DCEBC03 + - C0BAE301EC15B514C5685A661BC3E23A6596CE9DC412A83F67A8C8611A4415B1B0447E8C09D2816CAE0D750C4AB1ED8FE9C85C05D448C2114147A2C935030708 + - A317F4EB085C8D3D80435669EF54C6C9C9AD9B57165B14CF051F43879D0112E3A79591DD6D469BFAA850891FA2CB601BA58CD1BAEBFF5D84C49179AC7FE14706 + - FDB98C472D0B98FDD766DA177366DEB2DB0E79721BD73DA96A84622A98932DA75BAA327BA9E23D448C6F25344654A6F17F7734C14D1530B327F911A97B4DE30A +treasuryReissuanceFallbackTransactionSignatures: + - E29FA2456E505044B2087D4D4FFC390D3E2BDAEF2233E10E812C8677D1DE95DDB5D7A696D8C697DB74D07DC9AB863659EE9C6E984BE83E394AE632D21129EC0F inflation: starting-at-height-2: 0 starting-at-height-5760: 191997042 diff --git a/presets/shared.yml b/presets/shared.yml index ffaa3823e..50eb02693 100644 --- a/presets/shared.yml +++ b/presets/shared.yml @@ -25,7 +25,7 @@ maxMessageSize: 1024 reservedRootNamespaceNames: 'symbol, symbl, xym, xem, nem, user, account, org, com, biz, net, edu, mil, gov, info' defaultDynamicFeeMultiplier: 1000 minFeeMultiplier: 100 -maxTimeBehindPullTransactionsStart: 5m +maxTimeBehindPullTransactionsStart: 24h epochAdjustment: 1573430400s nodeEqualityStrategy: host maxVotingKeyLifetime: 26280 @@ -38,6 +38,8 @@ maxTransactionsPerAggregate: 100 maxCosignaturesPerAggregate: 25 harvestBeneficiaryPercentage: 10 harvestNetworkPercentage: 5 +treasuryReissuanceBlockTransactionsHash: '0000000000000000000000000000000000000000000000000000000000000000' +treasuryReissuanceFallbackBlockTransactionsHash: '0000000000000000000000000000000000000000000000000000000000000000' rootNamespaceRentalFeePerBlock: 1 childNamespaceRentalFee: 100 enableStrictCosignatureCheck: false @@ -64,13 +66,13 @@ maxNameSize: 64 maxChildNamespaces: 256 maxNamespaceDepth: 3 batchVerificationRandomSource: -symbolServerImage: symbolplatform/symbol-server:gcc-10-1.0.2.0 -symbolRestImage: symbolplatform/symbol-rest:2.3.6 -symbolExplorerImage: symbolplatform/symbol-explorer:0.6.3-alpha +symbolServerImage: symbolplatform/symbol-server:gcc-10-1.0.3.0 +symbolRestImage: symbolplatform/symbol-rest:2.3.8 +symbolExplorerImage: symbolplatform/symbol-explorer:1.1.0-alpha symbolWalletImage: symbolplatform/symbol-desktop-wallet:1.0.1 -symbolFaucetImage: symbolplatform/symbol-faucet:0.5.0-alpha -symbolAgentImage: symbolplatform/symbol-node-rewards-agent:2.0.0 +symbolFaucetImage: symbolplatform/symbol-faucet:1.0.1-alpha mongoImage: mongo:4.4.3-bionic +httpsPortalImage: steveltn/https-portal:1.19 mongoComposeRunParam: --wiredTigerCacheSizeGB 2 logLevel: 'Info' # brokerLogLevel: 'Info' @@ -84,9 +86,9 @@ dataDirectory: ./data votingKeysDirectory: ./votingkeys enableDelegatedHarvestersAutoDetection: true catapultAppFolder: /usr/catapult -rewardProgramAgentPort: 7881 enableRevoteOnBoot: true totalVotingBalanceCalculationFix: 0 +treasuryReissuance: 0 # config database databaseName: catapult @@ -108,6 +110,7 @@ prevoteBlocksMultiple: 4 nonVotingUnfinalizedBlocksDuration: 8m votingUnfinalizedBlocksDuration: 0m voting: false +treasuryReissuanceEpoch: 0 # config messages: subscriberPort: 7902 @@ -164,9 +167,9 @@ delegatePrioritizationPolicy: Importance dockerComposeVersion: '2.4' dockerComposeServiceRestart: 'on-failure:2' dockerComposeDebugMode: false -minPartnerNodeVersion: 1.0.1.0 +minPartnerNodeVersion: 1.0.2.0 maxPartnerNodeVersion: 1.0.255.255 -serverVersion: 1.0.2.0 +serverVersion: outgoing_connections_maxConnections: 10 outgoing_connections_maxConnectionAge: 200 outgoing_connections_maxConnectionBanAge: 20 @@ -215,3 +218,11 @@ connectionPoolSize: 10 maxSubscriptions: 300 restExtensions: 'accountLink, aggregate, lockHash, lockSecret, mosaic, metadata, multisig, namespace, receipts, restrictions, transfer, cmc' restDeploymentTool: symbol-bootstrap +restProtocol: HTTP +restSSLPath: '/symbol-workdir' +restSSLKeyFileName: 'restSSL.key' +restSSLCertificateFileName: 'restSSL.crt' +statisticsServicePeerFilter: '' +statisticsServicePeerLimit: 50 +statisticsServiceRestFilter: suggested +statisticsServiceRestLimit: 10 diff --git a/presets/testnet/assembly-api.yml b/presets/testnet/assembly-api.yml index 0c52118cd..8c4bb5755 100644 --- a/presets/testnet/assembly-api.yml +++ b/presets/testnet/assembly-api.yml @@ -20,3 +20,11 @@ gateways: databaseHost: 'db' openPort: true ipv4_address: 172.20.0.25 +httpsProxies: + - name: 'https-proxy' + excludeDockerService: true #disabled as default + openPort: 3001 + #domains: 'symbol-node.example.com -> http://rest-gateway:3000' + stage: 'production' + webSocket: 'true' + serverNamesHashBucketSize: 128 diff --git a/presets/testnet/assembly-dual.yml b/presets/testnet/assembly-dual.yml index 6ec842b8b..68663fba6 100644 --- a/presets/testnet/assembly-dual.yml +++ b/presets/testnet/assembly-dual.yml @@ -20,3 +20,11 @@ gateways: databaseHost: 'db' openPort: true ipv4_address: 172.20.0.25 +httpsProxies: + - name: 'https-proxy' + excludeDockerService: true #disabled as default + openPort: 3001 + #domains: 'symbol-node.example.com -> http://rest-gateway:3000' + stage: 'production' + webSocket: 'true' + serverNamesHashBucketSize: 128 diff --git a/presets/testnet/network.yml b/presets/testnet/network.yml index b3d8356b2..a15a2bf71 100644 --- a/presets/testnet/network.yml +++ b/presets/testnet/network.yml @@ -13,22 +13,21 @@ maxMosaicAtomicUnits: 8999999999000000 minHarvesterBalance: 10000000000 minVoterBalance: 3000000000000 nemesisGenerationHashSeed: 3B5E1FA6445653C971A50687E75E6D09FB30481055E3990C84B25E9222DC1155 +harvestNetworkFeeSinkAddressV1: TCZ3UZPWWC5NR6TGGYEJ2MT4Z5ZLR3XTIVI4RHA harvestNetworkFeeSinkAddress: TCZ3UZPWWC5NR6TGGYEJ2MT4Z5ZLR3XTIVI4RHA +namespaceRentalFeeSinkAddressV1: TATBDUEWS2X2BKKBPVB7SY4Z626YCAERGA3IF5A namespaceRentalFeeSinkAddress: TATBDUEWS2X2BKKBPVB7SY4Z626YCAERGA3IF5A +mosaicRentalFeeSinkAddressV1: TAFNXW3VXVFTGTVGATKQAR75ALQX7DQXQJRWWTA mosaicRentalFeeSinkAddress: TAFNXW3VXVFTGTVGATKQAR75ALQX7DQXQJRWWTA nemesisSignerPublicKey: 2267B24107405779DDF0D8FBEABD8142B97105F356F3737B1FC02220E8F90FF2 networkType: 152 -rewardProgramCaFile: >- - LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJZVENDQVJNQ0ZHTGt2L1dUM2J0NmltLytTckdrSUJuRnhBMW5NQVVHQXl0bGNEQlRNUm93R0FZRFZRUUsKREJGT1JVMGdSM0p2ZFhBZ1RHbHRhWFJsWkRFYk1Ca0dBMVVFQXd3U2MzbHRZbTlzY0d4aGRHWnZjbTB1WTI5dApNUmd3RmdZRFZRUUxEQTlTWlhkaGNtUnpJRkJ5YjJkeVlXMHdIaGNOTWpFd05ESTJNVFEwTXpBMVdoY05OREV3Ck5ESXhNVFEwTXpBMVdqQlRNUm93R0FZRFZRUUtEQkZPUlUwZ1IzSnZkWEFnVEdsdGFYUmxaREViTUJrR0ExVUUKQXd3U2MzbHRZbTlzY0d4aGRHWnZjbTB1WTI5dE1SZ3dGZ1lEVlFRTERBOVNaWGRoY21SeklGQnliMmR5WVcwdwpLakFGQmdNclpYQURJUUFnTU5jWGpILzM2SmswRVFQODNGeEsrcUljcUZ6U29HdHNxN3diR1B2RmZ6QUZCZ01yClpYQURRUUR0RU5uTXFUS2M3eUp1MFN5SzZoalBLUDZWVjVvMHFjWTFXR3VVK3REOWxwbFBkWkRRSnhEZG5aWEMKV1JJQlROR0hYWjZNa1p5LzFIdTZpOEp6V0FVSQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== -rewardProgramEnrollmentAddress: TDL73SDUMPDK7EOF7H3O4F5WB5WHG2SX7XUSFZQ -rewardProgramControllerApiUrl: 'http://node-monitoring.testnet.symboldev.network:7890' totalChainImportance: 7842928625000000 initialCurrencyAtomicUnits: 7842928625000000 importanceGrouping: 180 votingSetGrouping: 720 votingKeyDesiredLifetime: 720 votingKeyDesiredFutureLifetime: 120 -lastKnownNetworkEpoch: 235 +lastKnownNetworkEpoch: 723 minVotingKeyLifetime: 28 maxVotingKeyLifetime: 720 stepDuration: 4m @@ -51,226 +50,19 @@ minProofSize: 0 syncTimeout: 5m maxChildNamespaces: 100 nonVotingUnfinalizedBlocksDuration: 10m +treasuryReissuanceEpoch: 0 +treasuryReissuanceEpochIneligibleVoterAddresses: [] votingUnfinalizedBlocksDuration: 0m timeSynchronizationMinImportance: 10000000000 -faucetUrl: 'http://faucet.testnet.symboldev.network' -explorerUrl: 'http://explorer.testnet.symboldev.network' restExtensions: 'accountLink, aggregate, lockHash, lockSecret, mosaic, metadata, multisig, namespace, receipts, restrictions, transfer, cmc' -knownRestGateways: - - 'http://ngl-dual-501.testnet.symboldev.network:3000' - - 'http://ngl-dual-601.testnet.symboldev.network:3000' - - 'http://ngl-dual-001.testnet.symboldev.network:3000' - - 'http://ngl-dual-101.testnet.symboldev.network:3000' - - 'http://ngl-dual-201.testnet.symboldev.network:3000' - - 'http://ngl-dual-301.testnet.symboldev.network:3000' - - 'http://ngl-dual-401.testnet.symboldev.network:3000' - - 'http://ngl-dual-502.testnet.symboldev.network:3000' - - 'http://ngl-dual-602.testnet.symboldev.network:3000' - - 'http://ngl-api-001.testnet.symboldev.network:3000' - - 'http://ngl-api-101.testnet.symboldev.network:3000' -knownPeers: - api-node: - - - publicKey: 1B8491EE121B865E733A0AFC2B0B5A0C762B57A7CDDDBDE6608943EAE135BE44 - endpoint: - host: ngl-dual-501.testnet.symboldev.network - port: 7900 - metadata: - name: ngl-dual-501 - roles: 'Api,Peer,Voting' - - - publicKey: 41F38D9C02F7D3D460A4CB0311E3D6E67CB063351434A6A00BB6F7AE64CD4FD7 - endpoint: - host: ngl-dual-601.testnet.symboldev.network - port: 7900 - metadata: - name: ngl-dual-601 - roles: 'Api,Peer,Voting' - - - publicKey: E3FC28889BDE31406465167F1D9D6A16DCA1FF67A3BABFA5E5A8596478848F78 - endpoint: - host: ngl-dual-001.testnet.symboldev.network - port: 7900 - metadata: - name: ngl-dual-001 - roles: 'Api,Peer' - - - publicKey: C4348215B4C417D3E4B52ACAA3D370D29DE3A5F482CAED3C9F1BE257DD2B4079 - endpoint: - host: ngl-dual-101.testnet.symboldev.network - port: 7900 - metadata: - name: ngl-dual-101 - roles: 'Api,Peer' - - - publicKey: C084A7B93E7B2B04A95328A39FD0851086BEE4389987654315F02F4DE32634F8 - endpoint: - host: ngl-dual-201.testnet.symboldev.network - port: 7900 - metadata: - name: ngl-dual-201 - roles: 'Api,Peer' - - - publicKey: 4AD462EFDB312769AB0F146E287C4216E0858992F8181B32A232EDF94E4D4A7C - endpoint: - host: ngl-dual-301.testnet.symboldev.network - port: 7900 - metadata: - name: ngl-dual-301 - roles: 'Api,Peer' - - - publicKey: EBB821CFAE5B8FBE76FAD81D4A6A2135EB6E2603E083AE9A726132B6AE8A1089 - endpoint: - host: ngl-dual-401.testnet.symboldev.network - port: 7900 - metadata: - name: ngl-dual-401 - roles: 'Api,Peer' - - - publicKey: 093894ECBD487A2601E9DFEF100C40238F39EA29E9DF2DB244BFD4F3E7B64142 - endpoint: - host: ngl-dual-502.testnet.symboldev.network - port: 7900 - metadata: - name: ngl-dual-502 - roles: 'Api,Peer' - - - publicKey: 53100549CE67E4B94867B461DC489747862A0CB34ADA701C6A974134F1DCC197 - endpoint: - host: ngl-dual-602.testnet.symboldev.network - port: 7900 - metadata: - name: ngl-dual-602 - roles: 'Api,Peer' - - - publicKey: 3BD4CECB2C82DE809CE6AD285ECF8687B4594EAE7D9220C2064E56812977EAE6 - endpoint: - host: ngl-api-001.testnet.symboldev.network - port: 7900 - metadata: - name: ngl-api-001 - roles: Api - - - publicKey: 904303E0DAF19BA69CD6A1AB4CA3E2E80525BD9D814342B67C850A0CBB3ECC0F - endpoint: - host: ngl-api-101.testnet.symboldev.network - port: 7900 - metadata: - name: ngl-api-101 - roles: Api - peer-node: - - - publicKey: 3CA5B729F46A56928C4971674B641C9535B93B560FC789F1134314786FC5766F - endpoint: - host: ngl-beacon-501.testnet.symboldev.network - port: 7900 - metadata: - name: ngl-beacon-501 - roles: 'Peer,Voting' - - - publicKey: CFC25E8E5C7348C075B8189BD2FEF16E9AE26A1E4814A1002B562B95F5538435 - endpoint: - host: ngl-beacon-601.testnet.symboldev.network - port: 7900 - metadata: - name: ngl-beacon-601 - roles: 'Peer,Voting' - - - publicKey: 5E5BF270398818DC58107C599238D00247DA33446BC1CE334CAD5ED44057184D - endpoint: - host: ngl-beacon-001.testnet.symboldev.network - port: 7900 - metadata: - name: ngl-beacon-001 - roles: 'Peer,Voting' - - - publicKey: 3BE809A65B98E8AF7E5835A9C12F90B29BEDFFFF97E11C1160D8136F15B66AD1 - endpoint: - host: ngl-beacon-101.testnet.symboldev.network - port: 7900 - metadata: - name: ngl-beacon-101 - roles: 'Peer,Voting' - - - publicKey: A33EF3ED8CFBF16C2C3468FCAEE78B36F6F0E737820CE9F48D349309515316F8 - endpoint: - host: ngl-beacon-401.testnet.symboldev.network - port: 7900 - metadata: - name: ngl-beacon-401 - roles: Peer - - - publicKey: 723C4D540D0796C998D62258DF16AEE8D55A403F716211DEAB479FCE18640B2C - endpoint: - host: ngl-peer-201.testnet.symboldev.network - port: 7900 - metadata: - name: ngl-peer-201 - roles: Peer - - - publicKey: DC7A90D0676DB3A2D963768276F606AF76541A59588B23C6C6B48D98E0AC3837 - endpoint: - host: ngl-peer-301.testnet.symboldev.network - port: 7900 - metadata: - name: ngl-peer-301 - roles: Peer - - - publicKey: 22F6D59D56E17619B8F8B7323A500693892092268122AF5E2A02F6EE29FA2F11 - endpoint: - host: ngl-peer-001.testnet.symboldev.network - port: 7900 - metadata: - name: ngl-peer-001 - roles: 'Peer,Voting' - - - publicKey: 78EFF533B504F49054F8CACEA9E5751E88EDCBBB057DE7410161B9398FEB9FCE - endpoint: - host: ngl-peer-101.testnet.symboldev.network - port: 7900 - metadata: - name: ngl-peer-101 - roles: 'Peer,Voting' - - - publicKey: BA8CA590E44FE53FAAF8E98ED6E98A53C5E911CE2E6D0ACCAB22A979DA151824 - endpoint: - host: ngl-peer-202.testnet.symboldev.network - port: 7900 - metadata: - name: ngl-peer-202 - roles: 'Peer,Voting' - - - publicKey: 356854C754039984F94C37C26CF58CD282AC3BCAC99F9549367702823A50D37C - endpoint: - host: ngl-peer-302.testnet.symboldev.network - port: 7900 - metadata: - name: ngl-peer-302 - roles: 'Peer,Voting' - - - publicKey: FE5D4350784BF72E9D36B6E7BE7BB8F3DF26D501614BB707A4C0DFB8DB541BEB - endpoint: - host: ngl-peer-401.testnet.symboldev.network - port: 7900 - metadata: - name: ngl-peer-401 - roles: 'Peer,Voting' - - - publicKey: FB1B701426A29A22A0711E351117AAFB9449B69CD0D6F310663DED02CD29F5CE - endpoint: - host: ngl-peer-501.testnet.symboldev.network - port: 7900 - metadata: - name: ngl-peer-501 - roles: 'Peer,Voting' - - - publicKey: 2489946E49B03D9BE040E3FD42FEBC705D001A746BD25399E2796D615B35B732 - endpoint: - host: ngl-peer-601.testnet.symboldev.network - port: 7900 - metadata: - name: ngl-peer-601 - roles: 'Peer,Voting' +faucetUrl: 'https://testnet.symbol.tools' +explorerUrl: 'https://testnet.symbol.fyi' +statisticsServiceUrl: 'https://testnet.symbol.services' +knownRestGateways: [] +knownPeers: [] +treasuryReissuanceTransactionSignatures: [] +treasuryReissuanceFallbackTransactionSignatures: [] + inflation: starting-at-height-2: 0 starting-at-height-5760: 191997042 diff --git a/src/commands/clean.ts b/src/commands/clean.ts index 7fec7dbde..eb6aa901b 100644 --- a/src/commands/clean.ts +++ b/src/commands/clean.ts @@ -15,8 +15,7 @@ */ import { Command } from '@oclif/command'; -import { BootstrapUtils } from '../service'; -import { CommandUtils } from '../service/CommandUtils'; +import { BootstrapUtils, CommandUtils } from '../service'; export default class Clean extends Command { static description = 'It removes the target folder deleting the generated configuration and data'; diff --git a/src/commands/compose.ts b/src/commands/compose.ts index 9b21ca1a5..8f9b56e68 100644 --- a/src/commands/compose.ts +++ b/src/commands/compose.ts @@ -15,8 +15,7 @@ */ import { Command, flags } from '@oclif/command'; -import { BootstrapService, BootstrapUtils, ComposeService } from '../service'; -import { CommandUtils } from '../service/CommandUtils'; +import { BootstrapService, BootstrapUtils, CommandUtils, ComposeService } from '../service'; export default class Compose extends Command { static description = 'It generates the `docker-compose.yml` file from the configured network.'; diff --git a/src/commands/enrollRewardProgram.ts b/src/commands/enrollRewardProgram.ts deleted file mode 100644 index 5ab82c5c7..000000000 --- a/src/commands/enrollRewardProgram.ts +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2020 NEM - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Command } from '@oclif/command'; -import { BootstrapService, BootstrapUtils } from '../service'; -import { AnnounceService } from '../service/AnnounceService'; -import { CommandUtils } from '../service/CommandUtils'; - -export default class EnrollRewardProgram extends Command { - static description = `It enrols the nodes in the rewards program by announcing the enroll transaction to the registration address. You can also use this command to update the program registration when you change the agent keys (changing the agent-ca-csr) or server host. - -Currently, the only program that can be enrolled post-launch is 'SuperNode'.`; - - static examples = [ - `$ symbol-bootstrap enrollRewardProgram`, - `$ symbol-bootstrap enrollRewardProgram --noPassword`, - `$ symbol-bootstrap enrollRewardProgram --useKnownRestGateways`, - `$ symbol-bootstrap enrollRewardProgram --password 1234 --url http://external-rest:3000`, - `$ echo "$MY_ENV_VAR_PASSWORD" | symbol-bootstrap enrollRewardProgram --url http://external-rest:3000`, - ]; - - static flags = { - help: CommandUtils.helpFlag, - target: CommandUtils.targetFlag, - ...AnnounceService.flags, - }; - - public async run(): Promise { - const { flags } = this.parse(EnrollRewardProgram); - BootstrapUtils.showBanner(); - flags.password = await CommandUtils.resolvePassword( - flags.password, - flags.noPassword, - CommandUtils.passwordPromptDefaultMessage, - true, - ); - return new BootstrapService(this.config.root).enrollRewardProgram(flags); - } -} diff --git a/src/commands/modifyMultisig.ts b/src/commands/modifyMultisig.ts new file mode 100644 index 000000000..5ca4de845 --- /dev/null +++ b/src/commands/modifyMultisig.ts @@ -0,0 +1,67 @@ +/* + * Copyright 2020 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Command, flags } from '@oclif/command'; +import { BootstrapService, BootstrapUtils } from '../service'; +import { AnnounceService } from '../service/AnnounceService'; +import { CommandUtils } from '../service/CommandUtils'; + +export default class ModifyMultisig extends Command { + static description = `Create or modify a multisig account`; + + static examples = [ + `$ symbol-bootstrap modifyMultisig`, + `$ echo "$MY_ENV_VAR_PASSWORD" | symbol-bootstrap modifyMultisig --useKnownRestGateways`, + ]; + + static flags = { + help: CommandUtils.helpFlag, + target: CommandUtils.targetFlag, + minRemovalDelta: flags.integer({ + description: + 'Delta of signatures needed to remove a cosignatory. ' + + '0 means no change, a positive(+) number means increment and a negative(-) number means decrement to the actual value.', + char: 'r', + }), + minApprovalDelta: flags.integer({ + description: + 'Delta of signatures needed to approve a transaction. ' + + '0 means no change, a positive(+) number means increment and a negative(-) number means decrement to the actual value.', + char: 'a', + }), + addressAdditions: flags.string({ + description: 'Cosignatory accounts addresses to be added (separated by a comma).', + char: 'A', + }), + addressDeletions: flags.string({ + description: 'Cosignatory accounts addresses to be removed (separated by a comma).', + char: 'D', + }), + ...AnnounceService.flags, + }; + + public async run(): Promise { + const { flags } = this.parse(ModifyMultisig); + BootstrapUtils.showBanner(); + flags.password = await CommandUtils.resolvePassword( + flags.password, + flags.noPassword, + CommandUtils.passwordPromptDefaultMessage, + true, + ); + return new BootstrapService(this.config.root).modifyMultisig(flags); + } +} diff --git a/src/commands/pack.ts b/src/commands/pack.ts new file mode 100644 index 000000000..7a4b30901 --- /dev/null +++ b/src/commands/pack.ts @@ -0,0 +1,118 @@ +/* + * Copyright 2021 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Command, flags } from '@oclif/command'; +import { existsSync } from 'fs'; +import { prompt } from 'inquirer'; +import { dirname, join } from 'path'; +import { BootstrapService, BootstrapUtils, CommandUtils, CryptoUtils, ZipItem, ZipUtils } from '../service'; +import Clean from './clean'; +import Compose from './compose'; +import Config from './config'; + +export default class Pack extends Command { + static description = 'It configures and packages your node into a zip file that can be uploaded to the final node machine.'; + + static examples = [ + `$ symbol-bootstrap pack`, + `$ symbol-bootstrap pack -p bootstrap -c custom-preset.yml`, + `$ symbol-bootstrap pack -p testnet -a dual -c custom-preset.yml`, + `$ symbol-bootstrap pack -p mainnet -a dual --password 1234 -c custom-preset.yml`, + `$ echo "$MY_ENV_VAR_PASSWORD" | symbol-bootstrap pack -p mainnet -a dual -c custom-preset.yml`, + ]; + + static flags = { + ...Compose.flags, + ...Clean.flags, + ...Config.resolveFlags(true), + ready: flags.boolean({ + description: 'If --ready is provided, the command will not ask offline confirmation.', + }), + }; + + public async run(): Promise { + const { flags } = this.parse(Pack); + BootstrapUtils.showBanner(); + const preset = flags.preset; + const assembly = flags.assembly; + const targetZip = join(dirname(flags.target), `${preset}-${assembly || 'default'}-node.zip`); + + if (existsSync(targetZip)) { + throw new Error( + `The target zip file ${targetZip} already exist. Do you want to delete it before repackaging your target folder?`, + ); + } + console.log(); + console.log(); + if ( + !flags.ready && + !( + await prompt([ + { + name: 'offlineNow', + message: `Symbol Bootstrap is about to start working with sensitive information (certificates and voting file generation) so it is highly recommended that you disconnect from the network before continuing. Say YES if you are offline or if you don't care.`, + type: 'confirm', + default: true, + }, + ]) + ).offlineNow + ) { + console.log('Come back when you are offline...'); + return; + } + + flags.password = await CommandUtils.resolvePassword( + flags.password, + flags.noPassword, + CommandUtils.passwordPromptDefaultMessage, + true, + ); + const service = await new BootstrapService(this.config.root); + const configOnlyCustomPresetFileName = 'config-only-custom-preset.yml'; + const configResult = await service.config(flags); + await service.compose(flags, configResult.presetData); + + const noPrivateKeyTempFile = 'custom-preset-temp.temp'; + + if (flags.customPreset) { + await BootstrapUtils.writeYaml( + noPrivateKeyTempFile, + CryptoUtils.removePrivateKeys(BootstrapUtils.loadYaml(flags.customPreset, flags.password)), + flags.password, + ); + } else { + await BootstrapUtils.writeYaml(noPrivateKeyTempFile, {}, flags.password); + } + const zipItems: ZipItem[] = [ + { + from: flags.target, + to: 'target', + directory: true, + }, + { + from: noPrivateKeyTempFile, + to: configOnlyCustomPresetFileName, + directory: false, + }, + ]; + + await ZipUtils.zip(targetZip, zipItems); + await BootstrapUtils.deleteFile(noPrivateKeyTempFile); + console.log(); + console.log(`Zip file ${targetZip} has been created. You can unzip it in your node's machine and run:`); + console.log(`$ symbol-bootstrap start -p ${preset}${assembly ? ` -a ${assembly}` : ''} -c ${configOnlyCustomPresetFileName}`); + } +} diff --git a/src/commands/updateVotingKeys.ts b/src/commands/updateVotingKeys.ts index f34fb2793..18da5afb2 100644 --- a/src/commands/updateVotingKeys.ts +++ b/src/commands/updateVotingKeys.ts @@ -71,7 +71,8 @@ When a new voting file is created, Bootstrap will advise running the \`link\` co const addresses = configLoader.loadExistingAddresses(target, password); const privateKeySecurityMode = CryptoUtils.getPrivateKeySecurityMode(presetData.privateKeySecurityMode); - const finalizationEpoch = flags.finalizationEpoch || (await new RemoteNodeService().resolveCurrentFinalizationEpoch(presetData)); + const finalizationEpoch = + flags.finalizationEpoch || (await new RemoteNodeService(presetData, false).resolveCurrentFinalizationEpoch()); const votingKeyUpgrade = ( await Promise.all( diff --git a/src/commands/wizard.ts b/src/commands/wizard.ts new file mode 100644 index 000000000..baee6f29b --- /dev/null +++ b/src/commands/wizard.ts @@ -0,0 +1,596 @@ +/* + * Copyright 2021 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Command, flags } from '@oclif/command'; +import { IOptionFlag } from '@oclif/command/lib/flags'; +import { existsSync, readFileSync } from 'fs'; +import { prompt } from 'inquirer'; +import { Account, NetworkType, PublicAccount } from 'symbol-sdk'; +import { CustomPreset, PrivateKeySecurityMode } from '../model'; +import { BootstrapService, BootstrapUtils, CommandUtils, ConfigLoader, ConfigService, KeyName, Preset } from '../service'; + +export const assemblies: Record = { + [Preset.bootstrap]: [ + { value: '', description: 'Default: A network with 2 peers, a api, a broker, a mongo db, and a Rest Gateway' }, + { value: 'full', description: 'Full: A complete network with a private Explorer, Faucet and Wallet' }, + { value: 'light', description: 'Light: A light network with a dual, a mongo dn and a rest gateway' }, + ], + [Preset.mainnet]: [ + { value: 'dual', description: 'Dual Node' }, + { value: 'peer', description: 'Peer Node' }, + { value: 'api', description: 'Api Node' }, + ], + [Preset.testnet]: [ + { value: 'dual', description: 'Dual Node' }, + { value: 'peer', description: 'Peer Node' }, + { value: 'api', description: 'Api Node' }, + ], +}; +export enum HttpsOption { + Native = 'Native', + Automatic = 'Automatic', + None = 'None', +} +export enum Network { + mainnet = 'mainnet', + testnet = 'testnet', + localNetwork = 'localNetwork', +} + +export interface ProvidedAccounts { + seeded: boolean; + main: Account; + remote: Account; + vrf: Account; + transport: Account; +} + +export const networkToPreset: Record = { + [Network.localNetwork]: Preset.bootstrap, + [Network.mainnet]: Preset.mainnet, + [Network.testnet]: Preset.testnet, +}; +export default class Wizard extends Command { + static description = 'An utility command that will help you configuring node!'; + + static examples = [`$ symbol-bootstrap wizard`]; + + static flags = { + help: CommandUtils.helpFlag, + target: CommandUtils.targetFlag, + password: CommandUtils.passwordFlag, + noPassword: CommandUtils.noPasswordFlag, + network: Wizard.getNetworkIdFlag(), + customPreset: Wizard.getCustomPresetFile(), + ready: flags.boolean({ + description: 'If --ready is provided, the command will not ask offline confirmation.', + }), + }; + + public async run(): Promise { + const flags = this.parse(Wizard).flags; + return Wizard.execute(this.config.root, flags); + } + + public static async execute( + root: string, + flags: { + noPassword: boolean; + skipPull?: boolean; + target: string; + password: string | undefined; + network: Network | undefined; + customPreset: string; + ready?: boolean; + }, + ): Promise { + BootstrapUtils.showBanner(); + console.log('Welcome to the Symbol Bootstrap wizard! This command will:'); + console.log(' - Guide you through the configuration process.'); + console.log(' - Import or generate private keys.'); + console.log(` - Create a custom preset and show you the way to launch your node!`); + console.log(); + const target = flags.target; + + const customPresetFile = flags.customPreset; + if (existsSync(customPresetFile)) { + throw new Error(`${customPresetFile} already exist!!! You should move the file somewhere else before overwriting it!`); + } + if (existsSync(target)) { + throw new Error( + 'There is currently a ./target folder here!!!! Have you executed bootstrap already? You should move the folder somewhere else before overwriting it!', + ); + } + + const network = await Wizard.resolveNetwork(flags.network); + const preset = networkToPreset[network]; + const assembly = await Wizard.resolveAssembly(preset); + if (network == Network.localNetwork) { + console.log('For a local network, just run: '); + console.log(''); + console.log(`$ symbol-bootstrap start -b ${preset}${assembly ? ` -a ${assembly}` : ''}`); + return; + } + + if (!flags.skipPull) { + const service = await new BootstrapService(); + console.log('\nPulling catapult tools image before asking to go offline...\n'); + ConfigLoader.presetInfoLogged = true; + await BootstrapUtils.pullImage( + service.resolveConfigPreset({ + ...ConfigService.defaultParams, + preset: preset, + assembly: assembly, + target: target, + }).symbolServerImage, + ); + } + console.log(); + console.log(); + if ( + !flags.ready && + !( + await prompt([ + { + name: 'offlineNow', + message: `Symbol Bootstrap is about to start working with sensitive information (private keys) so it is highly recommended that you disconnect from the network before continuing. Say YES if you are offline or if you don't care.`, + type: 'confirm', + default: true, + }, + ]) + ).offlineNow + ) { + console.log('Come back when you are offline...'); + return; + } + + console.log(); + console.log( + 'Symbol bootstrap needs to provide the node with a number of key pairs (Read more at https://docs.symbolplatform.com/concepts/cryptography.html#symbol-keys).', + ); + console.log(`If you don't know what a key is used for, let Symbol Bootstrap generate a new one for you.`); + + const password = await CommandUtils.resolvePassword( + flags.password, + flags.noPassword, + CommandUtils.passwordPromptDefaultMessage, + false, + ); + + const networkType = network === Network.mainnet ? NetworkType.MAIN_NET : NetworkType.TEST_NET; + const accounts = await Wizard.resolveAllAccounts(networkType); + + console.log(); + console.log(`These are your node's accounts:`); + Wizard.logAccount(accounts.main, KeyName.Main, false); + Wizard.logAccount(accounts.vrf, KeyName.VRF, false); + Wizard.logAccount(accounts.remote, KeyName.Remote, false); + Wizard.logAccount(accounts.transport, KeyName.Transport, false); + console.log(); + console.log(); + + const httpsOption: HttpsOption = await this.resolveHttpsOptions(); + + const symbolHostNameRequired = httpsOption !== HttpsOption.None; + const host = await Wizard.resolveHost( + `Enter the public domain name(eg. node-01.mysymbolnodes.com) that's pointing to your outbound host IP ${ + symbolHostNameRequired ? 'This value is required when you are running on HTTPS!' : '' + }`, + symbolHostNameRequired, + ); + + const resolveHttpsCustomPreset = async (): Promise => { + if (httpsOption === HttpsOption.Native) { + const restSSLKeyBase64 = await Wizard.resolveRestSSLKeyAsBase64(); + const restSSLCertificateBase64 = await Wizard.resolveRestSSLCertAsBase64(); + return { + gateways: [ + { + restProtocol: 'HTTPS', + openPort: 3001, + restSSLKeyBase64, + restSSLCertificateBase64, + }, + ], + }; + } else if (httpsOption === HttpsOption.Automatic) { + return { + httpsProxies: [ + { + excludeDockerService: false, + }, + ], + }; + } else { + // HttpsOption.None + console.log(`Warning! You've chosen to proceed with http, which is less secure in comparison to https.`); + return {}; + } + }; + + const httpsCustomPreset = await resolveHttpsCustomPreset(); + const friendlyName = await Wizard.resolveFriendlyName(host || accounts.main.publicKey.substr(0, 7)); + const privateKeySecurityMode = await Wizard.resolvePrivateKeySecurityMode(); + const voting = await Wizard.isVoting(); + const presetContent: CustomPreset = { + assembly: assembly, + preset: preset, + privateKeySecurityMode: privateKeySecurityMode, + nodes: [ + { + host: host, + voting: voting, + friendlyName: friendlyName, + mainPrivateKey: accounts.main.privateKey, + vrfPrivateKey: accounts.vrf.privateKey, + remotePrivateKey: accounts.remote.privateKey, + transportPrivateKey: accounts.transport.privateKey, + }, + ], + ...httpsCustomPreset, + }; + + const defaultParams = ConfigService.defaultParams; + await BootstrapUtils.writeYaml(customPresetFile, presetContent, password); + console.log(); + console.log(); + console.log(`The Symbol Bootstrap preset file '${customPresetFile}' has been created!!!. Keep this safe!`); + console.log(); + console.log(`To decrypt the node's private key, run: `); + console.log(); + console.log(`$ symbol-bootstrap decrypt --source ${customPresetFile} --destination plain-custom-preset.yml`); + console.log(); + console.log('Remember to delete the plain-custom-preset.yml file after used!!!'); + + console.log( + `You can edit this file to further customize it. Read more https://github.com/nemtech/symbol-bootstrap/blob/main/docs/presetGuides.md`, + ); + console.log(); + console.log(`Once you have finished the custom preset customization, You can use the 'start' to run the node in this machine:`); + console.log(); + console.log( + `$ symbol-bootstrap start -p ${network} -a ${assembly} -c ${customPresetFile} ${ + target !== defaultParams.target ? `-t ${target}` : '' + }`, + ); + + console.log(); + console.log(`Alternatively, to create a zip file that can be deployed in your node machine you can use the 'pack' command:`); + console.log(); + console.log( + `$ symbol-bootstrap pack -p ${network} -a ${assembly} -c ${customPresetFile} ${ + target !== defaultParams.target ? `-t ${target}` : '' + }`, + ); + console.log(); + console.log( + `Once the target folder is created, Bootstrap will use the protected and encrypted addresses.yml, and preset.yml in inside the target folder.`, + ); + console.log( + 'To upgrade your node version or configuration, use the --upgrade parameter in config, compose, start and/or pack. Remember to backup the node`s target folder!', + ); + console.log( + 'Hint: You can change the configuration of an already created node by proving a new custom preset. This is an experimental feature, backup the target folder before!', + ); + console.log(); + console.log('To complete the registration, you need to link your keys (online):'); + console.log(); + console.log(`$ symbol-bootstrap link --useKnownRestGateways -c ${customPresetFile}`); + console.log(); + } + public static logAccount(account: T, keyName: KeyName, showPrivateKeys: boolean): T { + if (account === undefined) { + return account; + } + const privateKeyText = showPrivateKeys && account instanceof Account ? `\n\tPrivate Key: ${account.privateKey}` : ''; + console.log(` - ${keyName}:\n\tAddress: ${account.address.plain()}\n\tPublic Key: ${account.publicKey}${privateKeyText}`); + return account as T; + } + + private static async resolveAllAccounts(networkType: NetworkType): Promise { + console.log(); + return { + seeded: true, + main: await this.resolveAccountFromSelection( + networkType, + KeyName.Main, + 'It holds the tokens required to give the node its importance.', + ), + transport: await this.resolveAccountFromSelection( + networkType, + KeyName.Transport, + 'It is used by nodes for secure transport over TLS.', + ), + vrf: await this.resolveAccountFromSelection(networkType, KeyName.VRF, 'It is required for harvesting.'), + remote: await this.resolveAccountFromSelection( + networkType, + KeyName.Remote, + 'It is used to harvest and collect the rewards on behalf of the main account in remote harvesting.', + ), + }; + } + + public static async resolveAccountFromSelection(networkType: NetworkType, keyName: KeyName, keyDescription: string): Promise { + console.log(`${keyName} Key Pair: ${keyDescription}`); + while (true) { + const keyCreationChoices = []; + keyCreationChoices.push({ name: 'Generating a new account', value: 'generate' }); + keyCreationChoices.push({ name: 'Entering a private key', value: 'manual' }); + const { keyCreationMode } = await prompt([ + { + name: 'keyCreationMode', + message: `How do you want to create the ${keyName} account:`, + type: 'list', + default: keyCreationChoices[0].name, + choices: keyCreationChoices, + }, + ]); + const log = (account: Account, message: string): Account => { + console.log(); + console.log(`Using account ${account.address.plain()} for ${keyName} key. ${message}`); + console.log(); + return account; + }; + if (keyCreationMode == 'generate') { + return log(this.generateAccount(networkType), 'It will be stored in your custom preset. Keep file safe!'); + } + // manual + const account = await Wizard.resolveAccount(networkType, keyName); + if (account) { + return log( + account, + 'It will be stored in your custom preset. You can recreate the account by providing the private key again!', + ); + } + } + } + + public static generateAccount(networkType: NetworkType): Account { + return Account.generateNewAccount(networkType); + } + + public static async resolveAccount(networkType: NetworkType, keyName: KeyName): Promise { + while (true) { + const { privateKey } = await prompt([ + { + name: 'privateKey', + message: `Enter the 64 HEX private key of the ${keyName} account (or press enter to select the option again).`, + type: 'password', + mask: '*', + validate: (value) => { + if (!value) { + return true; + } + return CommandUtils.isValidPrivateKey(value); + }, + }, + ]); + if (!privateKey) { + return undefined; + } else { + const enteredAccount = Account.createFromPrivateKey(privateKey, networkType); + const { ok } = await prompt([ + { + name: 'ok', + message: `Is this the expected address ${enteredAccount.address.plain()} to used as ${keyName} account? `, + type: 'confirm', + default: false, + }, + ]); + if (ok) { + return enteredAccount; + } + } + } + } + + public static async resolveNetwork(providedNetwork: Network | undefined): Promise { + if (!providedNetwork) { + console.log('Select type node or network you want to run:\n'); + const responses = await prompt([ + { + name: 'network', + message: 'Select a network:', + type: 'list', + default: Network.mainnet, + choices: [ + { name: 'Mainnet Node', value: Network.mainnet }, + { name: 'Testnet Node', value: Network.testnet }, + { name: 'Local Network', value: Network.localNetwork }, + ], + }, + ]); + return responses.network; + } + return providedNetwork; + } + + public static async resolvePrivateKeySecurityMode(): Promise { + const { mode } = await prompt([ + { + name: 'mode', + message: 'Select the type of security you want to use:', + type: 'list', + default: PrivateKeySecurityMode.PROMPT_MAIN_TRANSPORT, + choices: [ + { + name: + 'PROMPT_MAIN: Bootstrap may ask for the Main private key when doing certificates upgrades. Other keys are encrypted.', + value: PrivateKeySecurityMode.PROMPT_MAIN, + }, + { + name: + 'PROMPT_MAIN_TRANSPORT: Bootstrap may ask for the Main and Transport private keys when regenerating certificates. Other keys are encrypted. Recommended for most nodes', + value: PrivateKeySecurityMode.PROMPT_MAIN_TRANSPORT, + }, + { name: 'ENCRYPT: All keys are encrypted, only password would be asked', value: PrivateKeySecurityMode.ENCRYPT }, + ], + }, + ]); + return mode; + } + + public static async resolveAssembly(preset: Preset): Promise { + console.log('Select the assembly to be created:\n'); + const responses = await prompt([ + { + name: 'assembly', + message: 'Select an assembly:', + type: 'list', + default: assemblies[preset][0].value, + choices: assemblies[preset].map(({ value, description }) => ({ + value: value, + name: description, + })), + }, + ]); + return responses.assembly; + } + + private static async isVoting(): Promise { + console.log( + 'Select whether your Symbol node should be a Voting node. Note: A Voting node requires the main account to hold at least 3 million XYMs. ', + ); + console.log('If your node does not have enough XYMs its Voting key may not be included. '); + const { voting } = await prompt([ + { + name: 'voting', + message: 'Are you creating a Voting node?', + type: 'confirm', + default: false, + }, + ]); + return voting; + } + + public static getNetworkIdFlag(): IOptionFlag { + return flags.string({ + description: 'The node or network you want to create', + options: [Network.mainnet, Network.testnet, Network.localNetwork], + }) as IOptionFlag; + } + + public static getCustomPresetFile(): IOptionFlag { + return flags.string({ char: 'c', description: 'The custom preset to be created.', default: 'custom-preset.yml' }); + } + + public static async resolveHost(message: string, required: boolean): Promise { + const { host } = await prompt([ + { + name: 'host', + message: message, + type: 'input', + validate: (value) => { + if (!required && !value) { + return true; + } + return Wizard.isValidHost(value); + }, + }, + ]); + return host || undefined; + } + + public static async resolveRestSSLKeyAsBase64(): Promise { + return this.resolveFileContent('base64', 'Enter your SSL key file path:', 'Invalid path, cannot find SSL key file!'); + } + + public static async resolveRestSSLCertAsBase64(): Promise { + return this.resolveFileContent( + 'base64', + 'Enter your SSL Certificate file path:', + 'Invalid path, cannot find SSL certificate file!', + ); + } + + public static async resolveFileContent(encoding: string, message: string, notFoundMessage: string): Promise { + const { value } = await prompt([ + { + name: 'value', + message: message, + type: 'input', + validate: (value) => { + if (!existsSync(value)) { + return notFoundMessage; + } + return true; + }, + }, + ]); + + return readFileSync(value, encoding); + } + + // TODO Refactor this + public static isValidHost(input: string): boolean | string { + if (input.trim() == '') { + return 'Host is required.'; + } + if (input.length > 50) { + return `Input (${input.length}) is larger than 50`; + } + const valid = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$|^(?:(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)+(?:[A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$|^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/.test( + input, + ); + return valid ? true : `It's not a valid IP or hostname`; + } + + public static isValidFriendlyName(input: string): boolean | string { + if (input.trim() == '') { + return 'Friendly name is required.'; + } + if (input.length > 30) { + return `Input (${input.length}) is larger than 30`; + } + return true; + } + public static async resolveFriendlyName(defaultFriendlyName: string): Promise { + const { friendlyName } = await prompt([ + { + name: 'friendlyName', + message: `Enter the friendly name of your node.`, + type: 'input', + default: defaultFriendlyName, + validate: Wizard.isValidFriendlyName, + }, + ]); + return friendlyName; + } + + public static async resolveHttpsOptions(): Promise { + // TODO work on these messages, should be concise and clearer + console.log( + 'Your REST Gateway should be running on HTTPS (which is a secure protocol) so that it can be recognized by the Symbol Explorer.', + ); + const { value } = await prompt([ + { + name: 'value', + message: 'Select your HTTPS setup method:', + type: 'list', + default: HttpsOption.Native, + choices: [ + { name: 'Native support, I have the SSL certificate and key.', value: HttpsOption.Native }, + { + name: `Automatic, all of your keys and certs will be generated/renewed automatically, using letsencyrpt.`, + value: HttpsOption.Automatic, + }, + { name: 'None', value: HttpsOption.None }, + ], + }, + ]); + return value; + } +} diff --git a/src/model/Addresses.ts b/src/model/Addresses.ts index e3d75c6e6..50b5b1f6f 100644 --- a/src/model/Addresses.ts +++ b/src/model/Addresses.ts @@ -38,8 +38,6 @@ export interface NodeAccount { vrf?: ConfigAccount; // Voting keys are produced if node is voting voting?: VotingKeyFile[]; - // Agent private key is produced if node is supernode - agent?: ConfigAccount; roles: string; name: string; friendlyName: string; diff --git a/src/model/ConfigPreset.ts b/src/model/ConfigPreset.ts index bd6e3a9b7..897871105 100644 --- a/src/model/ConfigPreset.ts +++ b/src/model/ConfigPreset.ts @@ -15,8 +15,7 @@ */ import { NetworkType } from 'symbol-sdk'; -import { Preset, RewardProgram } from '../service'; -import { NodeType } from './NodeType'; +import { Preset } from '../service'; export enum PrivateKeySecurityMode { ENCRYPT = 'ENCRYPT', @@ -248,7 +247,6 @@ export interface NodeConfigPreset { maxProofSize: number; maxTransactionsPerBlock: number; localNetworks: string; - rewardProgramAgentPort: number; } export interface NodePreset extends DockerServicePreset, Partial { @@ -276,9 +274,6 @@ export interface NodePreset extends DockerServicePreset, Partial { @@ -329,6 +319,14 @@ export interface GatewayPreset extends DockerServicePreset, Partial; - knownPeers?: Record; + // Allows hardcoded list. For new networks and for possible fallbacks. + knownRestGateways?: string[]; + knownPeers?: PeerInfo[]; } export interface ConfigPreset extends CommonConfigPreset { @@ -436,6 +446,7 @@ export interface ConfigPreset extends CommonConfigPreset { explorers?: ExplorerPreset[]; wallets?: WalletPreset[]; faucets?: FaucetPreset[]; + httpsProxies?: HttpsProxyPreset[]; } export interface CustomPreset extends Partial { @@ -446,4 +457,5 @@ export interface CustomPreset extends Partial { explorers?: Partial[]; wallets?: Partial[]; faucets?: Partial[]; + httpsProxies?: Partial[]; } diff --git a/src/model/DockerCompose.ts b/src/model/DockerCompose.ts index 632ea0f5d..aad29a971 100644 --- a/src/model/DockerCompose.ts +++ b/src/model/DockerCompose.ts @@ -28,6 +28,7 @@ export interface DockerComposeService { user?: string; working_dir?: string; command?: string; + entrypoint?: string; hostname?: string; environment?: any; stop_signal?: string; diff --git a/src/model/NodeType.ts b/src/model/NodeType.ts deleted file mode 100644 index ebb739b26..000000000 --- a/src/model/NodeType.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2020 NEM - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export enum NodeType { - PEER_NODE = 'peer-node', - API_NODE = 'api-node', -} diff --git a/src/model/index.ts b/src/model/index.ts index f11ebd199..66216bab8 100644 --- a/src/model/index.ts +++ b/src/model/index.ts @@ -3,4 +3,3 @@ export * from './Addresses'; export * from './ConfigPreset'; export * from './DockerCompose'; -export * from './NodeType'; diff --git a/src/service/AgentCertificateService.ts b/src/service/AgentCertificateService.ts deleted file mode 100644 index 3ddabf0d7..000000000 --- a/src/service/AgentCertificateService.ts +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright 2020 NEM - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { existsSync } from 'fs'; -import { join, resolve } from 'path'; -import { NetworkType } from 'symbol-sdk'; -import { LogType } from '../logger'; -import Logger from '../logger/Logger'; -import LoggerFactory from '../logger/LoggerFactory'; -import { CertificatePair } from '../model'; -import { BootstrapUtils } from './BootstrapUtils'; -import { CertificateService } from './CertificateService'; -import { CommandUtils } from './CommandUtils'; -import { KeyName } from './ConfigService'; -export interface AgentCertificateParams { - readonly target: string; - readonly user: string; -} - -export interface AgentCertificates { - agent: CertificatePair; -} - -export interface AgentCertificateMetadata { - readonly agentPublicKey: string; - readonly version: number; -} - -const logger: Logger = LoggerFactory.getLogger(LogType.System); - -export class AgentCertificateService { - private static readonly METADATA_VERSION = 1; - constructor(private readonly root: string, protected readonly params: AgentCertificateParams) {} - - public async run( - networkType: NetworkType, - symbolServerImage: string, - name: string, - providedCertificates: AgentCertificates, - customCertFolder?: string, - ): Promise { - const copyFrom = `${this.root}/config/agent-cert`; - const certFolder = customCertFolder || BootstrapUtils.getTargetNodesFolder(this.params.target, false, name, 'agent'); - await BootstrapUtils.mkdir(certFolder); - - const metadataFile = join(certFolder, 'metadata.yml'); - if (!(await this.shouldGenerateCertificate(metadataFile, providedCertificates))) { - logger.info(`Agent Certificates for node ${name} have been previously generated. Reusing...`); - return; - } - await BootstrapUtils.deleteFolder(certFolder); - await BootstrapUtils.mkdir(certFolder); - const newCertsFolder = join(certFolder, 'new_certs'); - await BootstrapUtils.mkdir(newCertsFolder); - - const generatedContext = { name }; - await BootstrapUtils.generateConfiguration(generatedContext, copyFrom, certFolder, []); - - const agentPrivateKey = await CommandUtils.resolvePrivateKey( - networkType, - providedCertificates.agent, - KeyName.Agent, - name, - 'generating the Agent certificates', - ); - BootstrapUtils.createDerFile(agentPrivateKey, join(certFolder, 'agent-ca.der')); - - const command = this.createCertCommands('/data'); - await BootstrapUtils.writeTextFile(join(certFolder, 'createAgentCertificate.sh'), command); - const cmd = ['bash', 'createAgentCertificate.sh']; - const binds = [`${resolve(certFolder)}:/data:rw`]; - const userId = await BootstrapUtils.resolveDockerUserFromParam(this.params.user); - const { stdout, stderr } = await BootstrapUtils.runImageUsingExec({ - image: symbolServerImage, - userId: userId, - workdir: '/data', - cmds: cmd, - binds: binds, - }); - if (stdout.indexOf('Certificate Created') < 0) { - logger.info(BootstrapUtils.secureString(stdout)); - logger.error(BootstrapUtils.secureString(stderr)); - throw new Error('Certificate creation failed. Check the logs!'); - } - - const certificates = CertificateService.getCertificates(stdout); - if (certificates.length != 1) { - throw new Error('Certificate creation failed. 1 certificates should have been created but got: ' + certificates.length); - } - const agentCertificate = certificates[0]; - BootstrapUtils.validateIsTrue(agentCertificate.privateKey === agentPrivateKey, 'Invalid agent private key'); - BootstrapUtils.validateIsTrue(agentCertificate.publicKey === providedCertificates.agent.publicKey, 'Invalid agent public key'); - logger.info(`Agent Certificate for node ${name} created`); - const metadata: AgentCertificateMetadata = { - version: AgentCertificateService.METADATA_VERSION, - agentPublicKey: providedCertificates.agent.publicKey, - }; - await BootstrapUtils.writeYaml(metadataFile, metadata, undefined); - } - private async shouldGenerateCertificate(metadataFile: string, providedCertificates: AgentCertificates): Promise { - if (!existsSync(metadataFile)) { - return true; - } - try { - const metadata = BootstrapUtils.loadYaml(metadataFile, false) as AgentCertificateMetadata; - return ( - metadata.agentPublicKey !== providedCertificates.agent.publicKey || - metadata.version !== AgentCertificateService.METADATA_VERSION - ); - } catch (e) { - logger.warn(`Cannot load agent certificate metadata from file ${metadataFile}. Error: ${e.message}`, e); - return true; - } - } - - // Alternative reading the public key from agent-ca.pubkey.pem - // It's ok but it requires sshpk and unsure how to force an regeneration - // private async shouldGenerateCertificate(certFolder: string, providedCertificates: AgentCertificates): Promise { - // const pemFile = join(certFolder, 'agent-ca.pubkey.pem'); - // if (!existsSync(pemFile)) { - // return true; - // } - // try { - // const data = readFileSync(pemFile); - // const key = sshpk.parseKey(data, 'pem'); - // const storedPublicKey = Convert.uint8ToHex((key.part as any).A.data); - // return storedPublicKey !== providedCertificates.agent.publicKey; - // } catch (e) { - // logger.warn(`Cannot extract public key from file ${pemFile}. Error: ${e.message}`, e); - // return true; - // } - // } - - private createCertCommands(target: string): string { - return `set -e -cd ${target} - -# prepare dirs/files -chmod 700 new_certs -touch index.txt - -# Creating a self signed certificate for the agent. This will be created by bootstrap when setting up a supernode - -cat agent-ca.der | openssl pkey -inform DER -outform PEM -out agent-ca.key.pem -openssl pkey -inform pem -in agent-ca.key.pem -text -noout -openssl pkey -in agent-ca.key.pem -pubout -out agent-ca.pubkey.pem - -# create agent CA CSR -openssl req -config agent-ca.cnf -key agent-ca.key.pem -new -out agent-ca.csr.pem - -rm createAgentCertificate.sh -rm agent-ca.der - -echo "Certificate Created" -`; - } -} diff --git a/src/service/AnnounceService.ts b/src/service/AnnounceService.ts index 9af4c34cd..d66bf4672 100644 --- a/src/service/AnnounceService.ts +++ b/src/service/AnnounceService.ts @@ -21,16 +21,23 @@ import { Address, AggregateTransaction, Convert, + Currency, Deadline, + IListener, LockFundsTransaction, + Mosaic, MosaicId, MultisigAccountInfo, + MultisigAccountModificationTransaction, NetworkType, + PlainMessage, PublicAccount, RepositoryFactory, SignedTransaction, Transaction, TransactionService, + TransactionType, + TransferTransaction, UInt64, } from 'symbol-sdk'; import { LogType } from '../logger'; @@ -39,7 +46,7 @@ import LoggerFactory from '../logger/LoggerFactory'; import { Addresses, ConfigPreset, NodeAccount, NodePreset } from '../model'; import { CommandUtils } from './CommandUtils'; import { KeyName } from './ConfigService'; -import { RemoteNodeService } from './RemoteNodeService'; +import { TransactionUtils } from './TransactionUtils'; const logger: Logger = LoggerFactory.getLogger(LogType.System); @@ -47,7 +54,7 @@ export interface TransactionFactoryParams { presetData: ConfigPreset; nodePreset: NodePreset; nodeAccount: NodeAccount; - mainAccountInfo: AccountInfo; + mainAccountInfo?: AccountInfo; // the main account is brand new. It's likely that the service provider account it's being used. mainAccount: PublicAccount; deadline: Deadline; target: string; @@ -88,7 +95,12 @@ export class AnnounceService { description: `This command uses the encrypted addresses.yml to resolve the main private key. If the main private is only stored in the custom preset, you can provide it using this param. Otherwise, the command may ask for it when required.`, required: false, }), + serviceProviderPublicKey: flags.string({ + description: + 'Public key of the service provider account, used when the transaction announcer(service provider account) is different than the main account private key holder', + }), }; + public async announce( providedUrl: string, providedMaxFee: number | undefined, @@ -99,6 +111,7 @@ export class AnnounceService { addresses: Addresses, transactionFactory: TransactionFactory, tokenAmount = 'some', + serviceProviderPublicKey?: string, ): Promise { AnnounceService.onProcessListener(); if (!presetData.nodes || !presetData.nodes?.length) { @@ -106,9 +119,7 @@ export class AnnounceService { return; } const url = providedUrl.replace(/\/$/, ''); - const urls = (useKnownRestGateways && presetData.knownRestGateways) || [url]; - const repositoryInfo = await new RemoteNodeService().getBestRepositoryInfo(urls); - const repositoryFactory = repositoryInfo.repositoryFactory; + const repositoryFactory = await TransactionUtils.getRepositoryFactory(presetData, useKnownRestGateways ? undefined : url); const networkType = await repositoryFactory.getNetworkType().toPromise(); const transactionRepository = repositoryFactory.createTransactionRepository(); const transactionService = new TransactionService(transactionRepository, repositoryFactory.createReceiptRepository()); @@ -122,6 +133,9 @@ export class AnnounceService { const minFeeMultiplier = (await repositoryFactory.createNetworkRepository().getTransactionFees().toPromise()).minFeeMultiplier; const latestFinalizedBlockEpoch = (await repositoryFactory.createChainRepository().getChainInfo().toPromise()).latestFinalizedBlock .finalizationEpoch; + if (!currencyMosaicId) { + throw new Error('Mosaic Id must not be null!'); + } if (providedMaxFee) { logger.info(`MaxFee is ${providedMaxFee / Math.pow(10, currency.divisibility)}`); } else { @@ -141,23 +155,46 @@ export class AnnounceService { } const nodePreset = (presetData.nodes || [])[index]; const mainAccount = PublicAccount.createFromPublicKey(nodeAccount.main.publicKey, presetData.networkType); + const serviceProviderPublicAccount = serviceProviderPublicKey + ? PublicAccount.createFromPublicKey(serviceProviderPublicKey, presetData.networkType) + : undefined; + if (serviceProviderPublicAccount) { + logger.info( + `The Service Provider Account ${CommandUtils.formatAccount( + serviceProviderPublicAccount, + )} is creating transactions on behalf of your node account ${CommandUtils.formatAccount(mainAccount)}.`, + ); + } + const announcerPublicAccount = serviceProviderPublicAccount ? serviceProviderPublicAccount : mainAccount; const noFundsMessage = faucetUrl - ? `Does your node signing address have any network coin? Send ${tokenAmount} tokens to ${mainAccount.address.plain()} via ${faucetUrl}/?recipient=${mainAccount.address.plain()}` - : `Does your node signing address have any network coin? Send ${tokenAmount} tokens to ${mainAccount.address.plain()} .`; - const mainAccountInfo = await this.getAccountInfo(repositoryFactory, mainAccount.address); + ? `Your account does not have enough XYM to complete this transaction. Send ${tokenAmount} tokens to ${announcerPublicAccount.address.plain()} via ${faucetUrl}/?recipient=${announcerPublicAccount.address.plain()}` + : `Your account does not have enough XYM to complete this transaction. Send ${tokenAmount} tokens to ${announcerPublicAccount.address.plain()} .`; + const announcerAccountInfo = await this.getAccountInfo(repositoryFactory, announcerPublicAccount.address); - if (!mainAccountInfo) { - logger.error(`Node signing account ${mainAccount.address.plain()} is not valid. \n\n${noFundsMessage}`); + if (!announcerAccountInfo) { + logger.error( + `Node signing account ${CommandUtils.formatAccount(announcerPublicAccount)} is not valid. \n\n${noFundsMessage}`, + ); continue; } - if (this.isAccountEmpty(mainAccountInfo, currencyMosaicId)) { + if (this.isAccountEmpty(announcerAccountInfo, currencyMosaicId)) { logger.error( - `Node signing account ${mainAccount.address.plain()} does not have enough currency. Mosaic id: ${currencyMosaicId}. \n\n${noFundsMessage}`, + `Node signing account ${CommandUtils.formatAccount( + announcerPublicAccount, + )} does not have enough currency. Mosaic id: ${currencyMosaicId}. \n\n${noFundsMessage}`, ); continue; } + + const mainAccountInfo = mainAccount.address.equals(announcerPublicAccount.address) + ? announcerAccountInfo + : await this.getAccountInfo(repositoryFactory, mainAccount.address); + if (!mainAccountInfo) { + logger.info(`Main account ${CommandUtils.formatAccount(mainAccount)} is brand new. There are no records on the chain yet.`); + } + const defaultMaxFee = UInt64.fromUint(providedMaxFee || 0); - const multisigAccountInfo = await this.getMultisigAccount(repositoryFactory, mainAccount.address); + const multisigAccountInfo = await TransactionUtils.getMultisigAccount(repositoryFactory, announcerPublicAccount.address); const params: TransactionFactoryParams = { presetData, nodePreset, @@ -165,7 +202,7 @@ export class AnnounceService { mainAccountInfo, latestFinalizedBlockEpoch, target, - mainAccount, + mainAccount: announcerPublicAccount, deadline, maxFee: defaultMaxFee, }; @@ -175,36 +212,11 @@ export class AnnounceService { continue; } - const getTransactionDescription = (transaction: Transaction, signedTransaction: SignedTransaction): string => { - return `${transaction.constructor.name} - Hash: ${signedTransaction.hash} - MaxFee ${ - transaction.maxFee.compact() / Math.pow(10, currency.divisibility) - }`; - }; - - const shouldAnnounce = async (transaction: Transaction, signedTransaction: SignedTransaction): Promise => { - const response: boolean = - ready || - ( - await prompt([ - { - name: 'value', - message: `Do you want to announce ${getTransactionDescription(transaction, signedTransaction)}?`, - type: 'confirm', - default: true, - }, - ]) - ).value; - if (!response) { - logger.info(`Ignoring transaction for node ${nodeAccount.name}`); - } - return response; - }; - const resolveMainAccount = async (): Promise => { const presetMainPrivateKey = (presetData.nodes || [])[index]?.mainPrivateKey; if (presetMainPrivateKey) { const account = Account.createFromPrivateKey(presetMainPrivateKey, networkType); - if (account.address.equals(mainAccount.address)) { + if (account.address.equals(announcerPublicAccount.address)) { return account; } } @@ -221,161 +233,180 @@ export class AnnounceService { ); }; - if (multisigAccountInfo) { - logger.info( - `The node's main account is a multig account with Address: ${ - multisigAccountInfo.minApproval - } min approval. Cosigners are: ${multisigAccountInfo.cosignatoryAddresses - .map((a) => a.plain()) - .join( - ', ', - )}. The tool will ask for the cosigners provide keys in order to announce the transactions. These private keys are not stored anywhere!`, - ); - const cosigners = await this.promptAccounts( - networkType, - multisigAccountInfo.cosignatoryAddresses, - multisigAccountInfo.minApproval, - ); - if (!cosigners.length) { - logger.info('No cosigner has been provided, ignoring!'); - continue; - } - const bestCosigner = await this.getBestCosigner(repositoryFactory, cosigners, currencyMosaicId); - if (!bestCosigner) { - logger.info(`There is no cosigner with enough tokens to announce!`); - continue; - } - logger.info(`Cosigner ${bestCosigner.address.plain()} is initializing the transactions.`); - if (cosigners.length >= multisigAccountInfo.minApproval) { - let aggregateTransaction = AggregateTransaction.createComplete( - deadline, - transactions.map((t) => t.toAggregate(mainAccount)), + const cosigners: Account[] = []; + + if (serviceProviderPublicAccount) { + let signerAccount: Account; + let requiredCosignatures = 1; // for mainAccount + if (multisigAccountInfo) { + const bestCosigner = await this.getMultisigBestCosigner( + multisigAccountInfo, + cosigners, + 'Service provider account', networkType, - [], - defaultMaxFee, + repositoryFactory, + currencyMosaicId, ); - if (!providedMaxFee) { - aggregateTransaction = aggregateTransaction.setMaxFeeForAggregate(minFeeMultiplier, cosigners.length - 1); - } - const signedAggregateTransaction = bestCosigner.signTransactionWithCosignatories( - aggregateTransaction, - cosigners.filter((a) => a !== bestCosigner), - generationHash, - ); - if (!(await shouldAnnounce(aggregateTransaction, signedAggregateTransaction))) { + if (!bestCosigner) { + logger.info(`There is no cosigner with enough tokens to announce!`); continue; } - try { - logger.info(`Announcing ${getTransactionDescription(aggregateTransaction, signedAggregateTransaction)}`); - await transactionService.announce(signedAggregateTransaction, listener).toPromise(); - logger.info(`${getTransactionDescription(aggregateTransaction, signedAggregateTransaction)} has been confirmed`); - } catch (e) { - const message = - `Aggregate Complete Transaction ${signedAggregateTransaction.type} ${ - signedAggregateTransaction.hash - } - signer ${signedAggregateTransaction.getSignerAddress().plain()} failed!! ` + e.message; - logger.error(message); - } + logger.info(`Cosigner ${CommandUtils.formatAccount(bestCosigner.publicAccount)} is initializing the transactions.`); + signerAccount = bestCosigner; // override with a cosigner when multisig + requiredCosignatures = multisigAccountInfo.minApproval; } else { - let aggregateTransaction = AggregateTransaction.createBonded( - deadline, - transactions.map((t) => t.toAggregate(mainAccount)), + // ask for serviceProviderAccount private key + signerAccount = Account.createFromPrivateKey( + await CommandUtils.resolvePrivateKey( + networkType, + serviceProviderPublicAccount, + KeyName.ServiceProvider, + '', + 'signing a transaction', + ), networkType, - [], - defaultMaxFee, - ); - if (!providedMaxFee) { - aggregateTransaction = aggregateTransaction.setMaxFeeForAggregate(minFeeMultiplier, cosigners.length - 1); - } - const signedAggregateTransaction = bestCosigner.signTransactionWithCosignatories( - aggregateTransaction, - cosigners.filter((a) => a !== bestCosigner), - generationHash, ); - let lockFundsTransaction: Transaction = LockFundsTransaction.create( + } + const mainMultisigAccountInfo = await TransactionUtils.getMultisigAccount(repositoryFactory, mainAccount.address); + requiredCosignatures += mainMultisigAccountInfo?.minApproval || 0; // mainAccount.minApproval + + const zeroAmountInnerTransaction = (account: PublicAccount): Transaction => + TransferTransaction.create( deadline, - currency.createRelative(10), - UInt64.fromUint(1000), - signedAggregateTransaction, + account.address, // self transfer + [new Mosaic(currencyMosaicId, UInt64.fromUint(0))], // zero amount + PlainMessage.create(''), networkType, defaultMaxFee, - ); - if (!providedMaxFee) { - lockFundsTransaction = lockFundsTransaction.setMaxFee(minFeeMultiplier); - } - const signedLockFundsTransaction = bestCosigner.sign(lockFundsTransaction, generationHash); - if (!(await shouldAnnounce(lockFundsTransaction, signedLockFundsTransaction))) { - continue; - } - if (!(await shouldAnnounce(aggregateTransaction, signedAggregateTransaction))) { - continue; - } + ).toAggregate(account); - try { - logger.info(`Announcing ${getTransactionDescription(lockFundsTransaction, signedLockFundsTransaction)}`); - await transactionService.announce(signedLockFundsTransaction, listener).toPromise(); - logger.info(`${getTransactionDescription(lockFundsTransaction, signedLockFundsTransaction)} has been confirmed`); - - logger.info(`Announcing Bonded ${getTransactionDescription(aggregateTransaction, signedAggregateTransaction)}`); - await transactionService.announceAggregateBonded(signedAggregateTransaction, listener).toPromise(); - logger.info(`${getTransactionDescription(aggregateTransaction, signedAggregateTransaction)} has been announced`); - - logger.info('Aggregate Bonded Transaction has been confirmed! Your cosigners would need to cosign!'); - } catch (e) { - const message = - `Aggregate Bonded Transaction ${signedAggregateTransaction.type} ${ - signedAggregateTransaction.hash - } - signer ${signedAggregateTransaction.getSignerAddress().plain()} failed!! ` + e.message; - logger.error(message); - } - } + await this.announceAggregateBonded( + signerAccount, + () => [ + ...transactions.map((t) => t.toAggregate(mainAccount)), + zeroAmountInnerTransaction(serviceProviderPublicAccount), + ], + requiredCosignatures, + deadline, + networkType, + defaultMaxFee, + providedMaxFee, + minFeeMultiplier, + cosigners, + generationHash, + currency, + transactionService, + listener, + ready, + nodeAccount.name, + ); } else { - const signerAccount = await resolveMainAccount(); - if (transactions.length == 1) { - let transaction = transactions[0]; - if (!providedMaxFee) { - transaction = transaction.setMaxFee(minFeeMultiplier); - } - const signedTransaction = signerAccount.sign(transactions[0], generationHash); - if (!(await shouldAnnounce(transaction, signedTransaction))) { - continue; - } - try { - logger.info(`Announcing ${getTransactionDescription(transaction, signedTransaction)}`); - await transactionService.announce(signedTransaction, listener).toPromise(); - logger.info(`${getTransactionDescription(transaction, signedTransaction)} has been confirmed`); - } catch (e) { - const message = - `Simple Transaction ${signedTransaction.type} ${ - signedTransaction.hash - } - signer ${signedTransaction.getSignerAddress().plain()} failed!! ` + e.message; - logger.error(message); - } - } else { - let aggregateTransaction = AggregateTransaction.createComplete( - deadline, - transactions.map((t) => t.toAggregate(mainAccount)), + if (multisigAccountInfo) { + const bestCosigner = await this.getMultisigBestCosigner( + multisigAccountInfo, + cosigners, + `The node's main account`, networkType, - [], - defaultMaxFee, + repositoryFactory, + currencyMosaicId, ); - if (!providedMaxFee) { - aggregateTransaction = aggregateTransaction.setMaxFeeForAggregate(minFeeMultiplier, 0); - } - const signedAggregateTransaction = signerAccount.sign(aggregateTransaction, generationHash); - if (!(await shouldAnnounce(aggregateTransaction, signedAggregateTransaction))) { + if (!bestCosigner) { + logger.info(`There is no cosigner with enough tokens to announce!`); continue; } - try { - logger.info(`Announcing ${getTransactionDescription(aggregateTransaction, signedAggregateTransaction)}`); - await transactionService.announce(signedAggregateTransaction, listener).toPromise(); - logger.info(`${getTransactionDescription(aggregateTransaction, signedAggregateTransaction)} has been confirmed`); - } catch (e) { - const message = - `Aggregate Complete Transaction ${signedAggregateTransaction.type} ${ - signedAggregateTransaction.hash - } - signer ${signedAggregateTransaction.getSignerAddress().plain()} failed!! ` + e.message; - logger.error(message); + logger.info(`Cosigner ${CommandUtils.formatAccount(bestCosigner.publicAccount)} is initializing the transactions.`); + if (cosigners.length >= multisigAccountInfo.minApproval) { + //agg complete + await this.announceAggregateComplete( + bestCosigner, + () => transactions.map((t) => t.toAggregate(mainAccount)), + deadline, + networkType, + defaultMaxFee, + providedMaxFee, + minFeeMultiplier, + generationHash, + currency, + transactionService, + listener, + ready, + nodeAccount.name, + cosigners.length - 1, + cosigners, + ); + } else { + //agg bonded + await this.announceAggregateBonded( + bestCosigner, + () => transactions.map((t) => t.toAggregate(mainAccount)), + multisigAccountInfo.minApproval, + deadline, + networkType, + defaultMaxFee, + providedMaxFee, + minFeeMultiplier, + cosigners, + generationHash, + currency, + transactionService, + listener, + ready, + nodeAccount.name, + ); + } + } else { + const signerAccount = await resolveMainAccount(); + if (transactions.length == 1) { + if (transactions[0].type === TransactionType.MULTISIG_ACCOUNT_MODIFICATION) { + const multisigModificationTx = transactions[0] as MultisigAccountModificationTransaction; + await this.announceAggregateBonded( + signerAccount, + () => transactions.map((t) => t.toAggregate(mainAccount)), + (multisigModificationTx.addressAdditions || []).length + (multisigModificationTx.minApprovalDelta || 0), + deadline, + networkType, + defaultMaxFee, + providedMaxFee, + minFeeMultiplier, + cosigners, + generationHash, + currency, + transactionService, + listener, + ready, + nodeAccount.name, + ); + } else { + await this.announceSimple( + signerAccount, + transactions[0], + providedMaxFee, + minFeeMultiplier, + generationHash, + currency, + transactionService, + listener, + ready, + nodeAccount.name, + ); + } + } else { + await this.announceAggregateComplete( + signerAccount, + () => transactions.map((t) => t.toAggregate(mainAccount)), + deadline, + networkType, + defaultMaxFee, + providedMaxFee, + minFeeMultiplier, + generationHash, + currency, + transactionService, + listener, + ready, + nodeAccount.name, + 0, + ); } } } @@ -451,18 +482,6 @@ export class AnnounceService { } } - private async getMultisigAccount( - repositoryFactory: RepositoryFactory, - mainAccountAddress: Address, - ): Promise { - try { - const info = await repositoryFactory.createMultisigRepository().getMultisigAccountInfo(mainAccountAddress).toPromise(); - return info.isMultisig() ? info : undefined; - } catch (e) { - return undefined; - } - } - private async getBestCosigner( repositoryFactory: RepositoryFactory, cosigners: Account[], @@ -487,4 +506,215 @@ export class AnnounceService { const mosaic = mainAccountInfo.mosaics.find((m) => m.id.equals(currencyMosaicId)); return !mosaic || mosaic.amount.compare(UInt64.fromUint(0)) < 1; } + + private async announceAggregateBonded( + signerAccount: Account, + transactionFactory: () => Transaction[], + requiredCosignatures: number, + deadline: Deadline, + networkType: NetworkType, + defaultMaxFee: UInt64, + providedMaxFee: number | undefined, + minFeeMultiplier: number, + cosigners: Account[], + generationHash: string, + currency: Currency, + transactionService: TransactionService, + listener: IListener, + ready: boolean | undefined, + nodeName: string, + ): Promise { + let aggregateTransaction = AggregateTransaction.createBonded(deadline, transactionFactory(), networkType, [], defaultMaxFee); + if (!providedMaxFee) { + aggregateTransaction = aggregateTransaction.setMaxFeeForAggregate(minFeeMultiplier, requiredCosignatures); + } + const signedAggregateTransaction = signerAccount.signTransactionWithCosignatories( + aggregateTransaction, + cosigners.filter((a) => a !== signerAccount), + generationHash, + ); + let lockFundsTransaction: Transaction = LockFundsTransaction.create( + deadline, + currency.createRelative(10), + UInt64.fromUint(5760), + signedAggregateTransaction, + networkType, + defaultMaxFee, + ); + if (!providedMaxFee) { + lockFundsTransaction = lockFundsTransaction.setMaxFee(minFeeMultiplier); + } + const signedLockFundsTransaction = signerAccount.sign(lockFundsTransaction, generationHash); + if (!(await this.shouldAnnounce(lockFundsTransaction, signedLockFundsTransaction, ready, currency, nodeName))) { + return false; + } + if (!(await this.shouldAnnounce(aggregateTransaction, signedAggregateTransaction, ready, currency, nodeName))) { + return false; + } + + try { + logger.info(`Announcing ${this.getTransactionDescription(lockFundsTransaction, signedLockFundsTransaction, currency)}`); + await transactionService.announce(signedLockFundsTransaction, listener).toPromise(); + logger.info(`${this.getTransactionDescription(lockFundsTransaction, signedLockFundsTransaction, currency)} has been confirmed`); + + logger.info(`Announcing Bonded ${this.getTransactionDescription(aggregateTransaction, signedAggregateTransaction, currency)}`); + await transactionService.announceAggregateBonded(signedAggregateTransaction, listener).toPromise(); + logger.info(`${this.getTransactionDescription(aggregateTransaction, signedAggregateTransaction, currency)} has been announced`); + + logger.info('Aggregate Bonded Transaction has been confirmed! Your cosigners would need to cosign!'); + } catch (e) { + const message = + `Aggregate Bonded Transaction ${signedAggregateTransaction.type} ${ + signedAggregateTransaction.hash + } - signer ${signedAggregateTransaction.getSignerAddress().plain()} failed!! ` + e.message; + logger.error(message); + return false; + } + return true; + } + + private async announceAggregateComplete( + signer: Account, + transactionFactory: () => Transaction[], + deadline: Deadline, + networkType: NetworkType, + defaultMaxFee: UInt64, + providedMaxFee: number | undefined, + minFeeMultiplier: number, + generationHash: string, + currency: Currency, + transactionService: TransactionService, + listener: IListener, + ready: boolean | undefined, + nodeName: string, + requiredCosignatures?: number, + cosigners?: Account[], + ): Promise { + let aggregateTransaction = AggregateTransaction.createComplete(deadline, transactionFactory(), networkType, [], defaultMaxFee); + if (!providedMaxFee) { + aggregateTransaction = aggregateTransaction.setMaxFeeForAggregate(minFeeMultiplier, requiredCosignatures || 0); + } + const signedAggregateTransaction = cosigners + ? signer.signTransactionWithCosignatories( + aggregateTransaction, + cosigners.filter((a) => a !== signer), + generationHash, + ) + : signer.sign(aggregateTransaction, generationHash); + if (!(await this.shouldAnnounce(aggregateTransaction, signedAggregateTransaction, ready, currency, nodeName))) { + return false; + } + try { + logger.info(`Announcing ${this.getTransactionDescription(aggregateTransaction, signedAggregateTransaction, currency)}`); + await transactionService.announce(signedAggregateTransaction, listener).toPromise(); + logger.info(`${this.getTransactionDescription(aggregateTransaction, signedAggregateTransaction, currency)} has been confirmed`); + return true; + } catch (e) { + const message = + `Aggregate Complete Transaction ${signedAggregateTransaction.type} ${ + signedAggregateTransaction.hash + } - signer ${signedAggregateTransaction.getSignerAddress().plain()} failed!! ` + e.message; + logger.error(message); + return false; + } + } + + private async announceSimple( + signer: Account, + transaction: Transaction, + providedMaxFee: number | undefined, + minFeeMultiplier: number, + generationHash: string, + currency: Currency, + transactionService: TransactionService, + listener: IListener, + ready: boolean | undefined, + nodeName: string, + ): Promise { + if (!providedMaxFee) { + transaction = transaction.setMaxFee(minFeeMultiplier); + } + const signedTransaction = signer.sign(transaction, generationHash); + if (!(await this.shouldAnnounce(transaction, signedTransaction, ready, currency, nodeName))) { + return false; + } + try { + logger.info(`Announcing ${this.getTransactionDescription(transaction, signedTransaction, currency)}`); + await transactionService.announce(signedTransaction, listener).toPromise(); + logger.info(`${this.getTransactionDescription(transaction, signedTransaction, currency)} has been confirmed`); + return true; + } catch (e) { + const message = + `Simple Transaction ${signedTransaction.type} ${ + signedTransaction.hash + } - signer ${signedTransaction.getSignerAddress().plain()} failed!! ` + e.message; + logger.error(message); + return false; + } + } + + private getTransactionDescription(transaction: Transaction, signedTransaction: SignedTransaction, currency: Currency): string { + const aggTypeDescription = (type: TransactionType) => { + switch (type) { + case TransactionType.AGGREGATE_BONDED: + return '(Bonded)'; + case TransactionType.AGGREGATE_COMPLETE: + return '(Complete)'; + default: + return ''; + } + }; + return `${transaction.constructor.name + aggTypeDescription(transaction.type)} - Hash: ${signedTransaction.hash} - MaxFee ${ + transaction.maxFee.compact() / Math.pow(10, currency.divisibility) + }`; + } + + public async shouldAnnounce( + transaction: Transaction, + signedTransaction: SignedTransaction, + ready: boolean | undefined, + currency: Currency, + nodeName: string, + ): Promise { + const response: boolean = + ready || + ( + await prompt([ + { + name: 'value', + message: `Do you want to announce ${this.getTransactionDescription(transaction, signedTransaction, currency)}?`, + type: 'confirm', + default: true, + }, + ]) + ).value; + if (!response) { + logger.info(`Ignoring transaction for node[${nodeName}]`); + } + return response; + } + + private async getMultisigBestCosigner( + msigAccountInfo: MultisigAccountInfo, + cosigners: Account[], + accountName: string, + networkType: NetworkType, + repositoryFactory: RepositoryFactory, + currencyMosaicId: MosaicId | undefined, + ): Promise { + logger.info( + `${accountName} is a multisig account with Address: ${ + msigAccountInfo.minApproval + } min approval. Cosigners are: ${msigAccountInfo.cosignatoryAddresses + .map((a) => a.plain()) + .join( + ', ', + )}. The tool will ask for the cosigners provide keys in order to announce the transactions. These private keys are not stored anywhere!`, + ); + cosigners.push(...(await this.promptAccounts(networkType, msigAccountInfo.cosignatoryAddresses, msigAccountInfo.minApproval))); + if (!cosigners.length) { + return undefined; + } + return await this.getBestCosigner(repositoryFactory, cosigners, currencyMosaicId); + } } diff --git a/src/service/BootstrapService.ts b/src/service/BootstrapService.ts index 62e535d10..272d8733a 100644 --- a/src/service/BootstrapService.ts +++ b/src/service/BootstrapService.ts @@ -19,8 +19,8 @@ import { BootstrapUtils } from './BootstrapUtils'; import { ComposeParams, ComposeService } from './ComposeService'; import { ConfigParams, ConfigResult, ConfigService } from './ConfigService'; import { LinkParams, LinkService } from './LinkService'; +import { ModifyMultisigParams, ModifyMultisigService } from './ModifyMultisigService'; import { ReportParams, ReportService } from './ReportService'; -import { RewardProgramParams, RewardProgramService } from './RewardProgramService'; import { RunParams, RunService } from './RunService'; export type StartParams = ConfigParams & ComposeParams & RunParams; @@ -40,6 +40,15 @@ export class BootstrapService { return new ConfigService(this.root, config).run(); } + /** + * It resolves the preset used for preventive configuration. + * + * @param config the params of the config command. + */ + public resolveConfigPreset(config: ConfigParams = ConfigService.defaultParams): ConfigPreset { + return new ConfigService(this.root, config).resolveConfigPreset(false); + } + /** * It generates the docker-compose.yaml file from the previously generated configuration. * @@ -76,18 +85,19 @@ export class BootstrapService { } /** - * It calls a running service announcing the registration of the nodes to the supernode rewards program. + * It converts main account into multisig account or modifies multisig structure * * @param config the params passed * @param passedPresetData the created preset if you know it, otherwise will load the latest one resolved from the target folder. * @param passedAddresses the created addresses if you know it, otherwise will load the latest one resolved from the target folder. */ - public async enrollRewardProgram( - config: RewardProgramParams = RewardProgramService.defaultParams, + + public async modifyMultisig( + config: ModifyMultisigParams = ModifyMultisigService.defaultParams, passedPresetData?: ConfigPreset | undefined, passedAddresses?: Addresses | undefined, ): Promise { - await new RewardProgramService(config).enroll(passedPresetData, passedAddresses); + await new ModifyMultisigService(config).run(passedPresetData, passedAddresses); } /** diff --git a/src/service/BootstrapUtils.ts b/src/service/BootstrapUtils.ts index a02bb43cd..821e4269f 100644 --- a/src/service/BootstrapUtils.ts +++ b/src/service/BootstrapUtils.ts @@ -31,7 +31,7 @@ import { import * as Handlebars from 'handlebars'; import { get } from 'https'; import * as _ from 'lodash'; -import { platform, totalmem } from 'os'; +import { totalmem } from 'os'; import { basename, dirname, join, resolve } from 'path'; import { Convert, DtoMapping, NetworkType } from 'symbol-sdk'; import * as util from 'util'; @@ -160,7 +160,7 @@ export class BootstrapUtils { }); }); - file.on('error', (err) => { + file.on('error', (err: any) => { file.close(); if (err.code === 'EEXIST') { reject(new Error('File already exists')); @@ -170,7 +170,7 @@ export class BootstrapUtils { } }); } else { - reject(new Error(`Server responded with ${response.statusCode}: ${response.statusMessage}`)); + reject(new Error(`Server responded with ${response.statusCode} ${response.statusMessage || ''}`.trim())); } }); @@ -183,7 +183,7 @@ export class BootstrapUtils { } public static logSameLineMessage(message: string): void { - process.stdout.write(platform() == 'win32' ? '\\033[0G' : '\r'); + process.stdout.write(BootstrapUtils.isWindows() ? '\x1b[0G' : '\r'); process.stdout.write(message); } @@ -302,8 +302,10 @@ export class BootstrapUtils { public static sleep(ms: number): Promise { // Create a promise that rejects in milliseconds - return new Promise((resolve) => { + return new Promise((resolve) => { setTimeout(() => { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore resolve(); }, ms); }); @@ -396,8 +398,18 @@ export class BootstrapUtils { // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types public static runTemplate(template: string, templateContext: any): string { - const compiledTemplate = Handlebars.compile(template); - return compiledTemplate(templateContext); + try { + const compiledTemplate = Handlebars.compile(template); + return compiledTemplate(templateContext); + } catch (e) { + const securedTemplate = BootstrapUtils.secureString(template); + const securedContext = BootstrapUtils.secureString(BootstrapUtils.toYaml(templateContext)); + const securedMessage = BootstrapUtils.secureString(e.message || 'Unknown'); + + const message = `Unknown error rendering template. Error: ${securedMessage}\nTemplate:\n${securedTemplate}.`; + logger.error(`${message}\nContext: \n${securedContext}`); + throw new Error(message); + } } public static async mkdir(path: string): Promise { @@ -659,10 +671,16 @@ export class BootstrapUtils { } public static toHex(renderedText: string): string { + if (!renderedText) { + return ''; + } const numberAsString = BootstrapUtils.toSimpleHex(renderedText); return '0x' + (numberAsString.match(/\w{1,4}(?=(\w{4})*$)/g) || [numberAsString]).join("'"); } public static toSimpleHex(renderedText: string): string { + if (!renderedText) { + return ''; + } return renderedText.toString().split("'").join('').replace(/^(0x)/, ''); } @@ -673,7 +691,11 @@ export class BootstrapUtils { public static formatJson(string: string): string { // Validates and format the json string. - return JSON.stringify(JSON.parse(string), null, 2); + try { + return JSON.stringify(JSON.parse(string), null, 2); + } catch (e) { + throw new Error(`${e.message}:JSON\n ${string}`); + } } public static splitCsv(object: string): string[] { @@ -713,37 +735,15 @@ export class BootstrapUtils { } public static getNetworkIdentifier(networkType: NetworkType): string { - switch (networkType) { - case NetworkType.MAIN_NET: - return 'public'; - case NetworkType.TEST_NET: - return 'public-test'; - case NetworkType.MIJIN: - return 'mijin'; - case NetworkType.MIJIN_TEST: - return 'mijin-test'; - case NetworkType.PRIVATE: - return 'private'; - case NetworkType.PRIVATE_TEST: - return 'private-test'; - } - throw new Error(`Invalid Network Type ${networkType}`); + return BootstrapUtils.getNetworkName(networkType); } public static getNetworkName(networkType: NetworkType): string { switch (networkType) { case NetworkType.MAIN_NET: - return 'public'; + return 'mainnet'; case NetworkType.TEST_NET: - return 'publicTest'; - case NetworkType.MIJIN: - return 'mijin'; - case NetworkType.MIJIN_TEST: - return 'mijinTest'; - case NetworkType.PRIVATE: - return 'private'; - case NetworkType.PRIVATE_TEST: - return 'privateTest'; + return 'testnet'; } throw new Error(`Invalid Network Type ${networkType}`); } diff --git a/src/service/CommandUtils.ts b/src/service/CommandUtils.ts index f1567a2a6..7304ef95e 100644 --- a/src/service/CommandUtils.ts +++ b/src/service/CommandUtils.ts @@ -142,4 +142,12 @@ export class CommandUtils { if (log) logger.info(`Password has been provided`); return providedPassword; } + + /** + * Returns account details formatted (ready to print) + */ + public static formatAccount(account: PublicAccount, wrapped = true): string { + const log = `Address: ${account.address.plain()}`; + return wrapped ? `[${log}]` : log; + } } diff --git a/src/service/ComposeService.ts b/src/service/ComposeService.ts index 70b73e400..1a597cc53 100644 --- a/src/service/ComposeService.ts +++ b/src/service/ComposeService.ts @@ -23,7 +23,7 @@ import LoggerFactory from '../logger/LoggerFactory'; import { Addresses, ConfigPreset, DockerCompose, DockerComposeService, DockerServicePreset } from '../model'; import { BootstrapUtils } from './BootstrapUtils'; import { ConfigLoader } from './ConfigLoader'; -// eslint-disable-next-line @typescript-eslint/no-var-requires + export type ComposeParams = { target: string; user?: string; upgrade?: boolean; password?: string }; const logger: Logger = LoggerFactory.getLogger(LogType.System); @@ -109,56 +109,29 @@ export class ComposeService { }); }; + const resolveHttpsProxyDomains = (fromDomain: string, toDomain: string): string => { + return `${fromDomain} -> ${toDomain}`; + }; + const resolveService = async ( servicePreset: DockerServicePreset, rawService: DockerComposeService, ): Promise => { - if (false) { - // POC about creating custom aws images. - const serviceName = rawService.container_name; - const volumes = rawService.volumes || []; - const image = rawService.image; - const repository = 'nem-repository'; - const dockerfileContent = `FROM docker.io/${image}\n\n${volumes - .map((v) => { - const parts = v.split(':'); - return `ADD ${parts[0].replace('../', '').replace('./', 'docker/')} ${parts[1]}`; - }) - .join('\n')}\n`; - const dockerFile = join(target, 'Dockerfile-' + serviceName); - await BootstrapUtils.writeTextFile(dockerFile, dockerfileContent); - await Promise.all( - volumes.map(async (v) => { - const parts = v.split(':'); - await BootstrapUtils.mkdir(join(targetDocker, parts[0])); - }), - ); - const generatedImageName = repository + ':' + serviceName; - await BootstrapUtils.createImageUsingExec(target, dockerFile, generatedImageName); - - // const awsUserId = '172617417348'; - // aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 172617417348.dkr.ecr.us-east-1.amazonaws.com - // const absoluteImageUrl = `${awsUserId}.dkr.ecr.us-east-1.amazonaws.com/${generatedImageName}`; - // await BootstrapUtils.exec(`docker tag ${generatedImageName} ${absoluteImageUrl}`); - - return { ...rawService, image: generatedImageName, volumes: undefined }; - } else { - const service = { ...rawService }; - if (servicePreset.host || servicePreset.ipv4_address) { - service.networks = { default: {} }; - } - if (servicePreset.host) { - service.hostname = servicePreset.host; - service.networks!.default.aliases = [servicePreset.host]; - } - if (servicePreset.environment) { - service.environment = { ...servicePreset.environment, ...rawService.environment }; - } - if (servicePreset.ipv4_address) { - service.networks!.default.ipv4_address = servicePreset.ipv4_address; - } - return service; + const service = { ...rawService }; + if (servicePreset.host || servicePreset.ipv4_address) { + service.networks = { default: {} }; + } + if (servicePreset.host) { + service.hostname = servicePreset.host; + service.networks!.default.aliases = [servicePreset.host]; + } + if (servicePreset.environment) { + service.environment = { ...servicePreset.environment, ...rawService.environment }; + } + if (servicePreset.ipv4_address) { + service.networks!.default.ipv4_address = servicePreset.ipv4_address; } + return service; }; await Promise.all( @@ -262,51 +235,13 @@ export class ComposeService { ), ); } - - if (n.rewardProgram) { - const volumes = [vol(`../${targetNodesFolder}/${n.name}/agent`, nodeWorkingDirectory, false)]; - - const rewardProgramAgentCommand = `/app/agent-linux.bin --config agent.properties`; - services.push( - await resolveService( - { - ipv4_address: n.rewardProgramAgentIpv4_address, - openPort: n.rewardProgramAgentOpenPort, - excludeDockerService: n.rewardProgramAgentExcludeDockerService, - host: n.rewardProgramAgentHost, - }, - { - user: user, - container_name: n.name + '-agent', - image: presetData.symbolAgentImage, - working_dir: nodeWorkingDirectory, - entrypoint: rewardProgramAgentCommand, - ports: resolvePorts([ - { - internalPort: n.rewardProgramAgentPort || presetData.rewardProgramAgentPort, - openPort: _.isUndefined(n.rewardProgramAgentOpenPort) ? true : n.rewardProgramAgentOpenPort, - }, - ]), - stop_signal: 'SIGINT', - restart: restart, - volumes: volumes, - ...this.resolveDebugOptions( - presetData.dockerComposeDebugMode, - n.rewardProgramAgentDockerComposeDebugMode, - ), - ...n.rewardProgramAgentCompose, - }, - ), - ); - } }), ); - + const restInternalPort = 3000; // Move to shared? await Promise.all( (presetData.gateways || []) .filter((d) => !d.excludeDockerService) .map(async (n) => { - const internalPort = 3000; const volumes = [vol(`../${targetGatewaysFolder}/${n.name}`, nodeWorkingDirectory, false)]; services.push( await resolveService(n, { @@ -316,7 +251,7 @@ export class ComposeService { command: 'npm start --prefix /app/catapult-rest/rest /symbol-workdir/rest.json', stop_signal: 'SIGINT', working_dir: nodeWorkingDirectory, - ports: resolvePorts([{ internalPort: internalPort, openPort: n.openPort }]), + ports: resolvePorts([{ internalPort: restInternalPort, openPort: n.openPort }]), restart: restart, volumes: volumes, depends_on: [n.databaseHost], @@ -327,6 +262,47 @@ export class ComposeService { }), ); + await Promise.all( + (presetData.httpsProxies || []) + .filter((d) => !d.excludeDockerService) + .map(async (n) => { + const internalPort = 443; + const host = n.host || presetData.nodes?.[0]?.host; + if (!host) { + throw new Error( + `HTTPS Proxy ${n.name} is invalid, 'host' property could not be resolved. It must be set to a valid DNS record.`, + ); + } + const domains: string | undefined = + n.domains || + presetData.gateways?.map((g) => resolveHttpsProxyDomains(host, `http://${g.name}:${restInternalPort}`))[0]; + if (!domains) { + throw new Error(`HTTPS Proxy ${n.name} is invalid, 'domains' property could not be resolved!`); + } + services.push( + await resolveService(n, { + container_name: n.name, + image: presetData.httpsPortalImage, + stop_signal: 'SIGINT', + ports: resolvePorts([ + { internalPort: 80, openPort: true }, + { internalPort: internalPort, openPort: n.openPort }, + ]), + environment: { + DOMAINS: domains, + WEBSOCKET: n.webSocket, + STAGE: n.stage, + SERVER_NAMES_HASH_BUCKET_SIZE: n.serverNamesHashBucketSize, + }, + restart: restart, + depends_on: [presetData.gateways![0].name], + ...this.resolveDebugOptions(presetData.dockerComposeDebugMode, n.dockerComposeDebugMode), + ...n.compose, + }), + ); + }), + ); + await Promise.all( (presetData.wallets || []) .filter((d) => !d.excludeDockerService) @@ -356,14 +332,15 @@ export class ComposeService { vol(`../${targetExplorersFolder}/${n.name}`, nodeWorkingDirectory, true), vol(`./explorer`, nodeCommandsDirectory, true), ]; + const entrypoint = `ash -c "/bin/ash ${nodeCommandsDirectory}/run.sh ${n.name}"`; services.push( await resolveService(n, { container_name: n.name, image: presetData.symbolExplorerImage, - command: `ash -c "/bin/ash ${nodeCommandsDirectory}/run.sh ${n.name}"`, + entrypoint: entrypoint, stop_signal: 'SIGINT', working_dir: nodeWorkingDirectory, - ports: resolvePorts([{ internalPort: 80, openPort: n.openPort }]), + ports: resolvePorts([{ internalPort: 4000, openPort: n.openPort }]), restart: restart, volumes: volumes, ...this.resolveDebugOptions(presetData.dockerComposeDebugMode, n.dockerComposeDebugMode), diff --git a/src/service/ConfigLoader.ts b/src/service/ConfigLoader.ts index ab679df3e..37b6c3339 100644 --- a/src/service/ConfigLoader.ts +++ b/src/service/ConfigLoader.ts @@ -60,12 +60,23 @@ export class ConfigLoader { if (!presetData.harvestNetworkFeeSinkAddress) { presetData.harvestNetworkFeeSinkAddress = addresses.sinkAddress; } + if (!presetData.harvestNetworkFeeSinkAddressV1) { + presetData.harvestNetworkFeeSinkAddressV1 = presetData.harvestNetworkFeeSinkAddress; + } + if (!presetData.mosaicRentalFeeSinkAddress) { presetData.mosaicRentalFeeSinkAddress = addresses.sinkAddress; } + if (!presetData.mosaicRentalFeeSinkAddressV1) { + presetData.mosaicRentalFeeSinkAddressV1 = presetData.mosaicRentalFeeSinkAddress; + } + if (!presetData.namespaceRentalFeeSinkAddress) { presetData.namespaceRentalFeeSinkAddress = addresses.sinkAddress; } + if (!presetData.namespaceRentalFeeSinkAddressV1) { + presetData.namespaceRentalFeeSinkAddressV1 = presetData.namespaceRentalFeeSinkAddress; + } presetData.networkIdentifier = BootstrapUtils.getNetworkIdentifier(presetData.networkType); presetData.networkName = BootstrapUtils.getNetworkName(presetData.networkType); @@ -204,7 +215,7 @@ export class ConfigLoader { const newAccount = this.getAccount(networkType, publicKey?.toUpperCase(), privateKey?.toUpperCase()); const getAccountLog = (account: Account | PublicAccount) => - `${keyName} Account ${account.address.plain()} Public Ley ${account.publicKey} `; + `${keyName} Account ${account.address.plain()} Public Key ${account.publicKey} `; if (oldAccount && !newAccount) { logger.info(`Reusing ${getAccountLog(oldAccount)}...`); @@ -309,15 +320,7 @@ export class ConfigLoader { nodePreset.vrfPrivateKey, nodePreset.vrfPublicKey, ); - if (nodePreset.rewardProgram) - nodeAccount.agent = this.generateAccount( - networkType, - privateKeySecurityMode, - KeyName.Agent, - oldNodeAccount?.agent, - nodePreset.agentPrivateKey, - nodePreset.agentPublicKey, - ); + return nodeAccount; } @@ -364,9 +367,14 @@ export class ConfigLoader { public mergePresets(object: ConfigPreset, ...otherArgs: (CustomPreset | undefined)[]): any { const presets: (CustomPreset | undefined)[] = [object, ...otherArgs]; - const inflation: Record = presets.reverse().find((p) => p?.inflation)?.inflation || {}; + const reversed = _.reverse(presets); + const inflation = reversed.find((p) => p?.inflation)?.inflation || {}; + const knownRestGateways = reversed.find((p) => p?.knownRestGateways)?.knownRestGateways || []; + const knownPeers = reversed.find((p) => p?.knownPeers)?.knownPeers || []; const presetData = _.merge(object, ...otherArgs); presetData.inflation = inflation; + presetData.knownRestGateways = knownRestGateways; + presetData.knownPeers = knownPeers; return presetData; } diff --git a/src/service/ConfigService.ts b/src/service/ConfigService.ts index 50555f1e8..3f0277346 100644 --- a/src/service/ConfigService.ts +++ b/src/service/ConfigService.ts @@ -24,6 +24,7 @@ import { Convert, Deadline, LinkAction, + NamespaceId, Transaction, TransactionMapping, UInt64, @@ -33,8 +34,7 @@ import { import { LogType } from '../logger'; import Logger from '../logger/Logger'; import LoggerFactory from '../logger/LoggerFactory'; -import { Addresses, ConfigPreset, CustomPreset, GatewayConfigPreset, NodeAccount, NodePreset, NodeType } from '../model'; -import { AgentCertificateService } from './AgentCertificateService'; +import { Addresses, ConfigPreset, CustomPreset, GatewayConfigPreset, NodeAccount, PeerInfo } from '../model'; import { BootstrapUtils, KnownError, Password } from './BootstrapUtils'; import { CertificateService } from './CertificateService'; import { CommandUtils } from './CommandUtils'; @@ -43,7 +43,6 @@ import { CryptoUtils } from './CryptoUtils'; import { NemgenService } from './NemgenService'; import { RemoteNodeService } from './RemoteNodeService'; import { ReportService } from './ReportService'; -import { RewardProgramService } from './RewardProgramService'; import { VotingService } from './VotingService'; /** @@ -61,9 +60,9 @@ export enum KeyName { Transport = 'Transport', Voting = 'Voting', VRF = 'VRF', - Agent = 'Agent', NemesisSigner = 'Nemesis Signer', NemesisAccount = 'Nemesis Account', + ServiceProvider = 'Service Provider', } export interface ConfigParams { @@ -102,6 +101,16 @@ export class ConfigService { this.configLoader = new ConfigLoader(); } + public resolveConfigPreset(password: Password): ConfigPreset { + const target = this.params.target; + const presetLocation = this.configLoader.getGeneratedPresetLocation(target); + if (fs.existsSync(presetLocation) && !this.params.upgrade) { + return this.configLoader.loadExistingPresetData(target, password); + } + const oldPresetData = this.configLoader.loadExistingPresetDataIfPreset(target, password); + return this.resolveCurrentPresetData(oldPresetData, password); + } + public async run(): Promise { const target = this.params.target; try { @@ -124,6 +133,11 @@ export class ConfigService { } const oldPresetData = this.configLoader.loadExistingPresetDataIfPreset(target, password); + if (oldPresetData) { + // HACK! https://github.com/symbol/symbol-bootstrap/pull/270 would fix this! + delete oldPresetData.knownPeers; + delete oldPresetData.knownRestGateways; + } const oldAddresses = this.configLoader.loadExistingAddressesIfPreset(target, password); if (oldAddresses && !oldPresetData) { @@ -144,13 +158,14 @@ export class ConfigService { const privateKeySecurityMode = CryptoUtils.getPrivateKeySecurityMode(presetData.privateKeySecurityMode); await BootstrapUtils.mkdir(target); + const remoteNodeService = new RemoteNodeService(presetData, this.params.offline); + this.cleanUpConfiguration(presetData); await this.generateNodeCertificates(presetData, addresses); - await this.generateAgentCertificates(presetData, addresses); - await this.generateNodes(presetData, addresses); + await this.generateNodes(presetData, addresses, remoteNodeService); await this.generateGateways(presetData); - await this.generateExplorers(presetData); - await this.generateWallets(presetData); + await this.generateExplorers(presetData, remoteNodeService); + await this.generateWallets(presetData, remoteNodeService); const isUpgrade = !!oldPresetData || !!oldAddresses; await this.resolveNemesis(presetData, addresses, isUpgrade); await this.copyNemesis(addresses); @@ -246,22 +261,35 @@ export class ConfigService { throw new Error('Seed could not be found!!!!'); } - private async generateNodes(presetData: ConfigPreset, addresses: Addresses): Promise { - const currentFinalizationEpoch = this.params.offline - ? presetData.lastKnownNetworkEpoch - : await new RemoteNodeService().resolveCurrentFinalizationEpoch(presetData); + private async generateNodes(presetData: ConfigPreset, addresses: Addresses, remoteNodeService: RemoteNodeService): Promise { + const currentFinalizationEpoch = await remoteNodeService.resolveCurrentFinalizationEpoch(); + const externalPeers: PeerInfo[] = await remoteNodeService.getPeerInfos(); + const localPeers: PeerInfo[] = (presetData.nodes || []).map((nodePresetData, index) => { + const node = (addresses.nodes || [])[index]; + return { + publicKey: node.main.publicKey, + endpoint: { + host: nodePresetData.host || '', + port: 7900, + }, + metadata: { + name: nodePresetData.friendlyName || '', + roles: ConfigLoader.resolveRoles(nodePresetData), + }, + }; + }); + const allPeers = _.uniqBy([...externalPeers, ...localPeers], (p) => p.publicKey); await Promise.all( - (addresses.nodes || []).map( - async (account, index) => - await this.generateNodeConfiguration(account, index, presetData, addresses, currentFinalizationEpoch), + (addresses.nodes || []).map((account, index) => + this.generateNodeConfiguration(account, index, presetData, currentFinalizationEpoch, allPeers), ), ); } private async generateNodeCertificates(presetData: ConfigPreset, addresses: Addresses): Promise { await Promise.all( - (addresses.nodes || []).map(async (account) => { - return await new CertificateService(this.root, this.params).run( + (addresses.nodes || []).map((account) => { + return new CertificateService(this.root, this.params).run( presetData.networkType, presetData.symbolServerImage, account.name, @@ -274,29 +302,12 @@ export class ConfigService { ); } - private async generateAgentCertificates(presetData: ConfigPreset, addresses: Addresses): Promise { - await Promise.all( - (addresses.nodes || []).map(async (account, index) => { - const node = presetData.nodes?.[index]; - if (node?.rewardProgram && account.agent) - await new AgentCertificateService(this.root, this.params).run( - presetData.networkType, - presetData.symbolServerImage, - account.name, - { - agent: account.agent, - }, - ); - }), - ); - } - private async generateNodeConfiguration( account: NodeAccount, index: number, presetData: ConfigPreset, - addresses: Addresses, currentFinalizationEpoch: number | undefined, + knownPeers: PeerInfo[], ) { const copyFrom = join(this.root, 'config', 'node'); const name = account.name; @@ -345,29 +356,6 @@ export class ConfigService { excludeFiles.push('config-networkheight.properties'); } - if (nodePreset.rewardProgram) { - if (!nodePreset.host) { - throw new Error( - `Cannot create reward program configuration. You need to provide a host field in preset: ${nodePreset.name}`, - ); - } - const restService = presetData.gateways?.find((g) => g.apiNodeName == nodePreset.name); - if (!restService) { - throw new Error( - `Cannot create reward program configuration. There is not rest gateway for the api node: ${nodePreset.name}`, - ); - } - - const rewardProgram = RewardProgramService.getRewardProgram(nodePreset.rewardProgram); - templateContext.restGatewayUrl = nodePreset.restGatewayUrl || `http://${restService.host || nodePreset.host}:3000`; - templateContext.rewardProgram = rewardProgram; - templateContext.serverVersion = nodePreset.serverVersion || presetData.serverVersion; - templateContext.mainPublicKey = account.main.publicKey; - const copyFrom = join(this.root, 'config', 'agent'); - const agentConfig = BootstrapUtils.getTargetNodesFolder(this.params.target, false, name, 'agent'); - await BootstrapUtils.generateConfiguration(templateContext, copyFrom, agentConfig, []); - } - const serverRecoveryConfig = { addressextractionRecovery: false, mongoRecovery: false, @@ -386,25 +374,29 @@ export class ConfigService { logger.info(`Generating ${name} server configuration`); await BootstrapUtils.generateConfiguration({ ...serverRecoveryConfig, ...templateContext }, copyFrom, serverConfig, excludeFiles); + + const isApi = (nodePresetData: PeerInfo): boolean => nodePresetData.metadata.roles.includes('Api'); + const peers = knownPeers.filter((peer) => isApi(peer) && peer.publicKey != account.main.publicKey); const peersP2PFile = await this.generateP2PFile( - presetData, - addresses, + peers, presetData.peersP2PListLimit, serverConfig, - NodeType.PEER_NODE, - (nodePresetData) => !!nodePresetData.syncsource && nodePresetData != nodePreset, + `this file contains a list of peers`, 'peers-p2p.json', ); + + const apiPeers = knownPeers.filter((peer) => !isApi(peer) && peer.publicKey != account.main.publicKey); const peersApiFile = await this.generateP2PFile( - presetData, - addresses, + apiPeers, presetData.peersApiListLimit, serverConfig, - NodeType.API_NODE, - (nodePresetData) => nodePresetData.api && nodePresetData != nodePreset, + `this file contains a list of api peers`, 'peers-api.json', ); + if (!peers.length && !apiPeers.length) { + logger.warn('The peer lists could not be resolved. peers-p2p.json and peers-api.json are empty!'); + } if (nodePreset.brokerName) { logger.info(`Generating ${nodePreset.brokerName} broker configuration`); await BootstrapUtils.generateConfiguration( @@ -427,38 +419,10 @@ export class ConfigService { ); } - private async generateP2PFile( - presetData: ConfigPreset, - addresses: Addresses, - listLimit: number, - outputFolder: string, - type: NodeType, - nodePresetDataFunction: (nodePresetData: NodePreset) => boolean, - jsonFileName: string, - ) { - const thisNetworkKnownPeers = (presetData.nodes || []) - .map((nodePresetData, index) => { - if (!nodePresetDataFunction(nodePresetData)) { - return undefined; - } - const node = (addresses.nodes || [])[index]; - return { - publicKey: node.main.publicKey, - endpoint: { - host: nodePresetData.host || '', - port: 7900, - }, - metadata: { - name: nodePresetData.friendlyName, - roles: ConfigLoader.resolveRoles(nodePresetData), - }, - }; - }) - .filter((i) => i); - const globalKnownPeers = presetData.knownPeers?.[type] || []; + private async generateP2PFile(knownPeers: PeerInfo[], listLimit: number, outputFolder: string, info: string, jsonFileName: string) { const data = { - _info: `this file contains a list of ${type} peers`, - knownPeers: _.sampleSize([...thisNetworkKnownPeers, ...globalKnownPeers], listLimit), + _info: info, + knownPeers: _.sampleSize(knownPeers, listLimit), }; const peerFile = join(outputFolder, `resources`, jsonFileName); await fs.promises.writeFile(peerFile, JSON.stringify(data, null, 2)); @@ -681,15 +645,58 @@ export class ConfigService { [], ['node.crt.pem', 'node.key.pem', 'ca.cert.pem'], ); + + if (gatewayPreset.restProtocol === 'HTTPS') { + if (gatewayPreset.restSSLKeyBase64 && gatewayPreset.restSSLCertificateBase64) { + fs.writeFileSync(join(moveTo, presetData.restSSLKeyFileName), gatewayPreset.restSSLKeyBase64, 'base64'); + fs.writeFileSync( + join(moveTo, presetData.restSSLCertificateFileName), + gatewayPreset.restSSLCertificateBase64, + 'base64', + ); + } else { + if ( + !existsSync(join(moveTo, presetData.restSSLKeyFileName)) && + !existsSync(join(moveTo, presetData.restSSLCertificateFileName)) + ) { + throw new KnownError( + `Native SSL is enabled but restSSLKeyBase64 or restSSLCertificateBase64 properties are not found in the custom-preset file! Either use 'symbol-bootstrap wizard' command to fill those properties in the custom-preset or make sure you copy your SSL key and cert files to ${moveTo} folder.`, + ); + } else { + logger.info( + `Native SSL certificates for gateway ${gatewayPreset.name} have been previously provided. Reusing...`, + ); + } + } + } }), ); } - private generateExplorers(presetData: ConfigPreset) { + private resolveCurrencyName(presetData: ConfigPreset): string { + const mosaicPreset = presetData.nemesis?.mosaics?.[0]; + const currencyName = mosaicPreset?.name || presetData.currencyName; + if (!currencyName) { + throw new Error('Currency name could not be resolved!!'); + } + return currencyName; + } + + private generateExplorers(presetData: ConfigPreset, remoteNodeService: RemoteNodeService) { return Promise.all( (presetData.explorers || []).map(async (explorerPreset, index: number) => { const copyFrom = join(this.root, 'config', 'explorer'); - const templateContext = { ...presetData, ...explorerPreset }; + const fullName = `${presetData.baseNamespace}.${this.resolveCurrencyName(presetData)}`; + const namespaceId = new NamespaceId(fullName); + const { restNodes, defaultNode } = await this.resolveRests(presetData, remoteNodeService); + const templateContext = { + namespaceName: fullName, + namespaceId: namespaceId.toHex(), + restNodes: restNodes, + defaultNode: defaultNode, + ...presetData, + ...explorerPreset, + }; const name = templateContext.name || `explorer-${index}`; const moveTo = BootstrapUtils.getTargetFolder(this.params.target, false, BootstrapUtils.targetExplorersFolder, name); await BootstrapUtils.generateConfiguration(templateContext, copyFrom, moveTo); @@ -697,11 +704,21 @@ export class ConfigService { ); } - private generateWallets(presetData: ConfigPreset) { + private generateWallets(presetData: ConfigPreset, remoteNodeService: RemoteNodeService) { return Promise.all( - (presetData.wallets || []).map(async (explorerPreset, index: number) => { + (presetData.wallets || []).map(async (walletPreset, index: number) => { const copyFrom = join(this.root, 'config', 'wallet'); - const templateContext = { ...presetData, ...explorerPreset }; + const { restNodes, defaultNode } = await this.resolveRests(presetData, remoteNodeService); + const templateContext = { + namespaceName: `${presetData.baseNamespace}.${this.resolveCurrencyName(presetData)}`, + defaultNodeUrl: defaultNode, + restNodes: restNodes.map((url) => { + return { url: url, roles: 2, friendlyName: new URL(url).hostname }; + }), + ...presetData, + ...walletPreset, + }; + const name = templateContext.name || `wallet-${index}`; const moveTo = BootstrapUtils.getTargetFolder(this.params.target, false, BootstrapUtils.targetWalletsFolder, name); await BootstrapUtils.generateConfiguration(templateContext, copyFrom, moveTo); @@ -710,7 +727,7 @@ export class ConfigService { await fsPromises.chmod(join(moveTo, 'network.conf.js'), 0o777); await fsPromises.chmod(join(moveTo, 'profileImporter.html'), 0o777); await Promise.all( - (explorerPreset.profiles || []).map(async (profile) => { + (walletPreset.profiles || []).map(async (profile) => { if (!profile.name) { throw new Error('Profile`s name must be provided in the wallets preset when creating wallet profiles.'); } @@ -739,6 +756,19 @@ export class ConfigService { ); } + private async resolveRests( + presetData: ConfigPreset, + remoteNodeService: RemoteNodeService, + ): Promise<{ restNodes: string[]; defaultNode: string }> { + const restNodes: string[] = []; + presetData.gateways?.forEach((restService) => { + const nodePreset = presetData.nodes?.find((g) => g.name == restService.apiNodeName); + restNodes.push(`http://${restService.host || nodePreset?.host || 'localhost'}:3000`); + }); + restNodes.push(...(await remoteNodeService.getRestUrls())); + return { restNodes: _.uniq(restNodes), defaultNode: restNodes[0] || 'http://localhost:3000' }; + } + private cleanUpConfiguration(presetData: ConfigPreset) { const target = this.params.target; (presetData.nodes || []).forEach(({ name }) => { @@ -757,7 +787,10 @@ export class ConfigService { }); (presetData.gateways || []).forEach(({ name }) => { const configFolder = BootstrapUtils.getTargetGatewayFolder(target, false, name); - BootstrapUtils.deleteFolder(configFolder); + BootstrapUtils.deleteFolder(configFolder, [ + join(configFolder, presetData.restSSLKeyFileName), + join(configFolder, presetData.restSSLCertificateFileName), + ]); }); } } diff --git a/src/service/CryptoUtils.ts b/src/service/CryptoUtils.ts index b1aaeef1f..464b3f04e 100644 --- a/src/service/CryptoUtils.ts +++ b/src/service/CryptoUtils.ts @@ -20,6 +20,7 @@ import { KnownError } from './BootstrapUtils'; export class CryptoUtils { private static readonly ENCRYPT_PREFIX = 'ENCRYPTED:'; + private static readonly ENCRYPTABLE_KEYS = ['privateKey', 'restSSLKeyBase64']; // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types public static encrypt(value: any, password: string, fieldName?: string): any { @@ -34,7 +35,7 @@ export class CryptoUtils { return _.mapValues(value, (value: any, name: string) => CryptoUtils.encrypt(value, password, name)); } - if (this.isPrivateKeyField(value, fieldName)) { + if (this.isEncryptableKeyField(value, fieldName)) { return CryptoUtils.ENCRYPT_PREFIX + Crypto.encrypt(value, password); } return value; @@ -81,7 +82,7 @@ export class CryptoUtils { const isBlacklisted = !blacklistNames.length || blacklistNames.find((blacklistName) => name.toLowerCase().indexOf(blacklistName.toLowerCase()) > -1); - return !isBlacklisted || !this.isPrivateKeyField(value, name); + return !isBlacklisted || !this.isEncryptableKeyField(value, name); }), (value: any, name: string) => { const isBlacklisted = @@ -106,7 +107,7 @@ export class CryptoUtils { if (_.isObject(value)) { return _.mapValues(value, (value: any, name: string) => CryptoUtils.decrypt(value, password, name)); } - if (this.isPrivateKeyField(value, fieldName) && value.startsWith(CryptoUtils.ENCRYPT_PREFIX)) { + if (this.isEncryptableKeyField(value, fieldName) && value.startsWith(CryptoUtils.ENCRYPT_PREFIX)) { let decryptedValue; try { const encryptedValue = value.substring(CryptoUtils.ENCRYPT_PREFIX.length); @@ -134,13 +135,17 @@ export class CryptoUtils { if (_.isObject(value)) { return _.sum(Object.entries(value).map(([fieldName, value]) => this.encryptedCount(value, fieldName))); } - if (this.isPrivateKeyField(value, fieldName) && value.startsWith(CryptoUtils.ENCRYPT_PREFIX)) { + if (this.isEncryptableKeyField(value, fieldName) && value.startsWith(CryptoUtils.ENCRYPT_PREFIX)) { return 1; } return 0; } - private static isPrivateKeyField(value: any, fieldName: string | undefined) { - return _.isString(value) && fieldName && fieldName.toLowerCase().endsWith('privatekey'); + private static isEncryptableKeyField(value: any, fieldName: string | undefined) { + return ( + _.isString(value) && + fieldName && + CryptoUtils.ENCRYPTABLE_KEYS.some((key) => fieldName.toLowerCase().endsWith(key.toLowerCase())) + ); } } diff --git a/src/service/ForgeCertificateService.ts b/src/service/ForgeCertificateService.ts deleted file mode 100644 index d117e340d..000000000 --- a/src/service/ForgeCertificateService.ts +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2020 NEM - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import * as forge from 'node-forge'; -import { pki } from 'node-forge'; -import { join } from 'path'; -import { CertificatePair } from '../model'; -import { BootstrapUtils } from './BootstrapUtils'; - -// eslint-disable-next-line @typescript-eslint/no-var-requires -type CertificateParams = { target: string }; - -/** - * TODO remove if not used! - */ -export class ForgeCertificateService { - constructor(protected readonly params: CertificateParams) {} - - public async run(name: string): Promise { - // Currently the SSL certifcates are created via a docker image. Migrate this to a native forge! - // https://www.npmjs.com/package/node-forge - - const target = `${this.params.target}/config/${name}/resources/cert`; - await BootstrapUtils.mkdir(target); - - const caKeyPair = await this.createCaCertificate(target, 'ca', `${name}-account`); - await this.createNodeCertificate(target, 'node', name, caKeyPair); - return { privateKey: 'a', publicKey: 'b' }; - } - - public async createCaCertificate(target: string, prefix: string, name: string): Promise { - const keyPair = pki.rsa.generateKeyPair(); - const publicKeyPem = pki.publicKeyToPem(keyPair.publicKey); - await BootstrapUtils.writeTextFile(join(target, `${prefix}.pubkey.pem`), publicKeyPem); - // console.log(publicKeyPem); - - const privateKeyToPem = pki.privateKeyToPem(keyPair.privateKey); - await BootstrapUtils.writeTextFile(join(target, `${prefix}.key.pem`), privateKeyToPem); - - const cert = pki.createCertificate(); - cert.publicKey = keyPair.publicKey; - cert.serialNumber = forge.util.bytesToHex(forge.random.getBytesSync(20)); - cert.validity.notBefore = new Date(); - cert.validity.notAfter = new Date(); - cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 20); - - const attrs = [ - { - shortName: 'CN', - value: name, - }, - ]; - cert.setSubject(attrs); - cert.sign(keyPair.privateKey); - - // convert a Forge certificate to PEM - const pemCertificate = pki.certificateToPem(cert); - await BootstrapUtils.writeTextFile(join(target, `${prefix}.cert.pem`), pemCertificate); - - return keyPair; - } - - public async createNodeCertificate(target: string, prefix: string, name: string, caKeyPair: pki.KeyPair): Promise { - const keypair = pki.rsa.generateKeyPair(); - const publicKeyPem = pki.publicKeyToPem(keypair.publicKey); - await BootstrapUtils.writeTextFile(join(target, `${prefix}.pubkey.pem`), publicKeyPem); - // console.log(publicKeyPem); - - const privateKeyToPem = pki.privateKeyToPem(keypair.privateKey); - await BootstrapUtils.writeTextFile(join(target, `${prefix}.key.pem`), privateKeyToPem); - - const cert = pki.createCertificationRequest(); - cert.publicKey = keypair.publicKey; - cert.serialNumber = forge.util.bytesToHex(forge.random.getBytesSync(20)); - - const attrs = [ - { - shortName: 'CN', - value: name, - }, - ]; - cert.setSubject(attrs); - cert.sign(caKeyPair.privateKey); - - // convert a Forge certificate to PEM - const pemCertificate = pki.certificationRequestToPem(cert); - await BootstrapUtils.writeTextFile(join(target, `${prefix}.csr.pem`), pemCertificate); - - return { privateKey: privateKeyToPem, publicKey: publicKeyPem }; - } - - private createCertCommands(target: string): string { - return ` -cd ${target} -set -e -mkdir new_certs && chmod 700 new_certs -touch index.txt - -# create CA key -openssl genpkey -out ca.key.pem -outform PEM -algorithm ed25519 -openssl pkey -inform pem -in ca.key.pem -text -noout -openssl pkey -in ca.key.pem -pubout -out ca.pubkey.pem - -# create CA cert and self-sign it -openssl req -config ca.cnf -keyform PEM -key ca.key.pem -new -x509 -days 7300 -out ca.cert.pem -openssl x509 -in ca.cert.pem -text -noout - -# create node key -openssl genpkey -out node.key.pem -outform PEM -algorithm ed25519 -openssl pkey -inform pem -in node.key.pem -text -noout - -# create request -openssl req -config node.cnf -key node.key.pem -new -out node.csr.pem -openssl req -text -noout -verify -in node.csr.pem - -### below is done after files are written -# CA side -# create serial -openssl rand -hex 19 > ./serial.dat - -# sign cert for 375 days -openssl ca -batch -config ca.cnf -days 375 -notext -in node.csr.pem -out node.crt.pem -openssl verify -CAfile ca.cert.pem node.crt.pem - -# finally create full crt -cat node.crt.pem ca.cert.pem > node.full.crt.pem -`; - } -} diff --git a/src/service/LinkService.ts b/src/service/LinkService.ts index d7435ddba..f49da5279 100644 --- a/src/service/LinkService.ts +++ b/src/service/LinkService.ts @@ -46,6 +46,7 @@ export type LinkParams = { useKnownRestGateways: boolean; ready?: boolean; customPreset?: string; + serviceProviderPublicKey?: string; removeOldLinked?: boolean; //TEST ONLY! }; @@ -56,7 +57,7 @@ const logger: Logger = LoggerFactory.getLogger(LogType.System); export interface LinkServiceTransactionFactoryParams { presetData: ConfigPreset; nodeAccount: NodeAccount; - mainAccountInfo: AccountInfo; + mainAccountInfo?: AccountInfo; deadline: Deadline; maxFee: UInt64; latestFinalizedBlockEpoch?: number; @@ -99,6 +100,8 @@ export class LinkService implements TransactionFactory { this.configLoader.mergePresets(presetData, customPreset), addresses, this, + 'some', + this.params.serviceProviderPublicKey, ); } public async createTransactions({ @@ -110,6 +113,7 @@ export class LinkService implements TransactionFactory { latestFinalizedBlockEpoch, }: LinkServiceTransactionFactoryParams): Promise { const networkType = presetData.networkType; + const mainAccountAddress = nodeAccount.main.address; const nodeName = nodeAccount.name; const remoteTransactionFactory = ({ publicKey }: KeyAccount, action: LinkAction): AccountKeyLinkTransaction => @@ -129,13 +133,13 @@ export class LinkService implements TransactionFactory { ); }; - logger.info(`Creating transactions for node: ${nodeName}, ca/main account: ${mainAccountInfo.address.plain()}`); + logger.info(`Creating transactions for node: ${nodeName}, ca/main account: ${mainAccountAddress}`); const transactions = await new LinkTransactionGenericFactory(this.params).createGenericTransactions( nodeName, { - vrf: mainAccountInfo.supplementalPublicKeys.vrf, - remote: mainAccountInfo.supplementalPublicKeys.linked, - voting: mainAccountInfo.supplementalPublicKeys.voting, + vrf: mainAccountInfo?.supplementalPublicKeys.vrf, + remote: mainAccountInfo?.supplementalPublicKeys.linked, + voting: mainAccountInfo?.supplementalPublicKeys.voting || [], }, nodeAccount, latestFinalizedBlockEpoch || presetData.lastKnownNetworkEpoch, diff --git a/src/service/ModifyMultisigService.ts b/src/service/ModifyMultisigService.ts new file mode 100644 index 000000000..adefb11ca --- /dev/null +++ b/src/service/ModifyMultisigService.ts @@ -0,0 +1,261 @@ +/* + * Copyright 2020 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { prompt } from 'inquirer'; +import { + Address, + MultisigAccountInfo, + MultisigAccountModificationTransaction, + NetworkType, + Transaction, + UnresolvedAddress, +} from 'symbol-sdk'; +import { LogType } from '../logger'; +import Logger from '../logger/Logger'; +import LoggerFactory from '../logger/LoggerFactory'; +import { Addresses, ConfigPreset } from '../model'; +import { AnnounceService, TransactionFactory, TransactionFactoryParams } from './AnnounceService'; +import { BootstrapUtils } from './BootstrapUtils'; +import { ConfigLoader } from './ConfigLoader'; +import { TransactionUtils } from './TransactionUtils'; + +/** + * params necessary to announce multisig account modification transaction to network. + */ +export type ModifyMultisigParams = { + target: string; + password?: string; + url: string; + maxFee?: number; + useKnownRestGateways: boolean; + ready?: boolean; + customPreset?: string; + minRemovalDelta?: number; + minApprovalDelta?: number; + addressAdditions?: string; + addressDeletions?: string; + serviceProviderPublicKey?: string; +}; + +const logger: Logger = LoggerFactory.getLogger(LogType.System); + +export class ModifyMultisigService implements TransactionFactory { + public static readonly defaultParams: ModifyMultisigParams = { + target: BootstrapUtils.defaultTargetFolder, + useKnownRestGateways: false, + ready: false, + url: 'http://localhost:3000', + maxFee: 100000, + }; + + private readonly configLoader: ConfigLoader; + + constructor(protected readonly params: ModifyMultisigParams) { + this.configLoader = new ConfigLoader(); + } + + public async run(passedPresetData?: ConfigPreset | undefined, passedAddresses?: Addresses | undefined): Promise { + const presetData = passedPresetData ?? this.configLoader.loadExistingPresetData(this.params.target, this.params.password); + const addresses = passedAddresses ?? this.configLoader.loadExistingAddresses(this.params.target, this.params.password); + const customPreset = this.configLoader.loadCustomPreset(this.params.customPreset, this.params.password); + + await new AnnounceService().announce( + this.params.url, + this.params.maxFee, + this.params.useKnownRestGateways, + this.params.ready, + this.params.target, + this.configLoader.mergePresets(presetData, customPreset), + addresses, + this, + 'some', + this.params.serviceProviderPublicKey, + ); + } + public async createTransactions({ presetData, deadline, maxFee, mainAccount }: TransactionFactoryParams): Promise { + const networkType = presetData.networkType; + + const addressAdditions = await this.resolveAddressAdditions(networkType, this.params.addressAdditions); + const addressDeletions = await this.resolveAddressDeletions(networkType, this.params.addressDeletions); + const minApprovalDelta = await this.resolveMinApprovalDelta(this.params.minApprovalDelta); + const minRemovalDelta = await this.resolveMinRemovalDelta(this.params.minRemovalDelta); + + const url = this.params.url.replace(/\/$/, ''); + const repositoryFactory = await TransactionUtils.getRepositoryFactory( + presetData, + this.params.useKnownRestGateways ? undefined : url, + ); + const multisigInfo = await TransactionUtils.getMultisigAccount(repositoryFactory, mainAccount.address); + this.validateParams(addressAdditions, addressDeletions, minRemovalDelta, minApprovalDelta, multisigInfo); + + logger.info( + `Creating multisig account modification transaction [addressAdditions: "${addressAdditions + ?.map((a) => a.plain()) + .join(' , ')}", addressDeletions: "${addressDeletions + ?.map((a) => a.plain()) + .join(' , ')}", minApprovalDelta: ${minApprovalDelta}, minRemovalDelta: ${minRemovalDelta}]`, + ); + const multisigAccountModificationTransaction = MultisigAccountModificationTransaction.create( + deadline, + minApprovalDelta, + minRemovalDelta, + addressAdditions ? addressAdditions : [], + addressDeletions ? addressDeletions : [], + networkType, + maxFee, + ); + + return [multisigAccountModificationTransaction]; + } + + public async resolveMinRemovalDelta(delta?: number): Promise { + return this.resolveDelta('minRemovalDelta', 'Minimum removal delta:', delta); + } + + public async resolveMinApprovalDelta(delta?: number): Promise { + return this.resolveDelta('minApprovalDelta', 'Minimum approval delta:', delta); + } + + public async resolveDelta(name: string, message: string, delta?: number): Promise { + return delta !== undefined + ? delta + : ( + await prompt([ + { + name, + message, + type: 'number', + default: 0, + }, + ]) + )[name]; + } + + public async resolveAddressAdditions(networkType: NetworkType, cosigners?: string): Promise { + return this.resolveCosigners( + networkType, + 'addressAdditions', + 'Enter the cosignatory addresses to add (separated by a comma) :', + cosigners, + ); + } + + public async resolveAddressDeletions(networkType: NetworkType, cosigners?: string): Promise { + return this.resolveCosigners( + networkType, + 'addressDeletions', + 'Enter the cosignatory addresses to remove (separated by a comma) :', + cosigners, + ); + } + + public async resolveCosigners( + networkType: NetworkType, + name: string, + message: string, + cosigners?: string, + ): Promise { + const resolution = + cosigners !== undefined + ? cosigners + : ( + await prompt([ + { + name, + message, + }, + ]) + )[name]; + if (!resolution) { + return []; + } + const cosignatoryAddresses = resolution.split(','); + return this.toAddresses(networkType, cosignatoryAddresses); + } + + private toAddresses(networkType: NetworkType, addresses?: string[]): UnresolvedAddress[] { + return ( + addresses?.map((addressString) => { + return this.toAddress(addressString.trim(), networkType); + }) || [] + ); + } + private toAddress(addressString: string, networkType: NetworkType): Address { + if (!Address.isValidRawAddress(addressString)) { + throw new Error(`Address ${addressString} is not valid!`); + } + const address = Address.createFromRawAddress(addressString); + if (address.networkType !== networkType) { + throw new Error(`Address ${addressString} invalid network type. Expected ${networkType} but got ${address.networkType}`); + } + return address; + } + + protected validateParams( + addressAdditions?: UnresolvedAddress[], + addressDeletions?: UnresolvedAddress[], + minRemovalDelta?: number, + minApprovalDelta?: number, + currentMultisigInfo?: MultisigAccountInfo, + ): void { + // calculate new min approval + const newMinApproval = currentMultisigInfo ? currentMultisigInfo.minApproval + (minApprovalDelta || 0) : minApprovalDelta || 0; + + // calculate new min approval + const newMinRemoval = currentMultisigInfo ? currentMultisigInfo.minRemoval + (minRemovalDelta || 0) : minRemovalDelta || 0; + + // calculate the delta of added cosigners + const numberOfAddedCosigners = (addressAdditions?.length || 0) - (addressDeletions?.length || 0); + + const newCosignatoryNumber = currentMultisigInfo + ? currentMultisigInfo.cosignatoryAddresses.length + numberOfAddedCosigners + : numberOfAddedCosigners; + + for (const addressToAdd of addressAdditions || []) { + if (currentMultisigInfo?.cosignatoryAddresses.some((ca) => ca && ca.plain() === addressToAdd.plain())) { + throw new Error(`Cannot add cosignatory! ${addressToAdd.plain()} is already a cosignatory!`); + } + } + + for (const addressToRemove of addressDeletions || []) { + if (!currentMultisigInfo?.cosignatoryAddresses.some((ca) => ca && ca.plain() === addressToRemove.plain())) { + throw new Error(`Cannot remove cosignatory! ${addressToRemove.plain()} is not an actual cosignatory!`); + } + } + + if (newCosignatoryNumber < newMinApproval) { + throw new Error( + `There are ${ + newMinApproval - newCosignatoryNumber + } more required cosignatories than available cosignatories for min. approval. Please add cosignatories or reduce the min. approval delta.`, + ); + } + + if (newCosignatoryNumber < newMinRemoval) { + throw new Error( + `There are ${ + newMinRemoval - newCosignatoryNumber + } more required cosignatories than available cosignatories for min removal. Please add cosignatories or reduce the min. removal delta.`, + ); + } + + if (newCosignatoryNumber > 0 && (newMinApproval == 0 || newMinRemoval == 0)) { + throw new Error( + `Minimum approval and/or minimum removal cannot be set to 0 while there are ${newCosignatoryNumber} cosignatories in your list.`, + ); + } + } +} diff --git a/src/service/PortService.ts b/src/service/PortService.ts index 40a55e2b1..a3a4fe6a7 100644 --- a/src/service/PortService.ts +++ b/src/service/PortService.ts @@ -18,7 +18,7 @@ import * as net from 'net'; export class PortService { public static async isReachable(port: number, host: string, timeout = 1000): Promise { - const promise = new Promise((resolve, reject) => { + const promise = new Promise((resolve, reject) => { const socket = new net.Socket(); const onError = () => { diff --git a/src/service/RemoteNodeService.ts b/src/service/RemoteNodeService.ts index c52fb5f96..b6cf058e2 100644 --- a/src/service/RemoteNodeService.ts +++ b/src/service/RemoteNodeService.ts @@ -13,12 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import fetch from 'cross-fetch'; import { lookup } from 'dns'; -import { ChainInfo, RepositoryFactory, RepositoryFactoryHttp } from 'symbol-sdk'; +import { ChainInfo, RepositoryFactory, RepositoryFactoryHttp, RoleType } from 'symbol-sdk'; +import { Configuration, NodeApi, NodeListFilter, RequestContext, RestClientUtils } from 'symbol-statistics-service-typescript-fetch-client'; import { LogType } from '../logger'; import Logger from '../logger/Logger'; import LoggerFactory from '../logger/LoggerFactory'; -import { ConfigPreset } from '../model'; +import { ConfigPreset, PeerInfo } from '../model'; +import { KnownError } from './BootstrapUtils'; const logger: Logger = LoggerFactory.getLogger(LogType.System); @@ -28,20 +31,23 @@ export interface RepositoryInfo { chainInfo: ChainInfo; } export class RemoteNodeService { - public async resolveCurrentFinalizationEpoch(presetData: ConfigPreset): Promise { - const votingNode = presetData.nodes?.find((n) => n.voting); - if (!votingNode) { - return presetData.lastKnownNetworkEpoch; + constructor(private readonly presetData: ConfigPreset, private readonly offline: boolean | undefined) {} + private restUrls: string[] | undefined; + + public async resolveCurrentFinalizationEpoch(): Promise { + const votingNode = this.presetData.nodes?.find((n) => n.voting); + if (!votingNode || this.offline) { + return this.presetData.lastKnownNetworkEpoch; } - const remoteNodeService = new RemoteNodeService(); - if (!(await remoteNodeService.isConnectedToInternet())) { - return presetData.lastKnownNetworkEpoch; + if (!(await this.isConnectedToInternet())) { + return this.presetData.lastKnownNetworkEpoch; } - return (await remoteNodeService.getBestFinalizationEpoch(presetData.knownRestGateways)) || presetData.lastKnownNetworkEpoch; + const urls = await this.getRestUrls(); + return (await this.getBestFinalizationEpoch(urls)) || this.presetData.lastKnownNetworkEpoch; } - public async getBestFinalizationEpoch(urls: string[] | undefined): Promise { - if (!urls || !urls.length) { + public async getBestFinalizationEpoch(urls: string[]): Promise { + if (!urls.length) { return undefined; } const repositoryInfo = this.sortByHeight(await this.getKnownNodeRepositoryInfos(urls)).find((i) => i); @@ -52,7 +58,8 @@ export class RemoteNodeService { return finalizationEpoch; } - public async getBestRepositoryInfo(urls: string[]): Promise { + public async getBestRepositoryInfo(url: string | undefined): Promise { + const urls = url ? [url] : await this.getRestUrls(); const repositoryInfo = this.sortByHeight(await this.getKnownNodeRepositoryInfos(urls)).find((i) => i); if (!repositoryInfo) { throw new Error(`No up and running node could be found out of: \n - ${urls.join('\n - ')}`); @@ -88,6 +95,9 @@ export class RemoteNodeService { } private async getKnownNodeRepositoryInfos(urls: string[]): Promise { + if (!urls.length) { + throw new KnownError('There are not known nodes!'); + } logger.info(`Looking for the best node out of: \n - ${urls.join('\n - ')}`); return ( await Promise.all( @@ -102,7 +112,7 @@ export class RemoteNodeService { chainInfo, }; } catch (e) { - const message = `There has been an error talking to node ${restGatewayUrl}. Error: ${e.message}}`; + const message = `There has been an error talking to node ${restGatewayUrl}. Error: ${e.message}`; logger.warn(message); return undefined; } @@ -113,4 +123,105 @@ export class RemoteNodeService { .filter((i) => i) .map((i) => i as RepositoryInfo); } + + public async getRestUrls(): Promise { + if (this.restUrls) { + return this.restUrls; + } + const presetData = this.presetData; + const urls = [...(presetData.knownRestGateways || [])]; + const statisticsServiceUrl = presetData.statisticsServiceUrl; + if (statisticsServiceUrl && !this.offline) { + const client = this.createNodeApiRestClient(statisticsServiceUrl); + try { + const filter = presetData.statisticsServiceRestFilter as NodeListFilter; + const limit = presetData.statisticsServiceRestLimit; + const nodes = await client.getNodes(filter ? filter : undefined, limit); + urls.push(...nodes.map((n) => n.apiStatus?.restGatewayUrl).filter((url): url is string => !!url)); + } catch (e) { + logger.warn( + `There has been an error connecting to statistics ${statisticsServiceUrl}. Rest urls cannot be resolved! Error ${e.message}`, + ); + } + } + if (!urls) { + throw new Error('Rest URLS could not be resolved!'); + } + this.restUrls = urls; + return urls; + } + + /** + * Return user friendly role type list + * @param role combined node role types + */ + public static getNodeRoles(role: number): string { + const roles: string[] = []; + if ((RoleType.PeerNode.valueOf() & role) != 0) { + roles.push('Peer'); + } + if ((RoleType.ApiNode.valueOf() & role) != 0) { + roles.push('Api'); + } + if ((RoleType.VotingNode.valueOf() & role) != 0) { + roles.push('Voting'); + } + return roles.join(','); + } + + public async getPeerInfos(): Promise { + const presetData = this.presetData; + const statisticsServiceUrl = presetData.statisticsServiceUrl; + const knownPeers = [...(presetData.knownPeers || [])]; + if (statisticsServiceUrl && !this.offline) { + const client = this.createNodeApiRestClient(statisticsServiceUrl); + try { + const filter = presetData.statisticsServicePeerFilter as NodeListFilter; + const limit = presetData.statisticsServicePeerLimit; + const nodes = await client.getNodes(filter ? filter : undefined, limit); + const peerInfos = nodes + .map((n): PeerInfo | undefined => { + if (!n.peerStatus?.isAvailable || !n.publicKey || !n.port || !n.friendlyName || !n.roles) { + return undefined; + } + return { + publicKey: n.publicKey, + endpoint: { + host: n.host || '', + port: n.port, + }, + metadata: { + name: n.friendlyName, + roles: RemoteNodeService.getNodeRoles(n.roles), + }, + }; + }) + .filter((peerInfo): peerInfo is PeerInfo => !!peerInfo); + knownPeers.push(...peerInfos); + } catch (e) { + const error = await RestClientUtils.getErrorFromFetchResponse(e); + logger.warn( + `There has been an error connecting to statistics ${statisticsServiceUrl}. Peers cannot be resolved! Error ${error.message}`, + ); + } + } + return knownPeers; + } + + public createNodeApiRestClient(statisticsServiceUrl: string): NodeApi { + return new NodeApi( + new Configuration({ + fetchApi: fetch as any, + basePath: statisticsServiceUrl, + middleware: [ + { + pre: (context: RequestContext): Promise => { + logger.info(`Getting nodes information from ${context.url}`); + return Promise.resolve(); + }, + }, + ], + }), + ); + } } diff --git a/src/service/RewardProgramService.ts b/src/service/RewardProgramService.ts deleted file mode 100644 index bc55f6840..000000000 --- a/src/service/RewardProgramService.ts +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2020 NEM - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { readFileSync } from 'fs'; -import { join } from 'path'; -import { Address, Deadline, PlainMessage, Transaction, TransferTransaction, UInt64 } from 'symbol-sdk'; -import Logger from '../logger/Logger'; -import LoggerFactory from '../logger/LoggerFactory'; -import { Addresses, ConfigPreset, NodeAccount, NodePreset } from '../model'; -import { AnnounceService, TransactionFactory } from './AnnounceService'; -import { BootstrapUtils, KnownError } from './BootstrapUtils'; -import { ConfigLoader } from './ConfigLoader'; - -const logger: Logger = LoggerFactory.getLogger(); - -export type RewardProgramParams = { - target: string; - password?: string; - url: string; - maxFee?: number; - useKnownRestGateways: boolean; - ready?: boolean; - customPreset?: string; -}; - -export interface RewardProgramServiceTransactionFactoryParams { - presetData: ConfigPreset; - nodePreset: NodePreset; - nodeAccount: NodeAccount; - deadline: Deadline; - maxFee: UInt64; -} - -export enum RewardProgram { - EarlyAdoption = 'EarlyAdoption', - Ecosystem = 'Ecosystem', - SuperNode = 'SuperNode', - MonitorOnly = 'MonitorOnly', -} - -export class RewardProgramService implements TransactionFactory { - public static readonly defaultParams: RewardProgramParams = { - useKnownRestGateways: false, - target: BootstrapUtils.defaultTargetFolder, - url: 'http://localhost:3000', - }; - - private readonly configLoader: ConfigLoader; - - constructor(protected readonly params: RewardProgramParams) { - this.configLoader = new ConfigLoader(); - } - - public static getRewardProgram(value: string): RewardProgram { - const programs = Object.values(RewardProgram) as RewardProgram[]; - const program = programs.find((p) => p.toLowerCase() == value.toLowerCase()); - if (program) { - return program; - } - throw new KnownError(`${value} is not a valid Reward program. Please use one of ${programs.join(', ')}`); - } - - public async enroll(passedPresetData?: ConfigPreset | undefined, passedAddresses?: Addresses | undefined): Promise { - const presetData = passedPresetData ?? this.configLoader.loadExistingPresetData(this.params.target, this.params.password); - const addresses = passedAddresses ?? this.configLoader.loadExistingAddresses(this.params.target, this.params.password); - const customPreset = this.configLoader.loadCustomPreset(this.params.customPreset, this.params.password); - if (!presetData.rewardProgramEnrollmentAddress) { - logger.warn('This network does not have a reward program controller public key. Nodes cannot be registered.'); - return; - } - await new AnnounceService().announce( - this.params.url, - this.params.maxFee, - this.params.useKnownRestGateways, - this.params.ready, - this.params.target, - this.configLoader.mergePresets(presetData, customPreset), - addresses, - this, - '1M+', - ); - } - - async createTransactions({ - presetData, - nodePreset, - nodeAccount, - deadline, - maxFee, - }: RewardProgramServiceTransactionFactoryParams): Promise { - const transactions: Transaction[] = []; - const networkType = presetData.networkType; - if (!nodePreset.rewardProgram) { - logger.warn(`Node ${nodeAccount.name} hasn't been configured with rewardProgram: preset property.`); - return transactions; - } - - if (!presetData.rewardProgramEnrollmentAddress) { - return transactions; - } - const rewardProgramEnrollmentAddress = Address.createFromRawAddress(presetData.rewardProgramEnrollmentAddress); - const agentPublicKey = nodeAccount.transport.publicKey; - if (!agentPublicKey) { - logger.warn(`Cannot resolve harvester public key of node ${nodeAccount.name}`); - return transactions; - } - if (!nodePreset.host) { - logger.warn( - `Node ${nodeAccount.name} public host name hasn't been provided! Please use 'host: myNodeHost' custom preset param.`, - ); - return transactions; - } - const agentUrl = - nodePreset.agentUrl || `https://${nodePreset.host}:${nodePreset.rewardProgramAgentPort || presetData.rewardProgramAgentPort}`; - const certFolder = BootstrapUtils.getTargetNodesFolder(this.params.target, false, nodePreset.name, 'agent'); - const base64AgentCaCsrFile = readFileSync(join(certFolder, 'agent-ca.csr.pem'), 'base64'); - const plainMessage = `enroll ${agentUrl} ${base64AgentCaCsrFile}`; - const message = PlainMessage.create(plainMessage); - logger.info(`Creating enrolment transfer with message '${plainMessage}'`); - const transaction: Transaction = TransferTransaction.create( - deadline, - rewardProgramEnrollmentAddress, - [], - message, - networkType, - maxFee, - ); - return [transaction]; - } -} diff --git a/src/service/RunService.ts b/src/service/RunService.ts index 0ef9bc58f..b4d44689b 100644 --- a/src/service/RunService.ts +++ b/src/service/RunService.ts @@ -15,7 +15,6 @@ */ import { chmodSync, existsSync } from 'fs'; -import * as https from 'https'; import * as _ from 'lodash'; import { join } from 'path'; import { NodeStatusEnum } from 'symbol-openapi-typescript-fetch-client'; @@ -146,41 +145,6 @@ export class RunService { return false; } } - if (service.container_name.indexOf('node-agent') > -1) { - const url = 'https://localhost:' + externalPort; - - const testUrl = `${url}/metadata`; - logger.info(`Testing ${testUrl}`); - try { - const response = await new Promise((resolve, reject) => { - try { - const req = https.request(testUrl, { rejectUnauthorized: false, timeout: 1000 }, (res) => { - let str = ''; - res.on('data', (chunk) => { - str += chunk; - }); - - res.on('end', () => { - resolve(str); - }); - }); - req.on('error', reject); - req.end(); - } catch (e) { - reject(e); - } - }); - const metadata = JSON.parse(response); - if (metadata.authorized || !metadata.rewardProgram || !metadata.mainPublicKey) { - throw new Error(`Invalid response ${response}`); - } - logger.info(`Agent ${testUrl} is up and running...`); - return true; - } catch (e) { - logger.warn(`Agent ${testUrl} is NOT up and running YET: ${e.message}`); - return false; - } - } return true; }), ) @@ -211,7 +175,7 @@ export class RunService { } public async stop(): Promise { - const args = ['down']; + const args = ['stop']; if (await this.beforeRun(args, true)) await this.basicRun(args); } diff --git a/src/service/SshpkService.ts b/src/service/SshpkService.ts deleted file mode 100644 index 02de9366a..000000000 --- a/src/service/SshpkService.ts +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2020 NEM - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { join, resolve } from 'path'; -import * as sshpk from 'sshpk'; -import { Key } from 'sshpk'; -import { Convert, Crypto } from 'symbol-sdk'; -import { LogType } from '../logger'; -import Logger from '../logger/Logger'; -import LoggerFactory from '../logger/LoggerFactory'; -import { CertificatePair, ConfigPreset, NodeAccount } from '../model'; -import { BootstrapUtils } from './BootstrapUtils'; -import { ConfigParams } from './ConfigService'; - -const anySshpk = sshpk as any; -type CertificateParams = ConfigParams; - -const logger: Logger = LoggerFactory.getLogger(LogType.System); - -interface NodeCertificates { - ssl: CertificatePair; - node: CertificatePair; -} - -interface SshpkKey { - publicKey: string; - privateKey: string; - key: Key; -} - -/** - * TODO remote if not used! - */ -export class SshpkService { - constructor(private readonly root: string, protected readonly params: CertificateParams) {} - - private async createKey(certFolder: string, privateKeyFileName: string, publicKeyFileName: string): Promise { - const key = anySshpk.generatePrivateKey('ed25519'); - const privateKey = Convert.uint8ToHex(key.part.k.data); - const publicKey = Convert.uint8ToHex(key.toPublic().part.A.data); - - console.log('pem', key.toString('pem')); - console.log('openssh', key.toString('openssh')); - console.log('ssh', key.toString('ssh')); - console.log('pkcs1', key.toString('pkcs1')); - - await BootstrapUtils.writeTextFile(join(certFolder, privateKeyFileName), key.toString('pem')); - await BootstrapUtils.writeTextFile(join(certFolder, publicKeyFileName), key.toPublic().toString('pem')); - - return { - privateKey, - publicKey, - key, - }; - } - - public async run(presetData: ConfigPreset, nodeAccount: NodeAccount): Promise { - const name = nodeAccount.name; - const copyFrom = `${this.root}/config/cert`; - - const certFolder = BootstrapUtils.getTargetNodesFolder(this.params.target, false, name, 'userconfig', 'resources', 'cert2'); - await BootstrapUtils.mkdir(certFolder); - const newCertsFolder = join(certFolder, 'new_certs'); - await BootstrapUtils.mkdir(newCertsFolder); - await BootstrapUtils.generateConfiguration({ name: name }, copyFrom, certFolder); - - if (!BootstrapUtils.isWindows()) { - // fs.chmodSync(newCertsFolder, 700); - } - - await BootstrapUtils.writeTextFile(join(certFolder, 'index.txt'), ''); - await BootstrapUtils.writeTextFile(join(certFolder, 'index.txt.attr'), ''); - await BootstrapUtils.writeTextFile(join(certFolder, 'serial.dat'), Convert.uint8ToHex(Crypto.randomBytes(19)).toUpperCase()); - - const ssl = await this.createKey(certFolder, 'ca.key.pem', 'ca.pubkey.pem'); - const node = await this.createKey(certFolder, 'node.key.pem', 'node.pubkey.pem'); - - // const certificate = sshpk.createSelfSignedCertificate('subject', ssl.key); - // console.log(certificate); - - const command = this.createCertCommands('/data'); - await BootstrapUtils.writeTextFile(join(certFolder, 'createCertificate.sh'), command); - const cmd = ['bash', 'createCertificate.sh']; - const binds = [`${resolve(certFolder)}:/data:rw`]; - const userId = await BootstrapUtils.resolveDockerUserFromParam(this.params.user); - const symbolServerImage = presetData.symbolServerImage; - const { stdout, stderr } = await BootstrapUtils.runImageUsingExec({ - catapultAppFolder: presetData.catapultAppFolder, - image: symbolServerImage, - userId: userId, - workdir: '/data', - cmds: cmd, - binds: binds, - }); - if (stdout.indexOf('Certificate Created') < 0) { - logger.info(stdout); - logger.error(stderr); - throw new Error('Certificate creation failed. Check the logs!'); - } - console.log(stdout); - console.log(stderr); - - // const key = sshpk.parseKey(node.node.privateKey, 'auto'); - - // const generatePrivateKey = anySshpk.generatePrivateKey(); - - // console.log(generatePrivateKey.toString('pem')); - // console.log(generatePrivateKey.toPublic().toString('pem')); - - // console.log(generatePrivateKey); - - // const publicKey = generatePrivateKey.toPublic().part.A.data; - // console.log(Convert.uint8ToHex(publicKey)); - - // const privateKey = generatePrivateKey.part.k.data; - // console.log(Convert.uint8ToHex(privateKey)); - - return { ssl, node }; - } - - private createCertCommands(target: string): string { - return ` -set -e - -# create CA cert and self-sign it -openssl req -config ca.cnf -keyform PEM -key ca.key.pem -new -x509 -days 7300 -out ca.cert.pem -openssl x509 -in ca.cert.pem -text -noout - -# create node key - -# create request -openssl req -config node.cnf -key node.key.pem -new -out node.csr.pem -openssl req -text -noout -verify -in node.csr.pem - -### below is done after files are written - -# sign cert for 375 days -openssl ca -batch -config ca.cnf -days 375 -notext -in node.csr.pem -out node.crt.pem -openssl verify -CAfile ca.cert.pem node.crt.pem - -# finally create full crt -cat node.crt.pem ca.cert.pem > node.full.crt.pem -echo "Certificate Created" -`; - } -} diff --git a/src/service/TransactionUtils.ts b/src/service/TransactionUtils.ts new file mode 100644 index 000000000..140440457 --- /dev/null +++ b/src/service/TransactionUtils.ts @@ -0,0 +1,38 @@ +/* + * Copyright 2020 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Address, MultisigAccountInfo, RepositoryFactory } from 'symbol-sdk'; +import { ConfigPreset } from '../model'; +import { RemoteNodeService } from './RemoteNodeService'; + +export class TransactionUtils { + public static async getRepositoryFactory(presetData: ConfigPreset, url: string | undefined): Promise { + const repositoryInfo = await new RemoteNodeService(presetData, false).getBestRepositoryInfo(url); + return repositoryInfo.repositoryFactory; + } + + public static async getMultisigAccount( + repositoryFactory: RepositoryFactory, + accountAddress: Address, + ): Promise { + try { + const info = await repositoryFactory.createMultisigRepository().getMultisigAccountInfo(accountAddress).toPromise(); + return info.isMultisig() ? info : undefined; + } catch (e) { + return undefined; + } + } +} diff --git a/src/service/VotingService.ts b/src/service/VotingService.ts index 54179b400..d5aeb18c4 100644 --- a/src/service/VotingService.ts +++ b/src/service/VotingService.ts @@ -110,7 +110,7 @@ export class VotingService { } } if (nemesisBlock) { - // For a new private network, voting keys are in the nemesisBlock. + // For a new local network, voting keys are in the nemesisBlock. logger.info(''); logger.info( `A new Voting File for the node ${nodeAccount.name} has been generated. The link transaction will be included in the nemesis block.`, diff --git a/src/service/VotingUtils.ts b/src/service/VotingUtils.ts index 2e436fc36..d3dedf8fe 100644 --- a/src/service/VotingUtils.ts +++ b/src/service/VotingUtils.ts @@ -15,12 +15,10 @@ */ import { existsSync, lstatSync, readdirSync, readFileSync } from 'fs'; import * as noble from 'noble-ed25519'; -import * as forge from 'node-forge'; import { join } from 'path'; import { Convert, Crypto } from 'symbol-sdk'; import * as nacl from 'tweetnacl'; -const ed25519 = forge.pki.ed25519; export interface KeyPair { privateKey: Uint8Array; publicKey: Uint8Array; @@ -51,26 +49,6 @@ export class VotingUtils { }, }; - public static forgeImplementation: CryptoImplementation = { - name: 'Forge', - createKeyPairFromPrivateKey: async (privateKey: Uint8Array): Promise => { - const keyPair = ed25519.generateKeyPair({ seed: privateKey }); - return { privateKey, publicKey: keyPair.publicKey }; - }, - - sign: async (keyPair: KeyPair, data: Uint8Array): Promise => { - const secretKey = new Uint8Array(64); - secretKey.set(keyPair.privateKey); - secretKey.set(keyPair.publicKey, 32); - const signature = ed25519.sign({ - // also accepts a forge ByteBuffer or Uint8Array - message: data, - privateKey: secretKey, - }); - return new Uint8Array(signature); - }, - }; - public static tweetNaClImplementation: CryptoImplementation = { name: 'TweetNaCl', createKeyPairFromPrivateKey: async (privateKey: Uint8Array): Promise => { @@ -86,7 +64,7 @@ export class VotingUtils { }, }; - public static implementations = [VotingUtils.nobleImplementation, VotingUtils.tweetNaClImplementation, VotingUtils.forgeImplementation]; + public static implementations = [VotingUtils.nobleImplementation, VotingUtils.tweetNaClImplementation]; constructor(private readonly implementation: CryptoImplementation = VotingUtils.nobleImplementation) {} public insert(result: Uint8Array, value: Uint8Array, index: number): number { diff --git a/src/service/ZipUtils.ts b/src/service/ZipUtils.ts new file mode 100644 index 000000000..21e5da987 --- /dev/null +++ b/src/service/ZipUtils.ts @@ -0,0 +1,128 @@ +/* + * Copyright 2021 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import * as archiver from 'archiver'; +import { createWriteStream } from 'fs'; +import * as StreamZip from 'node-stream-zip'; +import { LogType } from '../logger'; +import Logger from '../logger/Logger'; +import LoggerFactory from '../logger/LoggerFactory'; +import { BootstrapUtils } from './BootstrapUtils'; + +export interface ZipItem { + from: string; + directory: boolean; + to: string; + blacklist?: string[]; +} +const logger: Logger = LoggerFactory.getLogger(LogType.System); + +export class ZipUtils { + public static async zip(destination: string, items: ZipItem[]): Promise { + const output = createWriteStream(destination); + const archive = archiver('zip', { + zlib: { level: 9 }, // Sets the compression level. + }); + archive.pipe(output); + return new Promise(async (resolve, reject) => { + output.on('close', () => { + console.log(''); + console.info(`Zip file ${destination} size ${Math.floor(archive.pointer() / 1024)} MB has been created.`); + resolve(); + }); + + output.on('end', () => { + console.log(''); + console.log('Data has been drained'); + }); + + // good practice to catch warnings (ie stat failures and other non-blocking errors) + archive.on('warning', (err: any) => { + console.log(''); + if (err.code === 'ENOENT') { + // log warning + console.log(`There has been an warning creating ZIP file '${destination}' ${err.message || err}`); + } else { + // throw error + console.log(`There has been an error creating ZIP file '${destination}' ${err.message || err}`); + reject(err); + } + }); + + // good practice to catch this error explicitly + archive.on('error', function (err: any) { + console.log(`There has been an error creating ZIP file '${destination}' ${err.message || err}`); + reject(err); + }); + + for (const item of items) { + if (item.directory) { + archive.directory(item.from, item.to || false, (entry) => { + if (item.blacklist?.find((s) => entry.name === s)) { + return false; + } + return entry; + }); + } else { + archive.file(item.from, { name: item.to }); + } + } + archive.on('progress', (progress) => { + const message = `${progress.entries.processed} entries zipped!`; + BootstrapUtils.logSameLineMessage(message); + }); + await archive.finalize(); + }); + } + + public static unzip(zipFile: string, innerFolder: string, targetFolder: string): Promise { + const zip = new StreamZip({ + file: zipFile, + storeEntries: true, + }); + logger.info(`Unzipping Backup Sync's '${innerFolder}' into '${targetFolder}'. This could take a while!`); + let totalFiles = 0; + let process = 0; + return new Promise((resolve, reject) => { + zip.on('entry', (entry) => { + if (!entry.isDirectory && totalFiles) { + process++; + const percentage = ((process * 100) / totalFiles).toFixed(2); + const message = `${percentage}% | ${process} files unzipped out of ${totalFiles}`; + BootstrapUtils.logSameLineMessage(message); + } + if (BootstrapUtils.stopProcess) { + zip.close(); + console.log(); + reject(new Error('Process cancelled!')); + } + }); + zip.on('ready', () => { + totalFiles = zip.entriesCount; + zip.extract(innerFolder, targetFolder, (err) => { + zip.close(); + if (err) { + console.log(); + reject(err); + } else { + console.log(); + logger.info(`Unzipped '${targetFolder}' created`); + resolve(); + } + }); + }); + }); + } +} diff --git a/src/service/index.ts b/src/service/index.ts index dcd0c07fa..414d4b75a 100644 --- a/src/service/index.ts +++ b/src/service/index.ts @@ -1,6 +1,5 @@ // created from 'create-ts-index' -export * from './AgentCertificateService'; export * from './AnnounceService'; export * from './BootstrapService'; export * from './BootstrapUtils'; @@ -10,15 +9,15 @@ export * from './ComposeService'; export * from './ConfigLoader'; export * from './ConfigService'; export * from './CryptoUtils'; -export * from './ForgeCertificateService'; export * from './LinkService'; +export * from './ModifyMultisigService'; export * from './NemgenService'; export * from './PortService'; export * from './RemoteNodeService'; export * from './ReportService'; -export * from './RewardProgramService'; export * from './RunService'; -export * from './SshpkService'; +export * from './TransactionUtils'; export * from './VerifyService'; export * from './VotingService'; export * from './VotingUtils'; +export * from './ZipUtils'; diff --git a/test/agentCertificates/agent-ca.cnf b/test/agentCertificates/agent-ca.cnf deleted file mode 100644 index 453557283..000000000 --- a/test/agentCertificates/agent-ca.cnf +++ /dev/null @@ -1,20 +0,0 @@ -[ca] -default_ca = CA_default - -[CA_default] -new_certs_dir = ./new_certs -database = index.txt -serial = serial.dat -private_key = agent-ca.key.pem -certificate = agent-ca.crt.pem -policy = policy_catapult - -[policy_catapult] -commonName = supplied - -[req] -prompt = no -distinguished_name = dn - -[dn] -CN = Agent CA diff --git a/test/agentCertificates/agent-ca.csr.pem b/test/agentCertificates/agent-ca.csr.pem deleted file mode 100644 index 95a303a4f..000000000 --- a/test/agentCertificates/agent-ca.csr.pem +++ /dev/null @@ -1,6 +0,0 @@ ------BEGIN CERTIFICATE REQUEST----- -MIGSMEYCAQAwEzERMA8GA1UEAwwIQWdlbnQgQ0EwKjAFBgMrZXADIQAEeU7nvQgQ -BXhwx3OcmF1Cu0qqSxueOnG/5jc6ctY3JqAAMAUGAytlcANBAKsI2XzKGymi+k54 -3n0O8h9EafEkXQdR7zvKkSliFVRG/iSUMPkam1DIokdDEOqYDQwXkqwSjJjkL0Gl -eaE07Qk= ------END CERTIFICATE REQUEST----- diff --git a/test/agentCertificates/agent-ca.key.pem b/test/agentCertificates/agent-ca.key.pem deleted file mode 100644 index 1c24a2a22..000000000 --- a/test/agentCertificates/agent-ca.key.pem +++ /dev/null @@ -1,3 +0,0 @@ ------BEGIN PRIVATE KEY----- -MC4CAQAwBQYDK2VwBCIEII0ZKcrIkpW+fb4mt/gwqkKnTXXXBVEX3ylzAB4ycb3Z ------END PRIVATE KEY----- diff --git a/test/agentCertificates/agent-ca.pubkey.pem b/test/agentCertificates/agent-ca.pubkey.pem deleted file mode 100644 index c5adcb611..000000000 --- a/test/agentCertificates/agent-ca.pubkey.pem +++ /dev/null @@ -1,3 +0,0 @@ ------BEGIN PUBLIC KEY----- -MCowBQYDK2VwAyEABHlO570IEAV4cMdznJhdQrtKqksbnjpxv+Y3OnLWNyY= ------END PUBLIC KEY----- diff --git a/test/agentCertificates/agent-comm.cnf b/test/agentCertificates/agent-comm.cnf deleted file mode 100644 index 766f8efbc..000000000 --- a/test/agentCertificates/agent-comm.cnf +++ /dev/null @@ -1,7 +0,0 @@ -[req] -prompt = no -distinguished_name = dn - -[dn] -CN = Agent communication cert - diff --git a/test/agentCertificates/index.txt b/test/agentCertificates/index.txt deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/agentCertificates/metadata.yml b/test/agentCertificates/metadata.yml deleted file mode 100644 index 56763f3d5..000000000 --- a/test/agentCertificates/metadata.yml +++ /dev/null @@ -1,2 +0,0 @@ -version: 1 -agentPublicKey: 04794EE7BD0810057870C7739C985D42BB4AAA4B1B9E3A71BFE6373A72D63726 diff --git a/test/boat.png b/test/boat.png new file mode 100644 index 000000000..e022f1010 Binary files /dev/null and b/test/boat.png differ diff --git a/test/certificates/restSsl.crt b/test/certificates/restSsl.crt new file mode 100644 index 000000000..210657448 --- /dev/null +++ b/test/certificates/restSsl.crt @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICEjCCAXsCAg36MA0GCSqGSIb3DQEBBQUAMIGbMQswCQYDVQQGEwJKUDEOMAwG +A1UECBMFVG9reW8xEDAOBgNVBAcTB0NodW8ta3UxETAPBgNVBAoTCEZyYW5rNERE +MRgwFgYDVQQLEw9XZWJDZXJ0IFN1cHBvcnQxGDAWBgNVBAMTD0ZyYW5rNEREIFdl +YiBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmcmFuazRkZC5jb20wHhcNMTIw +ODIyMDUyNjU0WhcNMTcwODIxMDUyNjU0WjBKMQswCQYDVQQGEwJKUDEOMAwGA1UE +CAwFVG9reW8xETAPBgNVBAoMCEZyYW5rNEREMRgwFgYDVQQDDA93d3cuZXhhbXBs +ZS5jb20wXDANBgkqhkiG9w0BAQEFAANLADBIAkEAm/xmkHmEQrurE/0re/jeFRLl +8ZPjBop7uLHhnia7lQG/5zDtZIUC3RVpqDSwBuw/NTweGyuP+o8AG98HxqxTBwID +AQABMA0GCSqGSIb3DQEBBQUAA4GBABS2TLuBeTPmcaTaUW/LCB2NYOy8GMdzR1mx +8iBIu2H6/E2tiY3RIevV2OW61qY2/XRQg7YPxx3ffeUugX9F4J/iPnnu1zAxxyBy +2VguKv4SWjRFoRkIfIlHX0qVviMhSlNy2ioFLy7JcPZb+v3ftDGywUqcBiVDoea0 +Hn+GmxZA +-----END CERTIFICATE----- diff --git a/test/certificates/restSsl.key b/test/certificates/restSsl.key new file mode 100644 index 000000000..bc4edabce --- /dev/null +++ b/test/certificates/restSsl.key @@ -0,0 +1,9 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIBOwIBAAJBAJv8ZpB5hEK7qxP9K3v43hUS5fGT4waKe7ix4Z4mu5UBv+cw7WSF +At0Vaag0sAbsPzU8Hhsrj/qPABvfB8asUwcCAwEAAQJAG0r3ezH35WFG1tGGaUOr +QA61cyaII53ZdgCR1IU8bx7AUevmkFtBf+aqMWusWVOWJvGu2r5VpHVAIl8nF6DS +kQIhAMjEJ3zVYa2/Mo4ey+iU9J9Vd+WoyXDQD4EEtwmyG1PpAiEAxuZlvhDIbbce +7o5BvOhnCZ2N7kYb1ZC57g3F+cbJyW8CIQCbsDGHBto2qJyFxbAO7uQ8Y0UVHa0J +BO/g900SAcJbcQIgRtEljIShOB8pDjrsQPxmI1BLhnjD1EhRSubwhDw5AFUCIQCN +A24pDtdOHydwtSB5+zFqFLfmVZplQM/g5kb4so70Yw== +-----END RSA PRIVATE KEY----- diff --git a/test/commands/Wizard.test.ts b/test/commands/Wizard.test.ts new file mode 100644 index 000000000..cdee39b05 --- /dev/null +++ b/test/commands/Wizard.test.ts @@ -0,0 +1,323 @@ +/* + * Copyright 2021 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { expect } from '@oclif/test'; +import { Account, NetworkType } from 'symbol-sdk'; +import Wizard, { Network } from '../../src/commands/wizard'; +import { CustomPreset, PrivateKeySecurityMode } from '../../src/model'; +import { BootstrapUtils, Preset } from '../../src/service'; +import { StdUtils } from '../utils/StdUtils'; + +describe('Wizard', () => { + const testFolder = 'target/wizardTest'; + beforeEach(async () => { + BootstrapUtils.deleteFolder(testFolder); + }); + it('Provide private keys', async () => { + // assembly + StdUtils.in([ + '\n', + '\n', + StdUtils.keys.down, + '\n', + 'AAA3F0EF0AB368B8D7AC194D52A8CCFA2D5050B80B9C76E4D2F4D4BF2CD461C1\n', + 'y\n', + StdUtils.keys.down, + '\n', + 'BBB3F0EF0AB368B8D7AC194D52A8CCFA2D5050B80B9C76E4D2F4D4BF2CD461C1\n', + 'y\n', + StdUtils.keys.down, + '\n', + 'CCC3F0EF0AB368B8D7AC194D52A8CCFA2D5050B80B9C76E4D2F4D4BF2CD461C1\n', + 'y\n', + StdUtils.keys.down, + '\n', + 'DDD3F0EF0AB368B8D7AC194D52A8CCFA2D5050B80B9C76E4D2F4D4BF2CD461C1\n', + 'y\n', + StdUtils.keys.down, // resolveHttpsOptions select none down 1/2 + StdUtils.keys.down, // resolveHttpsOptions select none down 2/2 + '\n', + 'myhostname.org\n', + 'myfriendlyname\n', + '\n', + 'y\n', //Voting! + '\n', + 'n\n', + 'n\n', + ]); + + const password = '11111'; + const customPresetFile = `${testFolder}/wizard-custom.yml`; + await Wizard.execute(BootstrapUtils.resolveRootFolder(), { + customPreset: customPresetFile, + network: Network.mainnet, + noPassword: false, + skipPull: true, + target: `${testFolder}/target`, + password: password, + }); + const expectedCustomPreset: CustomPreset = { + assembly: 'dual', + nodes: [ + { + friendlyName: 'myfriendlyname', + host: 'myhostname.org', + voting: true, + mainPrivateKey: 'AAA3F0EF0AB368B8D7AC194D52A8CCFA2D5050B80B9C76E4D2F4D4BF2CD461C1', + remotePrivateKey: 'DDD3F0EF0AB368B8D7AC194D52A8CCFA2D5050B80B9C76E4D2F4D4BF2CD461C1', + transportPrivateKey: 'BBB3F0EF0AB368B8D7AC194D52A8CCFA2D5050B80B9C76E4D2F4D4BF2CD461C1', + vrfPrivateKey: 'CCC3F0EF0AB368B8D7AC194D52A8CCFA2D5050B80B9C76E4D2F4D4BF2CD461C1', + }, + ], + preset: Preset.mainnet, + privateKeySecurityMode: PrivateKeySecurityMode.PROMPT_MAIN_TRANSPORT, + }; + const customPreset = BootstrapUtils.loadYaml(customPresetFile, password); + expect(customPreset).deep.eq(expectedCustomPreset); + }); + + it('Generate private keys', async () => { + const toKey = (prefix: string | number, keySize = 64): string => { + return prefix.toString().padStart(keySize, '0'); + }; + let index = 0; + Wizard.generateAccount = (networkType: NetworkType) => { + return Account.createFromPrivateKey(toKey(++index), networkType); + }; + // assembly + StdUtils.in([ + '\n', + 'y\n', //Are you offline. + '\n', + '\n', + '\n', + '\n', + StdUtils.keys.down, // resolveHttpsOptions select none down 1 + StdUtils.keys.down, // resolveHttpsOptions select none down 2 + '\n', + 'myhostname.org\n', + 'myfriendlyname\n', + '\n', + 'y\n', + // '\n', + // '\n', + // 'y\n', + ]); + + const customPresetFile = `${testFolder}/wizard-custom.yml`; + const password = '11111'; + await Wizard.execute(BootstrapUtils.resolveRootFolder(), { + customPreset: customPresetFile, + network: Network.mainnet, + noPassword: false, + skipPull: true, + target: `${testFolder}/target`, + password: password, + }); + const expectedCustomPreset: CustomPreset = { + assembly: 'dual', + nodes: [ + { + friendlyName: 'myfriendlyname', + host: 'myhostname.org', + mainPrivateKey: '0000000000000000000000000000000000000000000000000000000000000001', + remotePrivateKey: '0000000000000000000000000000000000000000000000000000000000000004', + transportPrivateKey: '0000000000000000000000000000000000000000000000000000000000000002', + voting: true, + vrfPrivateKey: '0000000000000000000000000000000000000000000000000000000000000003', + }, + ], + preset: Preset.mainnet, + privateKeySecurityMode: PrivateKeySecurityMode.PROMPT_MAIN_TRANSPORT, + }; + const customPreset = BootstrapUtils.loadYaml(customPresetFile, password); + expect(customPreset).deep.eq(expectedCustomPreset); + }); + + it('Enables httpsProxy on rest-gateway', async () => { + const toKey = (prefix: string | number, keySize = 64): string => { + return prefix.toString().padStart(keySize, '0'); + }; + let index = 0; + Wizard.generateAccount = (networkType: NetworkType) => { + return Account.createFromPrivateKey(toKey(++index), networkType); + }; + // assembly + StdUtils.in([ + '\n', + 'y\n', //Are you offline. + '\n', + '\n', + '\n', + '\n', + StdUtils.keys.down, // resolveHttpsOptions select Automatic + '\n', + 'myhostname.org\n', + 'myfriendlyname\n', + '\n', + 'y\n', + // '\n', + // '\n', + // 'y\n', + ]); + + const customPresetFile = `${testFolder}/wizard-custom.yml`; + const password = '11111'; + await Wizard.execute(BootstrapUtils.resolveRootFolder(), { + customPreset: customPresetFile, + network: Network.mainnet, + noPassword: false, + skipPull: true, + target: `${testFolder}/target`, + password: password, + }); + const expectedCustomPreset: CustomPreset = { + preset: Preset.mainnet, + assembly: 'dual', + privateKeySecurityMode: PrivateKeySecurityMode.PROMPT_MAIN_TRANSPORT, + nodes: [ + { + friendlyName: 'myfriendlyname', + host: 'myhostname.org', + mainPrivateKey: '0000000000000000000000000000000000000000000000000000000000000001', + remotePrivateKey: '0000000000000000000000000000000000000000000000000000000000000004', + transportPrivateKey: '0000000000000000000000000000000000000000000000000000000000000002', + voting: true, + vrfPrivateKey: '0000000000000000000000000000000000000000000000000000000000000003', + }, + ], + httpsProxies: [ + { + excludeDockerService: false, + }, + ], + }; + console.log(BootstrapUtils.toYaml(expectedCustomPreset)); + const customPreset = BootstrapUtils.loadYaml(customPresetFile, password); + expect(customPreset).deep.eq(expectedCustomPreset); + }); + + it('Enables native SSL support on rest-gateway', async () => { + const toKey = (prefix: string | number, keySize = 64): string => { + return prefix.toString().padStart(keySize, '0'); + }; + let index = 0; + Wizard.generateAccount = (networkType: NetworkType) => { + return Account.createFromPrivateKey(toKey(++index), networkType); + }; + // assembly + StdUtils.in([ + '\n', + 'y\n', //Are you offline. + '\n', + '\n', + '\n', + '\n', + '\n', + '\n', // resolveHttpsOptions select Native + 'myhostname.org\n', + './test/certificates/restSsl.key\n', + './test/certificates/restSsl.crt\n', + 'myfriendlyname\n', + '\n', + 'y\n', + // '\n', + // '\n', + // 'y\n', + ]); + + const customPresetFile = `${testFolder}/wizard-custom.yml`; + const password = '11111'; + await Wizard.execute(BootstrapUtils.resolveRootFolder(), { + customPreset: customPresetFile, + network: Network.mainnet, + noPassword: false, + skipPull: true, + target: `${testFolder}/target`, + password: password, + }); + const expectedCustomPreset: CustomPreset = { + preset: Preset.mainnet, + assembly: 'dual', + privateKeySecurityMode: PrivateKeySecurityMode.PROMPT_MAIN_TRANSPORT, + nodes: [ + { + friendlyName: 'myfriendlyname', + host: 'myhostname.org', + mainPrivateKey: '0000000000000000000000000000000000000000000000000000000000000001', + remotePrivateKey: '0000000000000000000000000000000000000000000000000000000000000004', + transportPrivateKey: '0000000000000000000000000000000000000000000000000000000000000002', + voting: true, + vrfPrivateKey: '0000000000000000000000000000000000000000000000000000000000000003', + }, + ], + gateways: [ + { + restProtocol: 'HTTPS', + openPort: 3001, + restSSLCertificateBase64: + 'LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNFakNDQVhzQ0FnMzZNQTBHQ1NxR1NJYjNEUUVCQlFVQU1JR2JNUXN3Q1FZRFZRUUdFd0pLVURFT01Bd0cKQTFVRUNCTUZWRzlyZVc4eEVEQU9CZ05WQkFjVEIwTm9kVzh0YTNVeEVUQVBCZ05WQkFvVENFWnlZVzVyTkVSRQpNUmd3RmdZRFZRUUxFdzlYWldKRFpYSjBJRk4xY0hCdmNuUXhHREFXQmdOVkJBTVREMFp5WVc1ck5FUkVJRmRsCllpQkRRVEVqTUNFR0NTcUdTSWIzRFFFSkFSWVVjM1Z3Y0c5eWRFQm1jbUZ1YXpSa1pDNWpiMjB3SGhjTk1USXcKT0RJeU1EVXlOalUwV2hjTk1UY3dPREl4TURVeU5qVTBXakJLTVFzd0NRWURWUVFHRXdKS1VERU9NQXdHQTFVRQpDQXdGVkc5cmVXOHhFVEFQQmdOVkJBb01DRVp5WVc1ck5FUkVNUmd3RmdZRFZRUUREQTkzZDNjdVpYaGhiWEJzClpTNWpiMjB3WERBTkJna3Foa2lHOXcwQkFRRUZBQU5MQURCSUFrRUFtL3hta0htRVFydXJFLzByZS9qZUZSTGwKOFpQakJvcDd1TEhobmlhN2xRRy81ekR0WklVQzNSVnBxRFN3QnV3L05Ud2VHeXVQK284QUc5OEh4cXhUQndJRApBUUFCTUEwR0NTcUdTSWIzRFFFQkJRVUFBNEdCQUJTMlRMdUJlVFBtY2FUYVVXL0xDQjJOWU95OEdNZHpSMW14CjhpQkl1Mkg2L0UydGlZM1JJZXZWMk9XNjFxWTIvWFJRZzdZUHh4M2ZmZVV1Z1g5RjRKL2lQbm51MXpBeHh5QnkKMlZndUt2NFNXalJGb1JrSWZJbEhYMHFWdmlNaFNsTnkyaW9GTHk3SmNQWmIrdjNmdERHeXdVcWNCaVZEb2VhMApIbitHbXhaQQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==', + restSSLKeyBase64: + 'LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlCT3dJQkFBSkJBSnY4WnBCNWhFSzdxeFA5SzN2NDNoVVM1ZkdUNHdhS2U3aXg0WjRtdTVVQnYrY3c3V1NGCkF0MFZhYWcwc0Fic1B6VThIaHNyai9xUEFCdmZCOGFzVXdjQ0F3RUFBUUpBRzByM2V6SDM1V0ZHMXRHR2FVT3IKUUE2MWN5YUlJNTNaZGdDUjFJVThieDdBVWV2bWtGdEJmK2FxTVd1c1dWT1dKdkd1MnI1VnBIVkFJbDhuRjZEUwprUUloQU1qRUozelZZYTIvTW80ZXkraVU5SjlWZCtXb3lYRFFENEVFdHdteUcxUHBBaUVBeHVabHZoREliYmNlCjdvNUJ2T2huQ1oyTjdrWWIxWkM1N2czRitjYkp5VzhDSVFDYnNER0hCdG8ycUp5RnhiQU83dVE4WTBVVkhhMEoKQk8vZzkwMFNBY0piY1FJZ1J0RWxqSVNoT0I4cERqcnNRUHhtSTFCTGhuakQxRWhSU3Vid2hEdzVBRlVDSVFDTgpBMjRwRHRkT0h5ZHd0U0I1K3pGcUZMZm1WWnBsUU0vZzVrYjRzbzcwWXc9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=', + }, + ], + }; + + console.log(BootstrapUtils.toYaml(expectedCustomPreset)); + const customPreset = BootstrapUtils.loadYaml(customPresetFile, password); + expect(customPreset).deep.eq(expectedCustomPreset); + }); + + describe('isValidHost', () => { + // valid cases + it('should return true when given hostname is a valid IP address', () => { + expect(Wizard.isValidHost('10.10.10.10')).to.be.true; + }); + + it('should return true when given hostname is a valid domain name', () => { + expect(Wizard.isValidHost('example.com')).to.be.true; + }); + + it('should return true when given hostname is a valid numeric only domain name', () => { + expect(Wizard.isValidHost('1000.org')).to.be.true; + }); + + it('should return true when given hostname is a valid a subdomain', () => { + expect(Wizard.isValidHost('mynode.example.com')).to.be.true; + }); + + it('should return true when given hostname is a valid a subdomain starting with number', () => { + expect(Wizard.isValidHost('2.example.com')).to.be.true; + }); + + // invalid cases + it('should return error when given hostname is an invalid IP address', () => { + expect(Wizard.isValidHost('256.10.10.10')).to.be.eq("It's not a valid IP or hostname"); + }); + + it('should return error when given hostname does not have an extension', () => { + expect(Wizard.isValidHost('example')).to.be.eq("It's not a valid IP or hostname"); + }); + + it('should return error when given hostname is an invalid domain name', () => { + expect(Wizard.isValidHost('symbol-harvesting-.org')).to.be.eq("It's not a valid IP or hostname"); + }); + + it('should return error when given hostname is an invalid a subdomain', () => { + expect(Wizard.isValidHost('2-.example.com')).to.be.eq("It's not a valid IP or hostname"); + }); + }); +}); diff --git a/test/composes/expected-docker-compose-bootstrap-custom-compose.yml b/test/composes/expected-docker-compose-bootstrap-custom-compose.yml index 6a8b26e78..cd4bbcfb6 100644 --- a/test/composes/expected-docker-compose-bootstrap-custom-compose.yml +++ b/test/composes/expected-docker-compose-bootstrap-custom-compose.yml @@ -23,7 +23,7 @@ services: peer-node-0: user: '1000:1000' container_name: peer-node-0 - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data server broker peer-node-0 NORMAL false stop_signal: SIGINT working_dir: /symbol-workdir @@ -47,7 +47,7 @@ services: peer-node-1: user: '1000:1000' container_name: peer-node-1 - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data server broker peer-node-1 NORMAL false stop_signal: SIGINT working_dir: /symbol-workdir @@ -71,7 +71,7 @@ services: api-node-0: user: '1000:1000' container_name: api-node-0 - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data server broker api-node-0 NORMAL true stop_signal: SIGINT working_dir: /symbol-workdir @@ -90,7 +90,7 @@ services: api-node-broker-0: user: '1000:1000' container_name: api-node-broker-0 - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' working_dir: /symbol-workdir command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data broker server api-node-broker-0 NORMAL ports: @@ -105,7 +105,7 @@ services: rest-gateway-0: container_name: rest-gateway-0 user: '1000:1000' - image: 'symbolplatform/symbol-rest:2.3.6' + image: 'symbolplatform/symbol-rest:2.3.8' command: npm start --prefix /app/catapult-rest/rest /symbol-workdir/rest.json stop_signal: SIGINT working_dir: /symbol-workdir diff --git a/test/composes/expected-docker-compose-bootstrap-custom.yml b/test/composes/expected-docker-compose-bootstrap-custom.yml index a34a85651..6ea33bda0 100644 --- a/test/composes/expected-docker-compose-bootstrap-custom.yml +++ b/test/composes/expected-docker-compose-bootstrap-custom.yml @@ -16,7 +16,7 @@ services: - '../databases/db-0:/dbdata:rw' peer-node-0: container_name: peer-node-0 - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data server broker peer-node-0 DEBUG false stop_signal: SIGINT working_dir: /symbol-workdir @@ -38,7 +38,7 @@ services: hostname: peer-node-0 peer-node-1: container_name: peer-node-1 - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data server broker peer-node-1 DEBUG false stop_signal: SIGINT working_dir: /symbol-workdir @@ -60,7 +60,7 @@ services: hostname: peer-node-1 api-node-0: container_name: api-node-0 - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data server broker api-node-0 DEBUG true stop_signal: SIGINT working_dir: /symbol-workdir @@ -83,7 +83,7 @@ services: hostname: api-node-0 api-node-broker-0: container_name: api-node-broker-0 - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' working_dir: /symbol-workdir command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data broker server api-node-broker-0 DEBUG ports: @@ -103,7 +103,7 @@ services: rest-gateway-0: container_name: rest-gateway-0 user: '1000:1000' - image: 'symbolplatform/symbol-rest:2.3.6' + image: 'symbolplatform/symbol-rest:2.3.8' command: npm start --prefix /app/catapult-rest/rest /symbol-workdir/rest.json stop_signal: SIGINT working_dir: /symbol-workdir diff --git a/test/composes/expected-docker-compose-bootstrap-full.yml b/test/composes/expected-docker-compose-bootstrap-full.yml index 508f6428f..54affdd07 100644 --- a/test/composes/expected-docker-compose-bootstrap-full.yml +++ b/test/composes/expected-docker-compose-bootstrap-full.yml @@ -21,7 +21,7 @@ services: privileged: true peer-node-0: container_name: peer-node-0 - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data server broker peer-node-0 DEBUG false stop_signal: SIGINT working_dir: /symbol-workdir @@ -43,7 +43,7 @@ services: hostname: peer-node-0 peer-node-1: container_name: peer-node-1 - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data server broker peer-node-1 DEBUG false stop_signal: SIGINT working_dir: /symbol-workdir @@ -65,7 +65,7 @@ services: hostname: peer-node-1 api-node-0: container_name: api-node-0 - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data server broker api-node-0 DEBUG true stop_signal: SIGINT working_dir: /symbol-workdir @@ -88,7 +88,7 @@ services: hostname: api-node-0 api-node-broker-0: container_name: api-node-broker-0 - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' working_dir: /symbol-workdir command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data broker server api-node-broker-0 DEBUG ports: @@ -108,7 +108,7 @@ services: rest-gateway-0: container_name: rest-gateway-0 user: '1000:1000' - image: 'symbolplatform/symbol-rest:2.3.6' + image: 'symbolplatform/symbol-rest:2.3.8' command: npm start --prefix /app/catapult-rest/rest /symbol-workdir/rest.json stop_signal: SIGINT working_dir: /symbol-workdir @@ -144,12 +144,12 @@ services: privileged: true explorer-0: container_name: explorer-0 - image: 'symbolplatform/symbol-explorer:0.6.3-alpha' - command: ash -c "/bin/ash /symbol-commands/run.sh explorer-0" + image: 'symbolplatform/symbol-explorer:1.1.0-alpha' + entrypoint: ash -c "/bin/ash /symbol-commands/run.sh explorer-0" stop_signal: SIGINT working_dir: /symbol-workdir ports: - - '90:80' + - '90:4000' restart: 'on-failure:2' volumes: - '../explorers/explorer-0:/symbol-workdir:ro' @@ -161,7 +161,7 @@ services: privileged: true faucet-0: container_name: faucet-0 - image: 'symbolplatform/symbol-faucet:0.5.0-alpha' + image: 'symbolplatform/symbol-faucet:1.0.1-alpha' stop_signal: SIGINT environment: DEFAULT_NODE: 'http://rest-gateway-0:3000' diff --git a/test/composes/expected-docker-compose-bootstrap-repeat.yml b/test/composes/expected-docker-compose-bootstrap-repeat.yml index 2c894adfa..8b81cdbed 100644 --- a/test/composes/expected-docker-compose-bootstrap-repeat.yml +++ b/test/composes/expected-docker-compose-bootstrap-repeat.yml @@ -59,7 +59,7 @@ services: peer-node-0: user: '1000:1000' container_name: peer-node-0 - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data server broker peer-node-0 NORMAL false stop_signal: SIGINT working_dir: /symbol-workdir @@ -77,7 +77,7 @@ services: peer-node-1: user: '1000:1000' container_name: peer-node-1 - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data server broker peer-node-1 NORMAL false stop_signal: SIGINT working_dir: /symbol-workdir @@ -95,7 +95,7 @@ services: peer-node-2: user: '1000:1000' container_name: peer-node-2 - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data server broker peer-node-2 NORMAL false stop_signal: SIGINT working_dir: /symbol-workdir @@ -113,7 +113,7 @@ services: api-node-0: user: '1000:1000' container_name: api-node-0 - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data server broker api-node-0 NORMAL true stop_signal: SIGINT working_dir: /symbol-workdir @@ -132,7 +132,7 @@ services: api-node-1: user: '1000:1000' container_name: api-node-1 - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data server broker api-node-1 NORMAL true stop_signal: SIGINT working_dir: /symbol-workdir @@ -151,7 +151,7 @@ services: api-node-2: user: '1000:1000' container_name: api-node-2 - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data server broker api-node-2 NORMAL true stop_signal: SIGINT working_dir: /symbol-workdir @@ -170,7 +170,7 @@ services: api-node-3: user: '1000:1000' container_name: api-node-3 - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data server broker api-node-3 NORMAL true stop_signal: SIGINT working_dir: /symbol-workdir @@ -189,7 +189,7 @@ services: api-node-broker-0: user: '1000:1000' container_name: api-node-broker-0 - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' working_dir: /symbol-workdir command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data broker server api-node-broker-0 NORMAL ports: @@ -204,7 +204,7 @@ services: api-node-broker-1: user: '1000:1000' container_name: api-node-broker-1 - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' working_dir: /symbol-workdir command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data broker server api-node-broker-1 NORMAL ports: @@ -219,7 +219,7 @@ services: api-node-broker-2: user: '1000:1000' container_name: api-node-broker-2 - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' working_dir: /symbol-workdir command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data broker server api-node-broker-2 NORMAL ports: @@ -234,7 +234,7 @@ services: api-node-broker-3: user: '1000:1000' container_name: api-node-broker-3 - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' working_dir: /symbol-workdir command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data broker server api-node-broker-3 NORMAL ports: @@ -249,7 +249,7 @@ services: rest-gateway-0: container_name: rest-gateway-0 user: '1000:1000' - image: 'symbolplatform/symbol-rest:2.3.6' + image: 'symbolplatform/symbol-rest:2.3.8' command: npm start --prefix /app/catapult-rest/rest /symbol-workdir/rest.json stop_signal: SIGINT working_dir: /symbol-workdir @@ -266,7 +266,7 @@ services: rest-gateway-1: container_name: rest-gateway-1 user: '1000:1000' - image: 'symbolplatform/symbol-rest:2.3.6' + image: 'symbolplatform/symbol-rest:2.3.8' command: npm start --prefix /app/catapult-rest/rest /symbol-workdir/rest.json stop_signal: SIGINT working_dir: /symbol-workdir @@ -283,7 +283,7 @@ services: rest-gateway-2: container_name: rest-gateway-2 user: '1000:1000' - image: 'symbolplatform/symbol-rest:2.3.6' + image: 'symbolplatform/symbol-rest:2.3.8' command: npm start --prefix /app/catapult-rest/rest /symbol-workdir/rest.json stop_signal: SIGINT working_dir: /symbol-workdir @@ -300,7 +300,7 @@ services: rest-gateway-3: container_name: rest-gateway-3 user: '1000:1000' - image: 'symbolplatform/symbol-rest:2.3.6' + image: 'symbolplatform/symbol-rest:2.3.8' command: npm start --prefix /app/catapult-rest/rest /symbol-workdir/rest.json stop_signal: SIGINT working_dir: /symbol-workdir @@ -336,43 +336,43 @@ services: - '../wallets/wallet-1:/usr/share/nginx/html/config:ro' explorer-0: container_name: explorer-0 - image: 'symbolplatform/symbol-explorer:0.6.3-alpha' - command: ash -c "/bin/ash /symbol-commands/run.sh explorer-0" + image: 'symbolplatform/symbol-explorer:1.1.0-alpha' + entrypoint: ash -c "/bin/ash /symbol-commands/run.sh explorer-0" stop_signal: SIGINT working_dir: /symbol-workdir ports: - - '90:80' + - '90:4000' restart: 'on-failure:2' volumes: - '../explorers/explorer-0:/symbol-workdir:ro' - './explorer:/symbol-commands:ro' explorer-1: container_name: explorer-1 - image: 'symbolplatform/symbol-explorer:0.6.3-alpha' - command: ash -c "/bin/ash /symbol-commands/run.sh explorer-1" + image: 'symbolplatform/symbol-explorer:1.1.0-alpha' + entrypoint: ash -c "/bin/ash /symbol-commands/run.sh explorer-1" stop_signal: SIGINT working_dir: /symbol-workdir ports: - - '91:80' + - '91:4000' restart: 'on-failure:2' volumes: - '../explorers/explorer-1:/symbol-workdir:ro' - './explorer:/symbol-commands:ro' explorer-2: container_name: explorer-2 - image: 'symbolplatform/symbol-explorer:0.6.3-alpha' - command: ash -c "/bin/ash /symbol-commands/run.sh explorer-2" + image: 'symbolplatform/symbol-explorer:1.1.0-alpha' + entrypoint: ash -c "/bin/ash /symbol-commands/run.sh explorer-2" stop_signal: SIGINT working_dir: /symbol-workdir ports: - - '92:80' + - '92:4000' restart: 'on-failure:2' volumes: - '../explorers/explorer-2:/symbol-workdir:ro' - './explorer:/symbol-commands:ro' faucet-0: container_name: faucet-0 - image: 'symbolplatform/symbol-faucet:0.5.0-alpha' + image: 'symbolplatform/symbol-faucet:1.0.1-alpha' stop_signal: SIGINT environment: DEFAULT_NODE: 'http://rest-gateway-0:3000' @@ -394,7 +394,7 @@ services: - rest-gateway-0 faucet-1: container_name: faucet-1 - image: 'symbolplatform/symbol-faucet:0.5.0-alpha' + image: 'symbolplatform/symbol-faucet:1.0.1-alpha' stop_signal: SIGINT environment: DEFAULT_NODE: 'http://rest-gateway-1:3001' @@ -416,7 +416,7 @@ services: - rest-gateway-1 faucet-2: container_name: faucet-2 - image: 'symbolplatform/symbol-faucet:0.5.0-alpha' + image: 'symbolplatform/symbol-faucet:1.0.1-alpha' stop_signal: SIGINT environment: DEFAULT_NODE: 'http://rest-gateway-2:3002' @@ -438,7 +438,7 @@ services: - rest-gateway-2 faucet-3: container_name: faucet-3 - image: 'symbolplatform/symbol-faucet:0.5.0-alpha' + image: 'symbolplatform/symbol-faucet:1.0.1-alpha' stop_signal: SIGINT environment: DEFAULT_NODE: 'http://rest-gateway-3:3003' diff --git a/test/composes/expected-docker-compose-bootstrap.yml b/test/composes/expected-docker-compose-bootstrap.yml index 8c1ac2a37..7a8a73182 100644 --- a/test/composes/expected-docker-compose-bootstrap.yml +++ b/test/composes/expected-docker-compose-bootstrap.yml @@ -17,7 +17,7 @@ services: peer-node-0: user: '1000:1000' container_name: peer-node-0 - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data server broker peer-node-0 NORMAL false stop_signal: SIGINT working_dir: /symbol-workdir @@ -35,7 +35,7 @@ services: peer-node-1: user: '1000:1000' container_name: peer-node-1 - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data server broker peer-node-1 NORMAL false stop_signal: SIGINT working_dir: /symbol-workdir @@ -53,7 +53,7 @@ services: api-node-0: user: '1000:1000' container_name: api-node-0 - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data server broker api-node-0 NORMAL true stop_signal: SIGINT working_dir: /symbol-workdir @@ -72,7 +72,7 @@ services: api-node-broker-0: user: '1000:1000' container_name: api-node-broker-0 - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' working_dir: /symbol-workdir command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data broker server api-node-broker-0 NORMAL ports: @@ -87,7 +87,7 @@ services: rest-gateway-0: container_name: rest-gateway-0 user: '1000:1000' - image: 'symbolplatform/symbol-rest:2.3.6' + image: 'symbolplatform/symbol-rest:2.3.8' command: npm start --prefix /app/catapult-rest/rest /symbol-workdir/rest.json stop_signal: SIGINT working_dir: /symbol-workdir diff --git a/test/composes/expected-mainnet-api-compose.yml b/test/composes/expected-mainnet-api-compose.yml index 294183fde..595f715e3 100644 --- a/test/composes/expected-mainnet-api-compose.yml +++ b/test/composes/expected-mainnet-api-compose.yml @@ -15,7 +15,7 @@ services: node: user: '1000:1000' container_name: node - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data server broker node NORMAL true stop_signal: SIGINT working_dir: /symbol-workdir @@ -31,7 +31,7 @@ services: broker: user: '1000:1000' container_name: broker - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' working_dir: /symbol-workdir command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data broker server broker NORMAL stop_signal: SIGINT @@ -44,7 +44,7 @@ services: rest-gateway: container_name: rest-gateway user: '1000:1000' - image: 'symbolplatform/symbol-rest:2.3.6' + image: 'symbolplatform/symbol-rest:2.3.8' command: npm start --prefix /app/catapult-rest/rest /symbol-workdir/rest.json stop_signal: SIGINT working_dir: /symbol-workdir diff --git a/test/composes/expected-mainnet-dual-compose.yml b/test/composes/expected-mainnet-dual-compose.yml index 294183fde..595f715e3 100644 --- a/test/composes/expected-mainnet-dual-compose.yml +++ b/test/composes/expected-mainnet-dual-compose.yml @@ -15,7 +15,7 @@ services: node: user: '1000:1000' container_name: node - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data server broker node NORMAL true stop_signal: SIGINT working_dir: /symbol-workdir @@ -31,7 +31,7 @@ services: broker: user: '1000:1000' container_name: broker - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' working_dir: /symbol-workdir command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data broker server broker NORMAL stop_signal: SIGINT @@ -44,7 +44,7 @@ services: rest-gateway: container_name: rest-gateway user: '1000:1000' - image: 'symbolplatform/symbol-rest:2.3.6' + image: 'symbolplatform/symbol-rest:2.3.8' command: npm start --prefix /app/catapult-rest/rest /symbol-workdir/rest.json stop_signal: SIGINT working_dir: /symbol-workdir diff --git a/test/composes/expected-mainnet-peer-compose.yml b/test/composes/expected-mainnet-peer-compose.yml index c9375c8c4..35ab9e768 100644 --- a/test/composes/expected-mainnet-peer-compose.yml +++ b/test/composes/expected-mainnet-peer-compose.yml @@ -3,7 +3,7 @@ services: node: user: '1000:1000' container_name: node - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data server broker node NORMAL false stop_signal: SIGINT working_dir: /symbol-workdir diff --git a/test/composes/expected-testnet-api-compose.yml b/test/composes/expected-testnet-api-compose.yml index 294183fde..595f715e3 100644 --- a/test/composes/expected-testnet-api-compose.yml +++ b/test/composes/expected-testnet-api-compose.yml @@ -15,7 +15,7 @@ services: node: user: '1000:1000' container_name: node - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data server broker node NORMAL true stop_signal: SIGINT working_dir: /symbol-workdir @@ -31,7 +31,7 @@ services: broker: user: '1000:1000' container_name: broker - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' working_dir: /symbol-workdir command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data broker server broker NORMAL stop_signal: SIGINT @@ -44,7 +44,7 @@ services: rest-gateway: container_name: rest-gateway user: '1000:1000' - image: 'symbolplatform/symbol-rest:2.3.6' + image: 'symbolplatform/symbol-rest:2.3.8' command: npm start --prefix /app/catapult-rest/rest /symbol-workdir/rest.json stop_signal: SIGINT working_dir: /symbol-workdir diff --git a/test/composes/expected-testnet-dual-compose.yml b/test/composes/expected-testnet-dual-compose.yml index 294183fde..595f715e3 100644 --- a/test/composes/expected-testnet-dual-compose.yml +++ b/test/composes/expected-testnet-dual-compose.yml @@ -15,7 +15,7 @@ services: node: user: '1000:1000' container_name: node - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data server broker node NORMAL true stop_signal: SIGINT working_dir: /symbol-workdir @@ -31,7 +31,7 @@ services: broker: user: '1000:1000' container_name: broker - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' working_dir: /symbol-workdir command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data broker server broker NORMAL stop_signal: SIGINT @@ -44,7 +44,7 @@ services: rest-gateway: container_name: rest-gateway user: '1000:1000' - image: 'symbolplatform/symbol-rest:2.3.6' + image: 'symbolplatform/symbol-rest:2.3.8' command: npm start --prefix /app/catapult-rest/rest /symbol-workdir/rest.json stop_signal: SIGINT working_dir: /symbol-workdir diff --git a/test/composes/expected-testnet-supernode-compose.yml b/test/composes/expected-testnet-httpsproxy-compose.yml similarity index 75% rename from test/composes/expected-testnet-supernode-compose.yml rename to test/composes/expected-testnet-httpsproxy-compose.yml index 568c67daf..98001db32 100644 --- a/test/composes/expected-testnet-supernode-compose.yml +++ b/test/composes/expected-testnet-httpsproxy-compose.yml @@ -15,7 +15,7 @@ services: node: user: '1000:1000' container_name: node - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data server broker node NORMAL true stop_signal: SIGINT working_dir: /symbol-workdir @@ -31,12 +31,12 @@ services: networks: default: aliases: - - fboucquez-agent-symbollocal.ngrok.io - hostname: fboucquez-agent-symbollocal.ngrok.io + - symbol-node-2.rockbear.io + hostname: symbol-node-2.rockbear.io broker: user: '1000:1000' container_name: broker - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' working_dir: /symbol-workdir command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data broker server broker NORMAL stop_signal: SIGINT @@ -46,22 +46,10 @@ services: - './server:/symbol-commands:ro' depends_on: - db - node-agent: - user: '1000:1000' - container_name: node-agent - image: 'symbolplatform/symbol-node-rewards-agent:2.0.0' - working_dir: /symbol-workdir - entrypoint: /app/agent-linux.bin --config agent.properties - ports: - - '7881:7881' - stop_signal: SIGINT - restart: 'on-failure:2' - volumes: - - '../nodes/node/agent:/symbol-workdir:rw' rest-gateway: container_name: rest-gateway user: '1000:1000' - image: 'symbolplatform/symbol-rest:2.3.6' + image: 'symbolplatform/symbol-rest:2.3.8' command: npm start --prefix /app/catapult-rest/rest /symbol-workdir/rest.json stop_signal: SIGINT working_dir: /symbol-workdir @@ -75,6 +63,21 @@ services: networks: default: ipv4_address: 172.20.0.25 + https-proxy: + container_name: https-proxy + image: 'steveltn/https-portal:1.19' + stop_signal: SIGINT + ports: + - '80:80' + - '3001:443' + environment: + DOMAINS: 'symbol-node-2.rockbear.io -> http://rest-gateway:3000' + WEBSOCKET: 'true' + STAGE: production + SERVER_NAMES_HASH_BUCKET_SIZE: 128 + restart: 'on-failure:2' + depends_on: + - rest-gateway networks: default: ipam: diff --git a/test/composes/expected-testnet-native-ssl-compose.yml b/test/composes/expected-testnet-native-ssl-compose.yml new file mode 100644 index 000000000..32a78d735 --- /dev/null +++ b/test/composes/expected-testnet-native-ssl-compose.yml @@ -0,0 +1,70 @@ +version: '2.4' +services: + db: + user: '1000:1000' + environment: + MONGO_INITDB_DATABASE: catapult + container_name: db + image: 'mongo:4.4.3-bionic' + command: mongod --dbpath=/dbdata --bind_ip=db --wiredTigerCacheSizeGB 2 + stop_signal: SIGINT + working_dir: /docker-entrypoint-initdb.d + volumes: + - './mongo:/docker-entrypoint-initdb.d:ro' + - '../databases/db:/dbdata:rw' + node: + user: '1000:1000' + container_name: node + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' + command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data server broker node NORMAL true + stop_signal: SIGINT + working_dir: /symbol-workdir + restart: 'on-failure:2' + ports: + - '7900:7900' + volumes: + - '../nodes/node:/symbol-workdir:rw' + - './server:/symbol-commands:ro' + depends_on: + - db + - broker + networks: + default: + aliases: + - symbol-node-2.rockbear.io + hostname: symbol-node-2.rockbear.io + broker: + user: '1000:1000' + container_name: broker + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' + working_dir: /symbol-workdir + command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data broker server broker NORMAL + stop_signal: SIGINT + restart: 'on-failure:2' + volumes: + - '../nodes/node:/symbol-workdir:rw' + - './server:/symbol-commands:ro' + depends_on: + - db + rest-gateway: + container_name: rest-gateway + user: '1000:1000' + image: 'symbolplatform/symbol-rest:2.3.8' + command: npm start --prefix /app/catapult-rest/rest /symbol-workdir/rest.json + stop_signal: SIGINT + working_dir: /symbol-workdir + ports: + - '3001:3000' + restart: 'on-failure:2' + volumes: + - '../gateways/rest-gateway:/symbol-workdir:rw' + depends_on: + - db + networks: + default: + ipv4_address: 172.20.0.25 +networks: + default: + ipam: + config: + - subnet: 172.20.0.0/24 diff --git a/test/composes/expected-testnet-peer-compose.yml b/test/composes/expected-testnet-peer-compose.yml index c9375c8c4..35ab9e768 100644 --- a/test/composes/expected-testnet-peer-compose.yml +++ b/test/composes/expected-testnet-peer-compose.yml @@ -3,7 +3,7 @@ services: node: user: '1000:1000' container_name: node - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data server broker node NORMAL false stop_signal: SIGINT working_dir: /symbol-workdir diff --git a/test/composes/expected-testnet-voting-compose.yml b/test/composes/expected-testnet-voting-compose.yml index 294183fde..595f715e3 100644 --- a/test/composes/expected-testnet-voting-compose.yml +++ b/test/composes/expected-testnet-voting-compose.yml @@ -15,7 +15,7 @@ services: node: user: '1000:1000' container_name: node - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data server broker node NORMAL true stop_signal: SIGINT working_dir: /symbol-workdir @@ -31,7 +31,7 @@ services: broker: user: '1000:1000' container_name: broker - image: 'symbolplatform/symbol-server:gcc-10-1.0.2.0' + image: 'symbolplatform/symbol-server:gcc-10-1.0.3.0' working_dir: /symbol-workdir command: /bin/bash /symbol-commands/start.sh /usr/catapult ./data broker server broker NORMAL stop_signal: SIGINT @@ -44,7 +44,7 @@ services: rest-gateway: container_name: rest-gateway user: '1000:1000' - image: 'symbolplatform/symbol-rest:2.3.6' + image: 'symbolplatform/symbol-rest:2.3.8' command: npm start --prefix /app/catapult-rest/rest /symbol-workdir/rest.json stop_signal: SIGINT working_dir: /symbol-workdir diff --git a/test/encrypt/encrypted.yml b/test/encrypt/encrypted.yml index 0147453af..26f1f396a 100644 --- a/test/encrypt/encrypted.yml +++ b/test/encrypt/encrypted.yml @@ -1,9 +1,6 @@ nodes: - voting: true - rewardProgram: supernode - host: fboucquez-agent-symbollocal.ngrok.io - agentUrl: 'https://fboucquez-agent-symbollocal.ngrok.io' - restGatewayUrl: 'http://fboucquez-rest-gateway-symbollocal.ngrok.io' + host: mynode-symbollocal.io mainPrivateKey: >- ENCRYPTED:f9afc36baf705c11e7296b30e19c93ba8804aaf1992919fe8028f5ee177ecae96pdL7NWppSmu8HQb0oVtPEAsjeH1OhgaTQuoNgX1xZrYoIOOhcI895nmkfzZBOJ8K0bNZT2oEiSn9iSksbhWHcVY6Paho71zyVTuTRG1tkI= transportPrivateKey: >- diff --git a/test/encrypt/plain.yml b/test/encrypt/plain.yml index 891c74717..f8b71597b 100644 --- a/test/encrypt/plain.yml +++ b/test/encrypt/plain.yml @@ -1,9 +1,6 @@ nodes: - voting: true - rewardProgram: 'supernode' - host: fboucquez-agent-symbollocal.ngrok.io - agentUrl: https://fboucquez-agent-symbollocal.ngrok.io - restGatewayUrl: http://fboucquez-rest-gateway-symbollocal.ngrok.io + host: mynode-symbollocal.io mainPrivateKey: CA82E7ADAF7AB729A5462A1BD5AA78632390634904A64EB1BB22295E2E1A1BDD transportPrivateKey: 6154154096354BC3DB522174ACD8BFE553893A0991BD5D105599846F17A3383B vrfPrivateKey: F3C24C153783B683E40FB2671493B54480370BF4E3AB8027D4BF1293E14EB9B8 diff --git a/test/mainnet_preset.yml b/test/mainnet_preset.yml index 48bde1ed4..63dbafb65 100644 --- a/test/mainnet_preset.yml +++ b/test/mainnet_preset.yml @@ -1,5 +1,3 @@ privateKeySecurityMode: ENCRYPT nodes: - voting: true - rewardProgram: 'supernode' - host: mySuperNodeHostName diff --git a/test/reports/bootstrap-voting/api-node-0-config.csv b/test/reports/bootstrap-voting/api-node-0-config.csv index 7552e623b..38084fad5 100644 --- a/test/reports/bootstrap-voting/api-node-0-config.csv +++ b/test/reports/bootstrap-voting/api-node-0-config.csv @@ -73,6 +73,9 @@ messageSynchronizationMaxResponseSize; 20MB maxHashesPerPoint; 256 prevoteBlocksMultiple; 4 unfinalizedBlocksDuration; 8m +treasuryReissuanceEpoch; 0 + +treasury_reissuance_epoch_ineligible_voter_addresses config-inflation.properties @@ -149,7 +152,7 @@ listenInterface; 0.0.0.0 config-network.properties network -identifier; public-test; NetworkIdentifier; Network identifier. +identifier; testnet; NetworkIdentifier; Network identifier. nemesisSignerPublicKey; DA007A7CCA877805DF0DD6250C9806E7B25DC3ED21E506569239D11A7175101A; Key; Nemesis public key. nodeEqualityStrategy; host; NodeIdentityEqualityStrategy; Node equality strategy. generationHashSeed; 6AF8E35BBC7AC341E7931B39E2C9A591EDBE9F9111996053E6771D48E9C53B31; ; @@ -181,11 +184,11 @@ minVotingKeyLifetime; 28; uint32_t; Minimum number of finalization rounds for wh maxVotingKeyLifetime; 26280; uint32_t; Maximum number of finalization rounds for which voting key can be registered. harvestBeneficiaryPercentage; 10; uint8_t; Percentage of the harvested fee that is collected by the beneficiary account. harvestNetworkPercentage; 5; uint8_t; Percentage of the harvested fee that is collected by the network. +harvestNetworkFeeSinkAddressV1; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; ; harvestNetworkFeeSinkAddress; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; Address; Address of the harvest network fee sink account. maxTransactionsPerBlock; 6'000; uint32_t; Maximum number of transactions per block. - -fork_heights -totalVotingBalanceCalculationFix; 0; uint32_t; Height of fork to fix TotalVotingBalance calculation. +treasuryReissuanceBlockTransactionsHash; 0000000000000000000000000000000000000000000000000000000000000000; ; +treasuryReissuanceFallbackBlockTransactionsHash; 0000000000000000000000000000000000000000000000000000000000000000; ; plugin:catapult.plugins.accountlink dummy; to trigger plugin load @@ -213,6 +216,7 @@ plugin:catapult.plugins.mosaic maxMosaicsPerAccount; 1'000; uint16_t; Maximum number of mosaics that an account can own. maxMosaicDuration; 3650d; utils::BlockSpan; Maximum mosaic duration. maxMosaicDivisibility; 6; uint8_t; Maximum mosaic divisibility. +mosaicRentalFeeSinkAddressV1; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; ; mosaicRentalFeeSinkAddress; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; Address; Address of the mosaic rental fee sink account. mosaicRentalFee; 500; Amount; Mosaic rental fee. @@ -229,6 +233,7 @@ minNamespaceDuration; 1m; utils::BlockSpan; Minimum namespace duration. maxNamespaceDuration; 365d; utils::BlockSpan; Maximum namespace duration. namespaceGracePeriodDuration; 30d; utils::BlockSpan; Grace period during which time only the previous owner can renew an expired namespace. reservedRootNamespaceNames; symbol, symbl, xym, xem, nem, user, account, org, com, biz, net, edu, mil, gov, info; unordered_set; Reserved root namespaces that cannot be claimed. +namespaceRentalFeeSinkAddressV1; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; ; namespaceRentalFeeSinkAddress; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; Address; Address of the namespace rental fee sink account. rootNamespaceRentalFeePerBlock; 1; Amount; Root namespace rental fee per block. childNamespaceRentalFee; 100; Amount; Child namespace rental fee. @@ -242,6 +247,14 @@ maxMosaicRestrictionValues; 20; uint8_t; Maximum number of mosaic restriction va plugin:catapult.plugins.transfer maxMessageSize; 1024; uint16_t; Maximum transaction message size. +fork_heights +totalVotingBalanceCalculationFix; 0; uint32_t; Height of fork to fix TotalVotingBalance calculation. +treasuryReissuance; 0; ; + +treasury_reissuance_transaction_signatures + +treasury_reissuance_fallback_transaction_signatures + config-node.properties node @@ -262,7 +275,7 @@ shortLivedCacheBlockDuration; 100m; utils::TimeSpan; Duration of a block in the shortLivedCachePruneInterval; 90s; utils::TimeSpan; Time between short lived cache pruning. shortLivedCacheMaxSize; 10'000'000; uint32_t; Maximum size of a short lived cache. minFeeMultiplier; 100; BlockFeeMultiplier; Minimum fee multiplier of transactions to propagate and include in blocks. -maxTimeBehindPullTransactionsStart; 5m; ; +maxTimeBehindPullTransactionsStart; 24h; ; transactionSelectionStrategy; oldest; model::TransactionSelectionStrategy; Transaction selection strategy used for syncing and harvesting unconfirmed transactions. unconfirmedTransactionsCacheMaxResponseSize; 5MB; utils::FileSize; Maximum size of an unconfirmed transactions response. unconfirmedTransactionsCacheMaxSize; 20MB; uint32_t; Maximum size of the unconfirmed transactions cache. @@ -280,7 +293,7 @@ transactionDisruptorMaxMemorySize; 20MB; ; enableDispatcherAbortWhenFull; false; bool; Set to true if the process should terminate when any dispatcher is full. enableDispatcherInputAuditing; false; bool; Set to true if all dispatcher inputs should be audited. maxTrackedNodes; 5'000; uint32_t; Maximum number of nodes to track in memory. -minPartnerNodeVersion; 1.0.1.0; ; +minPartnerNodeVersion; 1.0.2.0; ; maxPartnerNodeVersion; 1.0.255.255; ; trustedHosts; 127.0.0.1, 172.20.0.25; unordered_set; Trusted hosts that are allowed to execute protected API calls on this node. localNetworks; 127.0.0.1, 172.20.0.25; unordered_set; Networks that should be treated as local. @@ -298,7 +311,7 @@ maxWriteBatchSize; 5MB localnode host; api-node-0; string; Node host (leave empty to auto-detect IP). friendlyName; my-api-node-0; string; Node friendly name (leave empty to use address). -version; 1.0.2.0; uint32_t; Node version. +version; ; uint32_t; Node version. roles; Api; ionet::NodeRoles; Node roles. outgoing_connections @@ -434,4 +447,4 @@ seedDirectory; ./seed certificateDirectory; ./cert dataDirectory; ./data pluginsDirectory; /usr/catapult/lib -votingKeysDirectory; ./votingkeys \ No newline at end of file +votingKeysDirectory; ./votingkeys diff --git a/test/reports/bootstrap-voting/api-node-0-config.rst b/test/reports/bootstrap-voting/api-node-0-config.rst index 1ce9977dc..81dc5de9d 100644 --- a/test/reports/bootstrap-voting/api-node-0-config.rst +++ b/test/reports/bootstrap-voting/api-node-0-config.rst @@ -93,6 +93,8 @@ config-finalization.properties maxHashesPerPoint; 256 prevoteBlocksMultiple; 4 unfinalizedBlocksDuration; 8m + treasuryReissuanceEpoch; 0 + **treasury_reissuance_epoch_ineligible_voter_addresses**; config-inflation.properties =========================== @@ -184,7 +186,7 @@ config-network.properties :delim: ; **network**; ; ; - identifier; public-test; NetworkIdentifier; Network identifier. + identifier; testnet; NetworkIdentifier; Network identifier. nemesisSignerPublicKey; DA007A7CCA877805DF0DD6250C9806E7B25DC3ED21E506569239D11A7175101A; Key; Nemesis public key. nodeEqualityStrategy; host; NodeIdentityEqualityStrategy; Node equality strategy. generationHashSeed; 6AF8E35BBC7AC341E7931B39E2C9A591EDBE9F9111996053E6771D48E9C53B31; ; @@ -215,10 +217,11 @@ config-network.properties maxVotingKeyLifetime; 26280; uint32_t; Maximum number of finalization rounds for which voting key can be registered. harvestBeneficiaryPercentage; 10; uint8_t; Percentage of the harvested fee that is collected by the beneficiary account. harvestNetworkPercentage; 5; uint8_t; Percentage of the harvested fee that is collected by the network. + harvestNetworkFeeSinkAddressV1; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; ; harvestNetworkFeeSinkAddress; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; Address; Address of the harvest network fee sink account. maxTransactionsPerBlock; 6'000; uint32_t; Maximum number of transactions per block. - **fork_heights**; ; ; - totalVotingBalanceCalculationFix; 0; uint32_t; Height of fork to fix TotalVotingBalance calculation. + treasuryReissuanceBlockTransactionsHash; 0000000000000000000000000000000000000000000000000000000000000000; ; + treasuryReissuanceFallbackBlockTransactionsHash; 0000000000000000000000000000000000000000000000000000000000000000; ; **plugin:catapult.plugins.accountlink**; dummy; to trigger plugin load **plugin:catapult.plugins.aggregate**; ; ; @@ -240,6 +243,7 @@ config-network.properties maxMosaicsPerAccount; 1'000; uint16_t; Maximum number of mosaics that an account can own. maxMosaicDuration; 3650d; utils::BlockSpan; Maximum mosaic duration. maxMosaicDivisibility; 6; uint8_t; Maximum mosaic divisibility. + mosaicRentalFeeSinkAddressV1; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; ; mosaicRentalFeeSinkAddress; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; Address; Address of the mosaic rental fee sink account. mosaicRentalFee; 500; Amount; Mosaic rental fee. **plugin:catapult.plugins.multisig**; ; ; @@ -254,6 +258,7 @@ config-network.properties maxNamespaceDuration; 365d; utils::BlockSpan; Maximum namespace duration. namespaceGracePeriodDuration; 30d; utils::BlockSpan; Grace period during which time only the previous owner can renew an expired namespace. reservedRootNamespaceNames; symbol, symbl, xym, xem, nem, user, account, org, com, biz, net, edu, mil, gov, info; unordered_set; Reserved root namespaces that cannot be claimed. + namespaceRentalFeeSinkAddressV1; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; ; namespaceRentalFeeSinkAddress; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; Address; Address of the namespace rental fee sink account. rootNamespaceRentalFeePerBlock; 1; Amount; Root namespace rental fee per block. childNamespaceRentalFee; 100; Amount; Child namespace rental fee. @@ -263,6 +268,11 @@ config-network.properties maxMosaicRestrictionValues; 20; uint8_t; Maximum number of mosaic restriction values. **plugin:catapult.plugins.transfer**; ; ; maxMessageSize; 1024; uint16_t; Maximum transaction message size. + **fork_heights**; ; ; + totalVotingBalanceCalculationFix; 0; uint32_t; Height of fork to fix TotalVotingBalance calculation. + treasuryReissuance; 0; ; + **treasury_reissuance_transaction_signatures**; + **treasury_reissuance_fallback_transaction_signatures**; config-node.properties ====================== @@ -288,7 +298,7 @@ config-node.properties shortLivedCachePruneInterval; 90s; utils::TimeSpan; Time between short lived cache pruning. shortLivedCacheMaxSize; 10'000'000; uint32_t; Maximum size of a short lived cache. minFeeMultiplier; 100; BlockFeeMultiplier; Minimum fee multiplier of transactions to propagate and include in blocks. - maxTimeBehindPullTransactionsStart; 5m; ; + maxTimeBehindPullTransactionsStart; 24h; ; transactionSelectionStrategy; oldest; model::TransactionSelectionStrategy; Transaction selection strategy used for syncing and harvesting unconfirmed transactions. unconfirmedTransactionsCacheMaxResponseSize; 5MB; utils::FileSize; Maximum size of an unconfirmed transactions response. unconfirmedTransactionsCacheMaxSize; 20MB; uint32_t; Maximum size of the unconfirmed transactions cache. @@ -306,7 +316,7 @@ config-node.properties enableDispatcherAbortWhenFull; false; bool; Set to true if the process should terminate when any dispatcher is full. enableDispatcherInputAuditing; false; bool; Set to true if all dispatcher inputs should be audited. maxTrackedNodes; 5'000; uint32_t; Maximum number of nodes to track in memory. - minPartnerNodeVersion; 1.0.1.0; ; + minPartnerNodeVersion; 1.0.2.0; ; maxPartnerNodeVersion; 1.0.255.255; ; trustedHosts; 127.0.0.1, 172.20.0.25; unordered_set; Trusted hosts that are allowed to execute protected API calls on this node. localNetworks; 127.0.0.1, 172.20.0.25; unordered_set; Networks that should be treated as local. @@ -322,7 +332,7 @@ config-node.properties **localnode**; ; ; host; api-node-0; string; Node host (leave empty to auto-detect IP). friendlyName; my-api-node-0; string; Node friendly name (leave empty to use address). - version; 1.0.2.0; uint32_t; Node version. + version; ; uint32_t; Node version. roles; Api; ionet::NodeRoles; Node roles. **outgoing_connections**; ; ; maxConnections; 10; uint16_t; Maximum number of active connections. @@ -452,4 +462,4 @@ config-user.properties certificateDirectory; ./cert dataDirectory; ./data pluginsDirectory; /usr/catapult/lib - votingKeysDirectory; ./votingkeys \ No newline at end of file + votingKeysDirectory; ./votingkeys diff --git a/test/reports/bootstrap-voting/peer-node-0-config.csv b/test/reports/bootstrap-voting/peer-node-0-config.csv index 612300e67..f3c051101 100644 --- a/test/reports/bootstrap-voting/peer-node-0-config.csv +++ b/test/reports/bootstrap-voting/peer-node-0-config.csv @@ -73,6 +73,9 @@ messageSynchronizationMaxResponseSize; 20MB maxHashesPerPoint; 256 prevoteBlocksMultiple; 4 unfinalizedBlocksDuration; 0m +treasuryReissuanceEpoch; 0 + +treasury_reissuance_epoch_ineligible_voter_addresses config-harvesting.properties @@ -159,7 +162,7 @@ listenInterface; 0.0.0.0 config-network.properties network -identifier; public-test; NetworkIdentifier; Network identifier. +identifier; testnet; NetworkIdentifier; Network identifier. nemesisSignerPublicKey; DA007A7CCA877805DF0DD6250C9806E7B25DC3ED21E506569239D11A7175101A; Key; Nemesis public key. nodeEqualityStrategy; host; NodeIdentityEqualityStrategy; Node equality strategy. generationHashSeed; 6AF8E35BBC7AC341E7931B39E2C9A591EDBE9F9111996053E6771D48E9C53B31; ; @@ -191,11 +194,11 @@ minVotingKeyLifetime; 28; uint32_t; Minimum number of finalization rounds for wh maxVotingKeyLifetime; 26280; uint32_t; Maximum number of finalization rounds for which voting key can be registered. harvestBeneficiaryPercentage; 10; uint8_t; Percentage of the harvested fee that is collected by the beneficiary account. harvestNetworkPercentage; 5; uint8_t; Percentage of the harvested fee that is collected by the network. +harvestNetworkFeeSinkAddressV1; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; ; harvestNetworkFeeSinkAddress; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; Address; Address of the harvest network fee sink account. maxTransactionsPerBlock; 6'000; uint32_t; Maximum number of transactions per block. - -fork_heights -totalVotingBalanceCalculationFix; 0; uint32_t; Height of fork to fix TotalVotingBalance calculation. +treasuryReissuanceBlockTransactionsHash; 0000000000000000000000000000000000000000000000000000000000000000; ; +treasuryReissuanceFallbackBlockTransactionsHash; 0000000000000000000000000000000000000000000000000000000000000000; ; plugin:catapult.plugins.accountlink dummy; to trigger plugin load @@ -223,6 +226,7 @@ plugin:catapult.plugins.mosaic maxMosaicsPerAccount; 1'000; uint16_t; Maximum number of mosaics that an account can own. maxMosaicDuration; 3650d; utils::BlockSpan; Maximum mosaic duration. maxMosaicDivisibility; 6; uint8_t; Maximum mosaic divisibility. +mosaicRentalFeeSinkAddressV1; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; ; mosaicRentalFeeSinkAddress; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; Address; Address of the mosaic rental fee sink account. mosaicRentalFee; 500; Amount; Mosaic rental fee. @@ -239,6 +243,7 @@ minNamespaceDuration; 1m; utils::BlockSpan; Minimum namespace duration. maxNamespaceDuration; 365d; utils::BlockSpan; Maximum namespace duration. namespaceGracePeriodDuration; 30d; utils::BlockSpan; Grace period during which time only the previous owner can renew an expired namespace. reservedRootNamespaceNames; symbol, symbl, xym, xem, nem, user, account, org, com, biz, net, edu, mil, gov, info; unordered_set; Reserved root namespaces that cannot be claimed. +namespaceRentalFeeSinkAddressV1; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; ; namespaceRentalFeeSinkAddress; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; Address; Address of the namespace rental fee sink account. rootNamespaceRentalFeePerBlock; 1; Amount; Root namespace rental fee per block. childNamespaceRentalFee; 100; Amount; Child namespace rental fee. @@ -252,6 +257,14 @@ maxMosaicRestrictionValues; 20; uint8_t; Maximum number of mosaic restriction va plugin:catapult.plugins.transfer maxMessageSize; 1024; uint16_t; Maximum transaction message size. +fork_heights +totalVotingBalanceCalculationFix; 0; uint32_t; Height of fork to fix TotalVotingBalance calculation. +treasuryReissuance; 0; ; + +treasury_reissuance_transaction_signatures + +treasury_reissuance_fallback_transaction_signatures + config-node.properties node @@ -272,7 +285,7 @@ shortLivedCacheBlockDuration; 100m; utils::TimeSpan; Duration of a block in the shortLivedCachePruneInterval; 90s; utils::TimeSpan; Time between short lived cache pruning. shortLivedCacheMaxSize; 10'000'000; uint32_t; Maximum size of a short lived cache. minFeeMultiplier; 100; BlockFeeMultiplier; Minimum fee multiplier of transactions to propagate and include in blocks. -maxTimeBehindPullTransactionsStart; 5m; ; +maxTimeBehindPullTransactionsStart; 24h; ; transactionSelectionStrategy; oldest; model::TransactionSelectionStrategy; Transaction selection strategy used for syncing and harvesting unconfirmed transactions. unconfirmedTransactionsCacheMaxResponseSize; 5MB; utils::FileSize; Maximum size of an unconfirmed transactions response. unconfirmedTransactionsCacheMaxSize; 20MB; uint32_t; Maximum size of the unconfirmed transactions cache. @@ -290,7 +303,7 @@ transactionDisruptorMaxMemorySize; 20MB; ; enableDispatcherAbortWhenFull; false; bool; Set to true if the process should terminate when any dispatcher is full. enableDispatcherInputAuditing; false; bool; Set to true if all dispatcher inputs should be audited. maxTrackedNodes; 5'000; uint32_t; Maximum number of nodes to track in memory. -minPartnerNodeVersion; 1.0.1.0; ; +minPartnerNodeVersion; 1.0.2.0; ; maxPartnerNodeVersion; 1.0.255.255; ; trustedHosts; 127.0.0.1; unordered_set; Trusted hosts that are allowed to execute protected API calls on this node. localNetworks; 127.0.0.1; unordered_set; Networks that should be treated as local. @@ -308,7 +321,7 @@ maxWriteBatchSize; 5MB localnode host; peer-node-0; string; Node host (leave empty to auto-detect IP). friendlyName; my-peer-node-0; string; Node friendly name (leave empty to use address). -version; 1.0.2.0; uint32_t; Node version. +version; ; uint32_t; Node version. roles; Peer,Voting; ionet::NodeRoles; Node roles. outgoing_connections @@ -444,4 +457,4 @@ seedDirectory; ./seed certificateDirectory; ./cert dataDirectory; ./data pluginsDirectory; /usr/catapult/lib -votingKeysDirectory; ./votingkeys \ No newline at end of file +votingKeysDirectory; ./votingkeys diff --git a/test/reports/bootstrap-voting/peer-node-0-config.rst b/test/reports/bootstrap-voting/peer-node-0-config.rst index d176dd697..dec499d45 100644 --- a/test/reports/bootstrap-voting/peer-node-0-config.rst +++ b/test/reports/bootstrap-voting/peer-node-0-config.rst @@ -93,6 +93,8 @@ config-finalization.properties maxHashesPerPoint; 256 prevoteBlocksMultiple; 4 unfinalizedBlocksDuration; 0m + treasuryReissuanceEpoch; 0 + **treasury_reissuance_epoch_ineligible_voter_addresses**; config-harvesting.properties ============================ @@ -198,7 +200,7 @@ config-network.properties :delim: ; **network**; ; ; - identifier; public-test; NetworkIdentifier; Network identifier. + identifier; testnet; NetworkIdentifier; Network identifier. nemesisSignerPublicKey; DA007A7CCA877805DF0DD6250C9806E7B25DC3ED21E506569239D11A7175101A; Key; Nemesis public key. nodeEqualityStrategy; host; NodeIdentityEqualityStrategy; Node equality strategy. generationHashSeed; 6AF8E35BBC7AC341E7931B39E2C9A591EDBE9F9111996053E6771D48E9C53B31; ; @@ -229,10 +231,11 @@ config-network.properties maxVotingKeyLifetime; 26280; uint32_t; Maximum number of finalization rounds for which voting key can be registered. harvestBeneficiaryPercentage; 10; uint8_t; Percentage of the harvested fee that is collected by the beneficiary account. harvestNetworkPercentage; 5; uint8_t; Percentage of the harvested fee that is collected by the network. + harvestNetworkFeeSinkAddressV1; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; ; harvestNetworkFeeSinkAddress; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; Address; Address of the harvest network fee sink account. maxTransactionsPerBlock; 6'000; uint32_t; Maximum number of transactions per block. - **fork_heights**; ; ; - totalVotingBalanceCalculationFix; 0; uint32_t; Height of fork to fix TotalVotingBalance calculation. + treasuryReissuanceBlockTransactionsHash; 0000000000000000000000000000000000000000000000000000000000000000; ; + treasuryReissuanceFallbackBlockTransactionsHash; 0000000000000000000000000000000000000000000000000000000000000000; ; **plugin:catapult.plugins.accountlink**; dummy; to trigger plugin load **plugin:catapult.plugins.aggregate**; ; ; @@ -254,6 +257,7 @@ config-network.properties maxMosaicsPerAccount; 1'000; uint16_t; Maximum number of mosaics that an account can own. maxMosaicDuration; 3650d; utils::BlockSpan; Maximum mosaic duration. maxMosaicDivisibility; 6; uint8_t; Maximum mosaic divisibility. + mosaicRentalFeeSinkAddressV1; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; ; mosaicRentalFeeSinkAddress; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; Address; Address of the mosaic rental fee sink account. mosaicRentalFee; 500; Amount; Mosaic rental fee. **plugin:catapult.plugins.multisig**; ; ; @@ -268,6 +272,7 @@ config-network.properties maxNamespaceDuration; 365d; utils::BlockSpan; Maximum namespace duration. namespaceGracePeriodDuration; 30d; utils::BlockSpan; Grace period during which time only the previous owner can renew an expired namespace. reservedRootNamespaceNames; symbol, symbl, xym, xem, nem, user, account, org, com, biz, net, edu, mil, gov, info; unordered_set; Reserved root namespaces that cannot be claimed. + namespaceRentalFeeSinkAddressV1; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; ; namespaceRentalFeeSinkAddress; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; Address; Address of the namespace rental fee sink account. rootNamespaceRentalFeePerBlock; 1; Amount; Root namespace rental fee per block. childNamespaceRentalFee; 100; Amount; Child namespace rental fee. @@ -277,6 +282,11 @@ config-network.properties maxMosaicRestrictionValues; 20; uint8_t; Maximum number of mosaic restriction values. **plugin:catapult.plugins.transfer**; ; ; maxMessageSize; 1024; uint16_t; Maximum transaction message size. + **fork_heights**; ; ; + totalVotingBalanceCalculationFix; 0; uint32_t; Height of fork to fix TotalVotingBalance calculation. + treasuryReissuance; 0; ; + **treasury_reissuance_transaction_signatures**; + **treasury_reissuance_fallback_transaction_signatures**; config-node.properties ====================== @@ -302,7 +312,7 @@ config-node.properties shortLivedCachePruneInterval; 90s; utils::TimeSpan; Time between short lived cache pruning. shortLivedCacheMaxSize; 10'000'000; uint32_t; Maximum size of a short lived cache. minFeeMultiplier; 100; BlockFeeMultiplier; Minimum fee multiplier of transactions to propagate and include in blocks. - maxTimeBehindPullTransactionsStart; 5m; ; + maxTimeBehindPullTransactionsStart; 24h; ; transactionSelectionStrategy; oldest; model::TransactionSelectionStrategy; Transaction selection strategy used for syncing and harvesting unconfirmed transactions. unconfirmedTransactionsCacheMaxResponseSize; 5MB; utils::FileSize; Maximum size of an unconfirmed transactions response. unconfirmedTransactionsCacheMaxSize; 20MB; uint32_t; Maximum size of the unconfirmed transactions cache. @@ -320,7 +330,7 @@ config-node.properties enableDispatcherAbortWhenFull; false; bool; Set to true if the process should terminate when any dispatcher is full. enableDispatcherInputAuditing; false; bool; Set to true if all dispatcher inputs should be audited. maxTrackedNodes; 5'000; uint32_t; Maximum number of nodes to track in memory. - minPartnerNodeVersion; 1.0.1.0; ; + minPartnerNodeVersion; 1.0.2.0; ; maxPartnerNodeVersion; 1.0.255.255; ; trustedHosts; 127.0.0.1; unordered_set; Trusted hosts that are allowed to execute protected API calls on this node. localNetworks; 127.0.0.1; unordered_set; Networks that should be treated as local. @@ -336,7 +346,7 @@ config-node.properties **localnode**; ; ; host; peer-node-0; string; Node host (leave empty to auto-detect IP). friendlyName; my-peer-node-0; string; Node friendly name (leave empty to use address). - version; 1.0.2.0; uint32_t; Node version. + version; ; uint32_t; Node version. roles; Peer,Voting; ionet::NodeRoles; Node roles. **outgoing_connections**; ; ; maxConnections; 10; uint16_t; Maximum number of active connections. @@ -466,4 +476,4 @@ config-user.properties certificateDirectory; ./cert dataDirectory; ./data pluginsDirectory; /usr/catapult/lib - votingKeysDirectory; ./votingkeys \ No newline at end of file + votingKeysDirectory; ./votingkeys diff --git a/test/reports/bootstrap-voting/peer-node-1-config.csv b/test/reports/bootstrap-voting/peer-node-1-config.csv index c1e7b01ac..32e569dc0 100644 --- a/test/reports/bootstrap-voting/peer-node-1-config.csv +++ b/test/reports/bootstrap-voting/peer-node-1-config.csv @@ -73,6 +73,9 @@ messageSynchronizationMaxResponseSize; 20MB maxHashesPerPoint; 256 prevoteBlocksMultiple; 4 unfinalizedBlocksDuration; 0m +treasuryReissuanceEpoch; 0 + +treasury_reissuance_epoch_ineligible_voter_addresses config-harvesting.properties @@ -159,7 +162,7 @@ listenInterface; 0.0.0.0 config-network.properties network -identifier; public-test; NetworkIdentifier; Network identifier. +identifier; testnet; NetworkIdentifier; Network identifier. nemesisSignerPublicKey; DA007A7CCA877805DF0DD6250C9806E7B25DC3ED21E506569239D11A7175101A; Key; Nemesis public key. nodeEqualityStrategy; host; NodeIdentityEqualityStrategy; Node equality strategy. generationHashSeed; 6AF8E35BBC7AC341E7931B39E2C9A591EDBE9F9111996053E6771D48E9C53B31; ; @@ -191,11 +194,11 @@ minVotingKeyLifetime; 28; uint32_t; Minimum number of finalization rounds for wh maxVotingKeyLifetime; 26280; uint32_t; Maximum number of finalization rounds for which voting key can be registered. harvestBeneficiaryPercentage; 10; uint8_t; Percentage of the harvested fee that is collected by the beneficiary account. harvestNetworkPercentage; 5; uint8_t; Percentage of the harvested fee that is collected by the network. +harvestNetworkFeeSinkAddressV1; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; ; harvestNetworkFeeSinkAddress; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; Address; Address of the harvest network fee sink account. maxTransactionsPerBlock; 6'000; uint32_t; Maximum number of transactions per block. - -fork_heights -totalVotingBalanceCalculationFix; 0; uint32_t; Height of fork to fix TotalVotingBalance calculation. +treasuryReissuanceBlockTransactionsHash; 0000000000000000000000000000000000000000000000000000000000000000; ; +treasuryReissuanceFallbackBlockTransactionsHash; 0000000000000000000000000000000000000000000000000000000000000000; ; plugin:catapult.plugins.accountlink dummy; to trigger plugin load @@ -223,6 +226,7 @@ plugin:catapult.plugins.mosaic maxMosaicsPerAccount; 1'000; uint16_t; Maximum number of mosaics that an account can own. maxMosaicDuration; 3650d; utils::BlockSpan; Maximum mosaic duration. maxMosaicDivisibility; 6; uint8_t; Maximum mosaic divisibility. +mosaicRentalFeeSinkAddressV1; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; ; mosaicRentalFeeSinkAddress; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; Address; Address of the mosaic rental fee sink account. mosaicRentalFee; 500; Amount; Mosaic rental fee. @@ -239,6 +243,7 @@ minNamespaceDuration; 1m; utils::BlockSpan; Minimum namespace duration. maxNamespaceDuration; 365d; utils::BlockSpan; Maximum namespace duration. namespaceGracePeriodDuration; 30d; utils::BlockSpan; Grace period during which time only the previous owner can renew an expired namespace. reservedRootNamespaceNames; symbol, symbl, xym, xem, nem, user, account, org, com, biz, net, edu, mil, gov, info; unordered_set; Reserved root namespaces that cannot be claimed. +namespaceRentalFeeSinkAddressV1; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; ; namespaceRentalFeeSinkAddress; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; Address; Address of the namespace rental fee sink account. rootNamespaceRentalFeePerBlock; 1; Amount; Root namespace rental fee per block. childNamespaceRentalFee; 100; Amount; Child namespace rental fee. @@ -252,6 +257,14 @@ maxMosaicRestrictionValues; 20; uint8_t; Maximum number of mosaic restriction va plugin:catapult.plugins.transfer maxMessageSize; 1024; uint16_t; Maximum transaction message size. +fork_heights +totalVotingBalanceCalculationFix; 0; uint32_t; Height of fork to fix TotalVotingBalance calculation. +treasuryReissuance; 0; ; + +treasury_reissuance_transaction_signatures + +treasury_reissuance_fallback_transaction_signatures + config-node.properties node @@ -272,7 +285,7 @@ shortLivedCacheBlockDuration; 100m; utils::TimeSpan; Duration of a block in the shortLivedCachePruneInterval; 90s; utils::TimeSpan; Time between short lived cache pruning. shortLivedCacheMaxSize; 10'000'000; uint32_t; Maximum size of a short lived cache. minFeeMultiplier; 100; BlockFeeMultiplier; Minimum fee multiplier of transactions to propagate and include in blocks. -maxTimeBehindPullTransactionsStart; 5m; ; +maxTimeBehindPullTransactionsStart; 24h; ; transactionSelectionStrategy; oldest; model::TransactionSelectionStrategy; Transaction selection strategy used for syncing and harvesting unconfirmed transactions. unconfirmedTransactionsCacheMaxResponseSize; 5MB; utils::FileSize; Maximum size of an unconfirmed transactions response. unconfirmedTransactionsCacheMaxSize; 20MB; uint32_t; Maximum size of the unconfirmed transactions cache. @@ -290,7 +303,7 @@ transactionDisruptorMaxMemorySize; 20MB; ; enableDispatcherAbortWhenFull; false; bool; Set to true if the process should terminate when any dispatcher is full. enableDispatcherInputAuditing; false; bool; Set to true if all dispatcher inputs should be audited. maxTrackedNodes; 5'000; uint32_t; Maximum number of nodes to track in memory. -minPartnerNodeVersion; 1.0.1.0; ; +minPartnerNodeVersion; 1.0.2.0; ; maxPartnerNodeVersion; 1.0.255.255; ; trustedHosts; 127.0.0.1; unordered_set; Trusted hosts that are allowed to execute protected API calls on this node. localNetworks; 127.0.0.1; unordered_set; Networks that should be treated as local. @@ -308,7 +321,7 @@ maxWriteBatchSize; 5MB localnode host; peer-node-1; string; Node host (leave empty to auto-detect IP). friendlyName; my-peer-node-1; string; Node friendly name (leave empty to use address). -version; 1.0.2.0; uint32_t; Node version. +version; ; uint32_t; Node version. roles; Peer,Voting; ionet::NodeRoles; Node roles. outgoing_connections @@ -444,4 +457,4 @@ seedDirectory; ./seed certificateDirectory; ./cert dataDirectory; ./data pluginsDirectory; /usr/catapult/lib -votingKeysDirectory; ./votingkeys \ No newline at end of file +votingKeysDirectory; ./votingkeys diff --git a/test/reports/bootstrap-voting/peer-node-1-config.rst b/test/reports/bootstrap-voting/peer-node-1-config.rst index ec32e7679..d555a5b94 100644 --- a/test/reports/bootstrap-voting/peer-node-1-config.rst +++ b/test/reports/bootstrap-voting/peer-node-1-config.rst @@ -93,6 +93,8 @@ config-finalization.properties maxHashesPerPoint; 256 prevoteBlocksMultiple; 4 unfinalizedBlocksDuration; 0m + treasuryReissuanceEpoch; 0 + **treasury_reissuance_epoch_ineligible_voter_addresses**; config-harvesting.properties ============================ @@ -198,7 +200,7 @@ config-network.properties :delim: ; **network**; ; ; - identifier; public-test; NetworkIdentifier; Network identifier. + identifier; testnet; NetworkIdentifier; Network identifier. nemesisSignerPublicKey; DA007A7CCA877805DF0DD6250C9806E7B25DC3ED21E506569239D11A7175101A; Key; Nemesis public key. nodeEqualityStrategy; host; NodeIdentityEqualityStrategy; Node equality strategy. generationHashSeed; 6AF8E35BBC7AC341E7931B39E2C9A591EDBE9F9111996053E6771D48E9C53B31; ; @@ -229,10 +231,11 @@ config-network.properties maxVotingKeyLifetime; 26280; uint32_t; Maximum number of finalization rounds for which voting key can be registered. harvestBeneficiaryPercentage; 10; uint8_t; Percentage of the harvested fee that is collected by the beneficiary account. harvestNetworkPercentage; 5; uint8_t; Percentage of the harvested fee that is collected by the network. + harvestNetworkFeeSinkAddressV1; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; ; harvestNetworkFeeSinkAddress; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; Address; Address of the harvest network fee sink account. maxTransactionsPerBlock; 6'000; uint32_t; Maximum number of transactions per block. - **fork_heights**; ; ; - totalVotingBalanceCalculationFix; 0; uint32_t; Height of fork to fix TotalVotingBalance calculation. + treasuryReissuanceBlockTransactionsHash; 0000000000000000000000000000000000000000000000000000000000000000; ; + treasuryReissuanceFallbackBlockTransactionsHash; 0000000000000000000000000000000000000000000000000000000000000000; ; **plugin:catapult.plugins.accountlink**; dummy; to trigger plugin load **plugin:catapult.plugins.aggregate**; ; ; @@ -254,6 +257,7 @@ config-network.properties maxMosaicsPerAccount; 1'000; uint16_t; Maximum number of mosaics that an account can own. maxMosaicDuration; 3650d; utils::BlockSpan; Maximum mosaic duration. maxMosaicDivisibility; 6; uint8_t; Maximum mosaic divisibility. + mosaicRentalFeeSinkAddressV1; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; ; mosaicRentalFeeSinkAddress; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; Address; Address of the mosaic rental fee sink account. mosaicRentalFee; 500; Amount; Mosaic rental fee. **plugin:catapult.plugins.multisig**; ; ; @@ -268,6 +272,7 @@ config-network.properties maxNamespaceDuration; 365d; utils::BlockSpan; Maximum namespace duration. namespaceGracePeriodDuration; 30d; utils::BlockSpan; Grace period during which time only the previous owner can renew an expired namespace. reservedRootNamespaceNames; symbol, symbl, xym, xem, nem, user, account, org, com, biz, net, edu, mil, gov, info; unordered_set; Reserved root namespaces that cannot be claimed. + namespaceRentalFeeSinkAddressV1; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; ; namespaceRentalFeeSinkAddress; TDGY4DD2U4YQQGERFMDQYHPYS6M7LHIF6XUCJ4Q; Address; Address of the namespace rental fee sink account. rootNamespaceRentalFeePerBlock; 1; Amount; Root namespace rental fee per block. childNamespaceRentalFee; 100; Amount; Child namespace rental fee. @@ -277,6 +282,11 @@ config-network.properties maxMosaicRestrictionValues; 20; uint8_t; Maximum number of mosaic restriction values. **plugin:catapult.plugins.transfer**; ; ; maxMessageSize; 1024; uint16_t; Maximum transaction message size. + **fork_heights**; ; ; + totalVotingBalanceCalculationFix; 0; uint32_t; Height of fork to fix TotalVotingBalance calculation. + treasuryReissuance; 0; ; + **treasury_reissuance_transaction_signatures**; + **treasury_reissuance_fallback_transaction_signatures**; config-node.properties ====================== @@ -302,7 +312,7 @@ config-node.properties shortLivedCachePruneInterval; 90s; utils::TimeSpan; Time between short lived cache pruning. shortLivedCacheMaxSize; 10'000'000; uint32_t; Maximum size of a short lived cache. minFeeMultiplier; 100; BlockFeeMultiplier; Minimum fee multiplier of transactions to propagate and include in blocks. - maxTimeBehindPullTransactionsStart; 5m; ; + maxTimeBehindPullTransactionsStart; 24h; ; transactionSelectionStrategy; oldest; model::TransactionSelectionStrategy; Transaction selection strategy used for syncing and harvesting unconfirmed transactions. unconfirmedTransactionsCacheMaxResponseSize; 5MB; utils::FileSize; Maximum size of an unconfirmed transactions response. unconfirmedTransactionsCacheMaxSize; 20MB; uint32_t; Maximum size of the unconfirmed transactions cache. @@ -320,7 +330,7 @@ config-node.properties enableDispatcherAbortWhenFull; false; bool; Set to true if the process should terminate when any dispatcher is full. enableDispatcherInputAuditing; false; bool; Set to true if all dispatcher inputs should be audited. maxTrackedNodes; 5'000; uint32_t; Maximum number of nodes to track in memory. - minPartnerNodeVersion; 1.0.1.0; ; + minPartnerNodeVersion; 1.0.2.0; ; maxPartnerNodeVersion; 1.0.255.255; ; trustedHosts; 127.0.0.1; unordered_set; Trusted hosts that are allowed to execute protected API calls on this node. localNetworks; 127.0.0.1; unordered_set; Networks that should be treated as local. @@ -336,7 +346,7 @@ config-node.properties **localnode**; ; ; host; peer-node-1; string; Node host (leave empty to auto-detect IP). friendlyName; my-peer-node-1; string; Node friendly name (leave empty to use address). - version; 1.0.2.0; uint32_t; Node version. + version; ; uint32_t; Node version. roles; Peer,Voting; ionet::NodeRoles; Node roles. **outgoing_connections**; ; ; maxConnections; 10; uint16_t; Maximum number of active connections. @@ -466,4 +476,4 @@ config-user.properties certificateDirectory; ./cert dataDirectory; ./data pluginsDirectory; /usr/catapult/lib - votingKeysDirectory; ./votingkeys \ No newline at end of file + votingKeysDirectory; ./votingkeys diff --git a/test/reports/bootstrap-voting/rest-gateway-0-rest.json b/test/reports/bootstrap-voting/rest-gateway-0-rest.json index a51f3e2b7..3d9b8230a 100644 --- a/test/reports/bootstrap-voting/rest-gateway-0-rest.json +++ b/test/reports/bootstrap-voting/rest-gateway-0-rest.json @@ -1,9 +1,12 @@ { "network": { - "name": "publicTest", + "name": "testnet", "description": "catapult development network" }, "port": 3000, + "protocol": "HTTP", + "sslKeyPath": "/symbol-workdir/restSSL.key", + "sslCertificatePath": "/symbol-workdir/restSSL.crt", "crossDomain": { "allowedHosts": [ "*" @@ -88,4 +91,4 @@ "deploymentToolVersion": "abc", "lastUpdatedDate": "2021-05-23" } -} \ No newline at end of file +} diff --git a/test/reports/mainnet-dual-voting/node-config.csv b/test/reports/mainnet-dual-voting/node-config.csv index f8f3e7362..bcfef7b6e 100644 --- a/test/reports/mainnet-dual-voting/node-config.csv +++ b/test/reports/mainnet-dual-voting/node-config.csv @@ -73,6 +73,71 @@ messageSynchronizationMaxResponseSize; 20MB maxHashesPerPoint; 256 prevoteBlocksMultiple; 4 unfinalizedBlocksDuration; 0m +treasuryReissuanceEpoch; 481 + +treasury_reissuance_epoch_ineligible_voter_addresses +ND6667LJBJJ6UMJSZKN2BLHQCS3WNZ3W4UGCFKI; true +NCKAC225JEFJTB3EO64MIVYF5D7YGZM2ZFXRJNI; true +NACXOOKIDID7S75S4FFSC7KBBIBHOBUXB5VSE7A; true +NCVQPB2LZ6UCYKGYJAMCC7V4JGXA35BBY44BMHY; true +NDSQX6J2QALD2XTU5NQ4FWA2MMEFKBOBEB2BIOQ; true +NDLFVQ3C25P5VO2VWP6AMHPIJT6FZYTXNJD4ZAY; true +NCXX3KEIEZ3NABMUU45GM7X7BLMPMQHFOZMMF4Q; true +NDF4ZCXFKIU5DSJEVBOOI2BDZMDKJTGJVBD6JRY; true +NCTTMDTZUUQVN4OKTSF3FTEHJQL2QOGAV25MDCA; true +NDLORKVADZSXTIVAA2FYLDMM7I32AIWE7HDWGUQ; true +NCQADXOA7ZHLUW2567H33HNNEKCOCN2OJ53PXIQ; true +NDX4GP6OL32EOSGXSB5FTGKXDJZP4D535ZZYDFI; true +NCE3EP762222D5D2UAF6KIFL7XZ7U4TPFWBYVHA; true +NDRLHNV4W7W2M527QOIP35OI3HOMAGTCJDPFDEQ; true +NDNGH7WJHSMULMCKYE333V6WU4CQDWXZIJK2VCY; true +NB5NIEQF7FM7LLSFASHOQF4X3F6IPDYSIGR3UVA; true +NDC3U2UERNMRYFQA45XC74TEEETTZPRUVWKFPAY; true +NBNCW3DUUHGBCVJ53LYSYYNMKJ52TLR33C5U53A; true +NCAXT7RH6SUPXEU75EIPAPF7DM4VWUBC5AW2L4Q; true +NALOQMBU45WOLZ4BCBYZX3N2Y2VSYQFOXGAO34A; true +NA2KVKEQDZZMM3NGXYVBHZ46JHM46UWIX3KJ4AY; true +NBI2NEBVAD45WWV44H3A53AQ5675Z4G3ZDGDYLI; true +NB5ORUTTH2QYHEVTDBB5WPQI4US22FNMODFRK5Y; true +NDMR4GMUWGMODWY4FF2VZ3CEC2F56HTD3T6EJYY; true +NCBLL63WUAL7FBNPZQISGJR4WZNB7RVWCWG25MI; true +NBGGUKW3GEUFHKTO4DYSGDTHIVPKAME3T2XSCGY; true +NCASTBFHXMHGQB2UJVUDSW7ZI4N2FDW54OTSHKQ; true +ND726EB3B2VG77J3EEQSGNGUX3SS6L2IEBS7PIY; true +ND2MRMODKMLCFJWPFJ4MDFI76R7FLZVKIIVKD3A; true +NDG6ORUW4PVWVQJRQ5AXADQBUQVL3KBX7AW7MUY; true +NBQS3VKGOJ3YNIABN4Y4SFUDBDQHARUIVS6IMGQ; true +NCC3VKV3V2HCAP2KTXJUWSXCJ3B6U32EKR6VU5I; true +NBUW4OTD42VHELNPCLPQCUHNBHR47PQKLP2EKXA; true +NDBKLXZWYBMUUTNRRZ5ESRAJYMQIMHGLGAYLTGY; true +NABH3A5VDLYAVA73OV246JTVMAIPD2WEMAQL27I; true +NCVG74MGUGR3PLVBWVNNACD6R37JA4RCQMXY3DY; true +NDQLBLKXVOK2YS5G7J3AYYKTNW3S3RRK6RQONAQ; true +NDTNPG2NUA3MPVDXHLC6D5PSKM4JLLTMQJ5HEDY; true +ND4MLYCECHPACYSDDQUFMPXONSIQLPAWNVBWSIA; true +NCNRS6KDPHV4MNMXOEGYD6LNRBMWUR7NT4SZI7I; true +NBRENIWJUCSUU7RJ5S2DEJVXAOJOTZZDKEFOC3I; true +NA7YZPY222RVYQMUM65ZSVFSPAHL55UWO3S35FY; true +NCVR72OUOHVGTVLYBKI7PLUDTIAYPRUWPMJJP3Q; true +NDE57ICE4UOAPUV3E4CYU3PBA2X4ABUGRGKDFBA; true +NBBBCIKJV45U7PNYTNXETH2UFZLJ3C6TJKLJDQQ; true +NCRLDB2O2QDPU57PEG3D3AIFSGPGCZU7VVTKBUY; true +NC7QENF6OO2FRYV7Q4B5Q74LRSC54Y3YNYN5O3Y; true +NAL4XHZU6MANNNFQI4Z2WNMU3KRI2YW2MRRMHLI; true +NC5CFRDWEZVCMGQ4Y77OEFSQLMQ3V4EL7JERY2A; true +NAIPUZBSDXZIHQKKILAFT3F43IQPS4LOZCH2H4Q; true +ND6ZNSQG3I7VWLWSJ3DTYVPEZSJRGSEERW2F7DI; true +NC54KVIISZCMMB3ABAMV6NQ6DAUIYYVKQ23S73Q; true +NBNRFJSGE53UNHBGZIHYZXPG7SHLQISJN5REGIY; true +NCFFJV3VTAK6BJZNV6ZRUZKUJPOWST6MYFAAK5A; true +NAAZKYH4V6SARDIJRGFXYEZIHVRWY7R2T62QFYA; true +NAGCLXJZHZSBM5ILN4LQBDKU4NYVHB6ZLGRTKJI; true +NBGEJ36QK43DR4MYB6XFUFLSVFLULX3HBVNRCVY; true +NCGCVCURBA2GCKPEGEA2Q6HKFEHYITKUNWRLMEA; true +NA5ZUGHBUUHO63E5OQQND7CYK7UZ3HVQONR2O6Y; true +NC2GXL6FQXZY3FXZAYJLBDQHBKSANZLGP4PL7VA; true +NB3WMVRI4RM3O3NUSWBZM7U4EZMKADSOFDPPJRQ; true +NCFH35TMUJ5QJL6LTBYRBO7ERMM4NIBH7TL6TFY; true config-harvesting.properties @@ -580,7 +645,7 @@ listenInterface; 0.0.0.0 config-network.properties network -identifier; public; NetworkIdentifier; Network identifier. +identifier; mainnet; NetworkIdentifier; Network identifier. nemesisSignerPublicKey; BE0B4CF546B7B4F4BBFCFF9F574FDA527C07A53D3FC76F8BB7DB746F8E8E0A9F; Key; Nemesis public key. nodeEqualityStrategy; host; NodeIdentityEqualityStrategy; Node equality strategy. generationHashSeed; 57F7DA205008026C776CB6AED843393F04CD458E0AA2D9F1D5F31A402072B2D6; ; @@ -612,11 +677,11 @@ minVotingKeyLifetime; 112; uint32_t; Minimum number of finalization rounds for w maxVotingKeyLifetime; 360; uint32_t; Maximum number of finalization rounds for which voting key can be registered. harvestBeneficiaryPercentage; 25; uint8_t; Percentage of the harvested fee that is collected by the beneficiary account. harvestNetworkPercentage; 5; uint8_t; Percentage of the harvested fee that is collected by the network. -harvestNetworkFeeSinkAddress; NBUTOBVT5JQDCV6UEPCPFHWWOAOPOCLA5AY5FLI; Address; Address of the harvest network fee sink account. +harvestNetworkFeeSinkAddressV1; NBUTOBVT5JQDCV6UEPCPFHWWOAOPOCLA5AY5FLI; ; +harvestNetworkFeeSinkAddress; NAVORTEX3IPBAUWQBBI3I3BDIOS4AVHPZLCFC7Y; Address; Address of the harvest network fee sink account. maxTransactionsPerBlock; 6'000; uint32_t; Maximum number of transactions per block. - -fork_heights -totalVotingBalanceCalculationFix; 528'000; uint32_t; Height of fork to fix TotalVotingBalance calculation. +treasuryReissuanceBlockTransactionsHash; 1A95DA607D545C7E5103EC8D3411E6E505D5B7567E8F3857CD6AEBAD90D3B07F; ; +treasuryReissuanceFallbackBlockTransactionsHash; E1DFEA3F15CDB974EA621A4A9E60B2EC676802DEAA542FE665D2FA364BB4C13D; ; plugin:catapult.plugins.accountlink dummy; to trigger plugin load @@ -644,7 +709,8 @@ plugin:catapult.plugins.mosaic maxMosaicsPerAccount; 1'000; uint16_t; Maximum number of mosaics that an account can own. maxMosaicDuration; 3650d; utils::BlockSpan; Maximum mosaic duration. maxMosaicDivisibility; 6; uint8_t; Maximum mosaic divisibility. -mosaicRentalFeeSinkAddress; NC733XE7DF46Q7QYLIIZBBSCJN2BEEP5FQ6PAYA; Address; Address of the mosaic rental fee sink account. +mosaicRentalFeeSinkAddressV1; NC733XE7DF46Q7QYLIIZBBSCJN2BEEP5FQ6PAYA; ; +mosaicRentalFeeSinkAddress; NCVORTEX4XD5IQASZQEHDWUXT33XBOTBMKFDCLI; Address; Address of the mosaic rental fee sink account. mosaicRentalFee; 500000; Amount; Mosaic rental fee. plugin:catapult.plugins.multisig @@ -660,7 +726,8 @@ minNamespaceDuration; 30d; utils::BlockSpan; Minimum namespace duration. maxNamespaceDuration; 1825d; utils::BlockSpan; Maximum namespace duration. namespaceGracePeriodDuration; 30d; utils::BlockSpan; Grace period during which time only the previous owner can renew an expired namespace. reservedRootNamespaceNames; symbol, symbl, xym, xem, nem, user, account, org, com, biz, net, edu, mil, gov, info; unordered_set; Reserved root namespaces that cannot be claimed. -namespaceRentalFeeSinkAddress; NBDTBUD6R32ZYJWDEWLJM4YMOX3OOILHGDUMTSA; Address; Address of the namespace rental fee sink account. +namespaceRentalFeeSinkAddressV1; NBDTBUD6R32ZYJWDEWLJM4YMOX3OOILHGDUMTSA; ; +namespaceRentalFeeSinkAddress; NCVORTEX4XD5IQASZQEHDWUXT33XBOTBMKFDCLI; Address; Address of the namespace rental fee sink account. rootNamespaceRentalFeePerBlock; 2; Amount; Root namespace rental fee per block. childNamespaceRentalFee; 100000; Amount; Child namespace rental fee. @@ -673,6 +740,22 @@ maxMosaicRestrictionValues; 20; uint8_t; Maximum number of mosaic restriction va plugin:catapult.plugins.transfer maxMessageSize; 1024; uint16_t; Maximum transaction message size. +fork_heights +totalVotingBalanceCalculationFix; 528'000; uint32_t; Height of fork to fix TotalVotingBalance calculation. +treasuryReissuance; 689'761; ; + +treasury_reissuance_transaction_signatures +0BBEADD37539444D75C09A245102D2B883267925398504623835DCD625290DEE4FA2371341050C49C001DEDD1C9FE241EA4A7DB335B2069FD4DAFF77AF734C03; true +89447704270E8B2F8EED19526587DB58870D90A02ACEF8AE2A54311DEB95C227201CD39662A0229D5746FFB84074EA6C7DD9620A2CE5AA69065C508DC0335201; true +D19BCD440545CF785D88F903141DE794F2D57012509BC224B25BFCA220267D1ADD42182702F50C1A4E95D0F21604E4F9EEEEF329932FCD0C76B43992B0D90B0D; true +C478DB6053C639AFC96F5D965159DC95449E5EE69A62E5FA28DF42D85C031B3A131B3AC403D9BFF27E1E64FD8012D05C720F0D2A8654D9F4BC48C8DD2DCEBC03; true +C0BAE301EC15B514C5685A661BC3E23A6596CE9DC412A83F67A8C8611A4415B1B0447E8C09D2816CAE0D750C4AB1ED8FE9C85C05D448C2114147A2C935030708; true +A317F4EB085C8D3D80435669EF54C6C9C9AD9B57165B14CF051F43879D0112E3A79591DD6D469BFAA850891FA2CB601BA58CD1BAEBFF5D84C49179AC7FE14706; true +FDB98C472D0B98FDD766DA177366DEB2DB0E79721BD73DA96A84622A98932DA75BAA327BA9E23D448C6F25344654A6F17F7734C14D1530B327F911A97B4DE30A; true + +treasury_reissuance_fallback_transaction_signatures +E29FA2456E505044B2087D4D4FFC390D3E2BDAEF2233E10E812C8677D1DE95DDB5D7A696D8C697DB74D07DC9AB863659EE9C6E984BE83E394AE632D21129EC0F; true + config-node.properties node @@ -693,7 +776,7 @@ shortLivedCacheBlockDuration; 100m; utils::TimeSpan; Duration of a block in the shortLivedCachePruneInterval; 90s; utils::TimeSpan; Time between short lived cache pruning. shortLivedCacheMaxSize; 10'000'000; uint32_t; Maximum size of a short lived cache. minFeeMultiplier; 100; BlockFeeMultiplier; Minimum fee multiplier of transactions to propagate and include in blocks. -maxTimeBehindPullTransactionsStart; 5m; ; +maxTimeBehindPullTransactionsStart; 24h; ; transactionSelectionStrategy; oldest; model::TransactionSelectionStrategy; Transaction selection strategy used for syncing and harvesting unconfirmed transactions. unconfirmedTransactionsCacheMaxResponseSize; 5MB; utils::FileSize; Maximum size of an unconfirmed transactions response. unconfirmedTransactionsCacheMaxSize; 20MB; uint32_t; Maximum size of the unconfirmed transactions cache. @@ -711,7 +794,7 @@ transactionDisruptorMaxMemorySize; 20MB; ; enableDispatcherAbortWhenFull; false; bool; Set to true if the process should terminate when any dispatcher is full. enableDispatcherInputAuditing; false; bool; Set to true if all dispatcher inputs should be audited. maxTrackedNodes; 5'000; uint32_t; Maximum number of nodes to track in memory. -minPartnerNodeVersion; 1.0.1.0; ; +minPartnerNodeVersion; 1.0.2.0; ; maxPartnerNodeVersion; 1.0.255.255; ; trustedHosts; 127.0.0.1, 172.20.0.25; unordered_set; Trusted hosts that are allowed to execute protected API calls on this node. localNetworks; 127.0.0.1, 172.20.0.25; unordered_set; Networks that should be treated as local. @@ -729,7 +812,7 @@ maxWriteBatchSize; 5MB localnode host; ; string; Node host (leave empty to auto-detect IP). friendlyName; myFriendlyName; string; Node friendly name (leave empty to use address). -version; 1.0.2.0; uint32_t; Node version. +version; ; uint32_t; Node version. roles; Peer,Api,Voting; ionet::NodeRoles; Node roles. outgoing_connections diff --git a/test/reports/mainnet-dual-voting/node-config.rst b/test/reports/mainnet-dual-voting/node-config.rst index 10f6d441f..5d89c0560 100644 --- a/test/reports/mainnet-dual-voting/node-config.rst +++ b/test/reports/mainnet-dual-voting/node-config.rst @@ -93,6 +93,70 @@ config-finalization.properties maxHashesPerPoint; 256 prevoteBlocksMultiple; 4 unfinalizedBlocksDuration; 0m + treasuryReissuanceEpoch; 481 + **treasury_reissuance_epoch_ineligible_voter_addresses**; + ND6667LJBJJ6UMJSZKN2BLHQCS3WNZ3W4UGCFKI; true + NCKAC225JEFJTB3EO64MIVYF5D7YGZM2ZFXRJNI; true + NACXOOKIDID7S75S4FFSC7KBBIBHOBUXB5VSE7A; true + NCVQPB2LZ6UCYKGYJAMCC7V4JGXA35BBY44BMHY; true + NDSQX6J2QALD2XTU5NQ4FWA2MMEFKBOBEB2BIOQ; true + NDLFVQ3C25P5VO2VWP6AMHPIJT6FZYTXNJD4ZAY; true + NCXX3KEIEZ3NABMUU45GM7X7BLMPMQHFOZMMF4Q; true + NDF4ZCXFKIU5DSJEVBOOI2BDZMDKJTGJVBD6JRY; true + NCTTMDTZUUQVN4OKTSF3FTEHJQL2QOGAV25MDCA; true + NDLORKVADZSXTIVAA2FYLDMM7I32AIWE7HDWGUQ; true + NCQADXOA7ZHLUW2567H33HNNEKCOCN2OJ53PXIQ; true + NDX4GP6OL32EOSGXSB5FTGKXDJZP4D535ZZYDFI; true + NCE3EP762222D5D2UAF6KIFL7XZ7U4TPFWBYVHA; true + NDRLHNV4W7W2M527QOIP35OI3HOMAGTCJDPFDEQ; true + NDNGH7WJHSMULMCKYE333V6WU4CQDWXZIJK2VCY; true + NB5NIEQF7FM7LLSFASHOQF4X3F6IPDYSIGR3UVA; true + NDC3U2UERNMRYFQA45XC74TEEETTZPRUVWKFPAY; true + NBNCW3DUUHGBCVJ53LYSYYNMKJ52TLR33C5U53A; true + NCAXT7RH6SUPXEU75EIPAPF7DM4VWUBC5AW2L4Q; true + NALOQMBU45WOLZ4BCBYZX3N2Y2VSYQFOXGAO34A; true + NA2KVKEQDZZMM3NGXYVBHZ46JHM46UWIX3KJ4AY; true + NBI2NEBVAD45WWV44H3A53AQ5675Z4G3ZDGDYLI; true + NB5ORUTTH2QYHEVTDBB5WPQI4US22FNMODFRK5Y; true + NDMR4GMUWGMODWY4FF2VZ3CEC2F56HTD3T6EJYY; true + NCBLL63WUAL7FBNPZQISGJR4WZNB7RVWCWG25MI; true + NBGGUKW3GEUFHKTO4DYSGDTHIVPKAME3T2XSCGY; true + NCASTBFHXMHGQB2UJVUDSW7ZI4N2FDW54OTSHKQ; true + ND726EB3B2VG77J3EEQSGNGUX3SS6L2IEBS7PIY; true + ND2MRMODKMLCFJWPFJ4MDFI76R7FLZVKIIVKD3A; true + NDG6ORUW4PVWVQJRQ5AXADQBUQVL3KBX7AW7MUY; true + NBQS3VKGOJ3YNIABN4Y4SFUDBDQHARUIVS6IMGQ; true + NCC3VKV3V2HCAP2KTXJUWSXCJ3B6U32EKR6VU5I; true + NBUW4OTD42VHELNPCLPQCUHNBHR47PQKLP2EKXA; true + NDBKLXZWYBMUUTNRRZ5ESRAJYMQIMHGLGAYLTGY; true + NABH3A5VDLYAVA73OV246JTVMAIPD2WEMAQL27I; true + NCVG74MGUGR3PLVBWVNNACD6R37JA4RCQMXY3DY; true + NDQLBLKXVOK2YS5G7J3AYYKTNW3S3RRK6RQONAQ; true + NDTNPG2NUA3MPVDXHLC6D5PSKM4JLLTMQJ5HEDY; true + ND4MLYCECHPACYSDDQUFMPXONSIQLPAWNVBWSIA; true + NCNRS6KDPHV4MNMXOEGYD6LNRBMWUR7NT4SZI7I; true + NBRENIWJUCSUU7RJ5S2DEJVXAOJOTZZDKEFOC3I; true + NA7YZPY222RVYQMUM65ZSVFSPAHL55UWO3S35FY; true + NCVR72OUOHVGTVLYBKI7PLUDTIAYPRUWPMJJP3Q; true + NDE57ICE4UOAPUV3E4CYU3PBA2X4ABUGRGKDFBA; true + NBBBCIKJV45U7PNYTNXETH2UFZLJ3C6TJKLJDQQ; true + NCRLDB2O2QDPU57PEG3D3AIFSGPGCZU7VVTKBUY; true + NC7QENF6OO2FRYV7Q4B5Q74LRSC54Y3YNYN5O3Y; true + NAL4XHZU6MANNNFQI4Z2WNMU3KRI2YW2MRRMHLI; true + NC5CFRDWEZVCMGQ4Y77OEFSQLMQ3V4EL7JERY2A; true + NAIPUZBSDXZIHQKKILAFT3F43IQPS4LOZCH2H4Q; true + ND6ZNSQG3I7VWLWSJ3DTYVPEZSJRGSEERW2F7DI; true + NC54KVIISZCMMB3ABAMV6NQ6DAUIYYVKQ23S73Q; true + NBNRFJSGE53UNHBGZIHYZXPG7SHLQISJN5REGIY; true + NCFFJV3VTAK6BJZNV6ZRUZKUJPOWST6MYFAAK5A; true + NAAZKYH4V6SARDIJRGFXYEZIHVRWY7R2T62QFYA; true + NAGCLXJZHZSBM5ILN4LQBDKU4NYVHB6ZLGRTKJI; true + NBGEJ36QK43DR4MYB6XFUFLSVFLULX3HBVNRCVY; true + NCGCVCURBA2GCKPEGEA2Q6HKFEHYITKUNWRLMEA; true + NA5ZUGHBUUHO63E5OQQND7CYK7UZ3HVQONR2O6Y; true + NC2GXL6FQXZY3FXZAYJLBDQHBKSANZLGP4PL7VA; true + NB3WMVRI4RM3O3NUSWBZM7U4EZMKADSOFDPPJRQ; true + NCFH35TMUJ5QJL6LTBYRBO7ERMM4NIBH7TL6TFY; true config-harvesting.properties ============================ @@ -619,7 +683,7 @@ config-network.properties :delim: ; **network**; ; ; - identifier; public; NetworkIdentifier; Network identifier. + identifier; mainnet; NetworkIdentifier; Network identifier. nemesisSignerPublicKey; BE0B4CF546B7B4F4BBFCFF9F574FDA527C07A53D3FC76F8BB7DB746F8E8E0A9F; Key; Nemesis public key. nodeEqualityStrategy; host; NodeIdentityEqualityStrategy; Node equality strategy. generationHashSeed; 57F7DA205008026C776CB6AED843393F04CD458E0AA2D9F1D5F31A402072B2D6; ; @@ -650,10 +714,11 @@ config-network.properties maxVotingKeyLifetime; 360; uint32_t; Maximum number of finalization rounds for which voting key can be registered. harvestBeneficiaryPercentage; 25; uint8_t; Percentage of the harvested fee that is collected by the beneficiary account. harvestNetworkPercentage; 5; uint8_t; Percentage of the harvested fee that is collected by the network. - harvestNetworkFeeSinkAddress; NBUTOBVT5JQDCV6UEPCPFHWWOAOPOCLA5AY5FLI; Address; Address of the harvest network fee sink account. + harvestNetworkFeeSinkAddressV1; NBUTOBVT5JQDCV6UEPCPFHWWOAOPOCLA5AY5FLI; ; + harvestNetworkFeeSinkAddress; NAVORTEX3IPBAUWQBBI3I3BDIOS4AVHPZLCFC7Y; Address; Address of the harvest network fee sink account. maxTransactionsPerBlock; 6'000; uint32_t; Maximum number of transactions per block. - **fork_heights**; ; ; - totalVotingBalanceCalculationFix; 528'000; uint32_t; Height of fork to fix TotalVotingBalance calculation. + treasuryReissuanceBlockTransactionsHash; 1A95DA607D545C7E5103EC8D3411E6E505D5B7567E8F3857CD6AEBAD90D3B07F; ; + treasuryReissuanceFallbackBlockTransactionsHash; E1DFEA3F15CDB974EA621A4A9E60B2EC676802DEAA542FE665D2FA364BB4C13D; ; **plugin:catapult.plugins.accountlink**; dummy; to trigger plugin load **plugin:catapult.plugins.aggregate**; ; ; @@ -675,7 +740,8 @@ config-network.properties maxMosaicsPerAccount; 1'000; uint16_t; Maximum number of mosaics that an account can own. maxMosaicDuration; 3650d; utils::BlockSpan; Maximum mosaic duration. maxMosaicDivisibility; 6; uint8_t; Maximum mosaic divisibility. - mosaicRentalFeeSinkAddress; NC733XE7DF46Q7QYLIIZBBSCJN2BEEP5FQ6PAYA; Address; Address of the mosaic rental fee sink account. + mosaicRentalFeeSinkAddressV1; NC733XE7DF46Q7QYLIIZBBSCJN2BEEP5FQ6PAYA; ; + mosaicRentalFeeSinkAddress; NCVORTEX4XD5IQASZQEHDWUXT33XBOTBMKFDCLI; Address; Address of the mosaic rental fee sink account. mosaicRentalFee; 500000; Amount; Mosaic rental fee. **plugin:catapult.plugins.multisig**; ; ; maxMultisigDepth; 3; uint8_t; Maximum number of multisig levels. @@ -689,7 +755,8 @@ config-network.properties maxNamespaceDuration; 1825d; utils::BlockSpan; Maximum namespace duration. namespaceGracePeriodDuration; 30d; utils::BlockSpan; Grace period during which time only the previous owner can renew an expired namespace. reservedRootNamespaceNames; symbol, symbl, xym, xem, nem, user, account, org, com, biz, net, edu, mil, gov, info; unordered_set; Reserved root namespaces that cannot be claimed. - namespaceRentalFeeSinkAddress; NBDTBUD6R32ZYJWDEWLJM4YMOX3OOILHGDUMTSA; Address; Address of the namespace rental fee sink account. + namespaceRentalFeeSinkAddressV1; NBDTBUD6R32ZYJWDEWLJM4YMOX3OOILHGDUMTSA; ; + namespaceRentalFeeSinkAddress; NCVORTEX4XD5IQASZQEHDWUXT33XBOTBMKFDCLI; Address; Address of the namespace rental fee sink account. rootNamespaceRentalFeePerBlock; 2; Amount; Root namespace rental fee per block. childNamespaceRentalFee; 100000; Amount; Child namespace rental fee. **plugin:catapult.plugins.restrictionaccount**; ; ; @@ -698,6 +765,19 @@ config-network.properties maxMosaicRestrictionValues; 20; uint8_t; Maximum number of mosaic restriction values. **plugin:catapult.plugins.transfer**; ; ; maxMessageSize; 1024; uint16_t; Maximum transaction message size. + **fork_heights**; ; ; + totalVotingBalanceCalculationFix; 528'000; uint32_t; Height of fork to fix TotalVotingBalance calculation. + treasuryReissuance; 689'761; ; + **treasury_reissuance_transaction_signatures**; + 0BBEADD37539444D75C09A245102D2B883267925398504623835DCD625290DEE4FA2371341050C49C001DEDD1C9FE241EA4A7DB335B2069FD4DAFF77AF734C03; true + 89447704270E8B2F8EED19526587DB58870D90A02ACEF8AE2A54311DEB95C227201CD39662A0229D5746FFB84074EA6C7DD9620A2CE5AA69065C508DC0335201; true + D19BCD440545CF785D88F903141DE794F2D57012509BC224B25BFCA220267D1ADD42182702F50C1A4E95D0F21604E4F9EEEEF329932FCD0C76B43992B0D90B0D; true + C478DB6053C639AFC96F5D965159DC95449E5EE69A62E5FA28DF42D85C031B3A131B3AC403D9BFF27E1E64FD8012D05C720F0D2A8654D9F4BC48C8DD2DCEBC03; true + C0BAE301EC15B514C5685A661BC3E23A6596CE9DC412A83F67A8C8611A4415B1B0447E8C09D2816CAE0D750C4AB1ED8FE9C85C05D448C2114147A2C935030708; true + A317F4EB085C8D3D80435669EF54C6C9C9AD9B57165B14CF051F43879D0112E3A79591DD6D469BFAA850891FA2CB601BA58CD1BAEBFF5D84C49179AC7FE14706; true + FDB98C472D0B98FDD766DA177366DEB2DB0E79721BD73DA96A84622A98932DA75BAA327BA9E23D448C6F25344654A6F17F7734C14D1530B327F911A97B4DE30A; true + **treasury_reissuance_fallback_transaction_signatures**; + E29FA2456E505044B2087D4D4FFC390D3E2BDAEF2233E10E812C8677D1DE95DDB5D7A696D8C697DB74D07DC9AB863659EE9C6E984BE83E394AE632D21129EC0F; true config-node.properties ====================== @@ -723,7 +803,7 @@ config-node.properties shortLivedCachePruneInterval; 90s; utils::TimeSpan; Time between short lived cache pruning. shortLivedCacheMaxSize; 10'000'000; uint32_t; Maximum size of a short lived cache. minFeeMultiplier; 100; BlockFeeMultiplier; Minimum fee multiplier of transactions to propagate and include in blocks. - maxTimeBehindPullTransactionsStart; 5m; ; + maxTimeBehindPullTransactionsStart; 24h; ; transactionSelectionStrategy; oldest; model::TransactionSelectionStrategy; Transaction selection strategy used for syncing and harvesting unconfirmed transactions. unconfirmedTransactionsCacheMaxResponseSize; 5MB; utils::FileSize; Maximum size of an unconfirmed transactions response. unconfirmedTransactionsCacheMaxSize; 20MB; uint32_t; Maximum size of the unconfirmed transactions cache. @@ -741,7 +821,7 @@ config-node.properties enableDispatcherAbortWhenFull; false; bool; Set to true if the process should terminate when any dispatcher is full. enableDispatcherInputAuditing; false; bool; Set to true if all dispatcher inputs should be audited. maxTrackedNodes; 5'000; uint32_t; Maximum number of nodes to track in memory. - minPartnerNodeVersion; 1.0.1.0; ; + minPartnerNodeVersion; 1.0.2.0; ; maxPartnerNodeVersion; 1.0.255.255; ; trustedHosts; 127.0.0.1, 172.20.0.25; unordered_set; Trusted hosts that are allowed to execute protected API calls on this node. localNetworks; 127.0.0.1, 172.20.0.25; unordered_set; Networks that should be treated as local. @@ -757,7 +837,7 @@ config-node.properties **localnode**; ; ; host; ; string; Node host (leave empty to auto-detect IP). friendlyName; myFriendlyName; string; Node friendly name (leave empty to use address). - version; 1.0.2.0; uint32_t; Node version. + version; ; uint32_t; Node version. roles; Peer,Api,Voting; ionet::NodeRoles; Node roles. **outgoing_connections**; ; ; maxConnections; 10; uint16_t; Maximum number of active connections. diff --git a/test/reports/mainnet-dual-voting/rest-gateway-rest.json b/test/reports/mainnet-dual-voting/rest-gateway-rest.json index 060614d72..5f351fdd1 100644 --- a/test/reports/mainnet-dual-voting/rest-gateway-rest.json +++ b/test/reports/mainnet-dual-voting/rest-gateway-rest.json @@ -1,9 +1,12 @@ { "network": { - "name": "public", + "name": "mainnet", "description": "catapult public main network" }, "port": 3000, + "protocol": "HTTP", + "sslKeyPath": "/symbol-workdir/restSSL.key", + "sslCertificatePath": "/symbol-workdir/restSSL.crt", "crossDomain": { "allowedHosts": [ "*" diff --git a/test/reports/mainnet-dual/node-config.csv b/test/reports/mainnet-dual/node-config.csv index ddb5ffae3..1a600c093 100644 --- a/test/reports/mainnet-dual/node-config.csv +++ b/test/reports/mainnet-dual/node-config.csv @@ -73,6 +73,71 @@ messageSynchronizationMaxResponseSize; 20MB maxHashesPerPoint; 256 prevoteBlocksMultiple; 4 unfinalizedBlocksDuration; 10m +treasuryReissuanceEpoch; 481 + +treasury_reissuance_epoch_ineligible_voter_addresses +ND6667LJBJJ6UMJSZKN2BLHQCS3WNZ3W4UGCFKI; true +NCKAC225JEFJTB3EO64MIVYF5D7YGZM2ZFXRJNI; true +NACXOOKIDID7S75S4FFSC7KBBIBHOBUXB5VSE7A; true +NCVQPB2LZ6UCYKGYJAMCC7V4JGXA35BBY44BMHY; true +NDSQX6J2QALD2XTU5NQ4FWA2MMEFKBOBEB2BIOQ; true +NDLFVQ3C25P5VO2VWP6AMHPIJT6FZYTXNJD4ZAY; true +NCXX3KEIEZ3NABMUU45GM7X7BLMPMQHFOZMMF4Q; true +NDF4ZCXFKIU5DSJEVBOOI2BDZMDKJTGJVBD6JRY; true +NCTTMDTZUUQVN4OKTSF3FTEHJQL2QOGAV25MDCA; true +NDLORKVADZSXTIVAA2FYLDMM7I32AIWE7HDWGUQ; true +NCQADXOA7ZHLUW2567H33HNNEKCOCN2OJ53PXIQ; true +NDX4GP6OL32EOSGXSB5FTGKXDJZP4D535ZZYDFI; true +NCE3EP762222D5D2UAF6KIFL7XZ7U4TPFWBYVHA; true +NDRLHNV4W7W2M527QOIP35OI3HOMAGTCJDPFDEQ; true +NDNGH7WJHSMULMCKYE333V6WU4CQDWXZIJK2VCY; true +NB5NIEQF7FM7LLSFASHOQF4X3F6IPDYSIGR3UVA; true +NDC3U2UERNMRYFQA45XC74TEEETTZPRUVWKFPAY; true +NBNCW3DUUHGBCVJ53LYSYYNMKJ52TLR33C5U53A; true +NCAXT7RH6SUPXEU75EIPAPF7DM4VWUBC5AW2L4Q; true +NALOQMBU45WOLZ4BCBYZX3N2Y2VSYQFOXGAO34A; true +NA2KVKEQDZZMM3NGXYVBHZ46JHM46UWIX3KJ4AY; true +NBI2NEBVAD45WWV44H3A53AQ5675Z4G3ZDGDYLI; true +NB5ORUTTH2QYHEVTDBB5WPQI4US22FNMODFRK5Y; true +NDMR4GMUWGMODWY4FF2VZ3CEC2F56HTD3T6EJYY; true +NCBLL63WUAL7FBNPZQISGJR4WZNB7RVWCWG25MI; true +NBGGUKW3GEUFHKTO4DYSGDTHIVPKAME3T2XSCGY; true +NCASTBFHXMHGQB2UJVUDSW7ZI4N2FDW54OTSHKQ; true +ND726EB3B2VG77J3EEQSGNGUX3SS6L2IEBS7PIY; true +ND2MRMODKMLCFJWPFJ4MDFI76R7FLZVKIIVKD3A; true +NDG6ORUW4PVWVQJRQ5AXADQBUQVL3KBX7AW7MUY; true +NBQS3VKGOJ3YNIABN4Y4SFUDBDQHARUIVS6IMGQ; true +NCC3VKV3V2HCAP2KTXJUWSXCJ3B6U32EKR6VU5I; true +NBUW4OTD42VHELNPCLPQCUHNBHR47PQKLP2EKXA; true +NDBKLXZWYBMUUTNRRZ5ESRAJYMQIMHGLGAYLTGY; true +NABH3A5VDLYAVA73OV246JTVMAIPD2WEMAQL27I; true +NCVG74MGUGR3PLVBWVNNACD6R37JA4RCQMXY3DY; true +NDQLBLKXVOK2YS5G7J3AYYKTNW3S3RRK6RQONAQ; true +NDTNPG2NUA3MPVDXHLC6D5PSKM4JLLTMQJ5HEDY; true +ND4MLYCECHPACYSDDQUFMPXONSIQLPAWNVBWSIA; true +NCNRS6KDPHV4MNMXOEGYD6LNRBMWUR7NT4SZI7I; true +NBRENIWJUCSUU7RJ5S2DEJVXAOJOTZZDKEFOC3I; true +NA7YZPY222RVYQMUM65ZSVFSPAHL55UWO3S35FY; true +NCVR72OUOHVGTVLYBKI7PLUDTIAYPRUWPMJJP3Q; true +NDE57ICE4UOAPUV3E4CYU3PBA2X4ABUGRGKDFBA; true +NBBBCIKJV45U7PNYTNXETH2UFZLJ3C6TJKLJDQQ; true +NCRLDB2O2QDPU57PEG3D3AIFSGPGCZU7VVTKBUY; true +NC7QENF6OO2FRYV7Q4B5Q74LRSC54Y3YNYN5O3Y; true +NAL4XHZU6MANNNFQI4Z2WNMU3KRI2YW2MRRMHLI; true +NC5CFRDWEZVCMGQ4Y77OEFSQLMQ3V4EL7JERY2A; true +NAIPUZBSDXZIHQKKILAFT3F43IQPS4LOZCH2H4Q; true +ND6ZNSQG3I7VWLWSJ3DTYVPEZSJRGSEERW2F7DI; true +NC54KVIISZCMMB3ABAMV6NQ6DAUIYYVKQ23S73Q; true +NBNRFJSGE53UNHBGZIHYZXPG7SHLQISJN5REGIY; true +NCFFJV3VTAK6BJZNV6ZRUZKUJPOWST6MYFAAK5A; true +NAAZKYH4V6SARDIJRGFXYEZIHVRWY7R2T62QFYA; true +NAGCLXJZHZSBM5ILN4LQBDKU4NYVHB6ZLGRTKJI; true +NBGEJ36QK43DR4MYB6XFUFLSVFLULX3HBVNRCVY; true +NCGCVCURBA2GCKPEGEA2Q6HKFEHYITKUNWRLMEA; true +NA5ZUGHBUUHO63E5OQQND7CYK7UZ3HVQONR2O6Y; true +NC2GXL6FQXZY3FXZAYJLBDQHBKSANZLGP4PL7VA; true +NB3WMVRI4RM3O3NUSWBZM7U4EZMKADSOFDPPJRQ; true +NCFH35TMUJ5QJL6LTBYRBO7ERMM4NIBH7TL6TFY; true config-harvesting.properties @@ -580,7 +645,7 @@ listenInterface; 0.0.0.0 config-network.properties network -identifier; public; NetworkIdentifier; Network identifier. +identifier; mainnet; NetworkIdentifier; Network identifier. nemesisSignerPublicKey; BE0B4CF546B7B4F4BBFCFF9F574FDA527C07A53D3FC76F8BB7DB746F8E8E0A9F; Key; Nemesis public key. nodeEqualityStrategy; host; NodeIdentityEqualityStrategy; Node equality strategy. generationHashSeed; 57F7DA205008026C776CB6AED843393F04CD458E0AA2D9F1D5F31A402072B2D6; ; @@ -612,11 +677,11 @@ minVotingKeyLifetime; 112; uint32_t; Minimum number of finalization rounds for w maxVotingKeyLifetime; 360; uint32_t; Maximum number of finalization rounds for which voting key can be registered. harvestBeneficiaryPercentage; 25; uint8_t; Percentage of the harvested fee that is collected by the beneficiary account. harvestNetworkPercentage; 5; uint8_t; Percentage of the harvested fee that is collected by the network. -harvestNetworkFeeSinkAddress; NBUTOBVT5JQDCV6UEPCPFHWWOAOPOCLA5AY5FLI; Address; Address of the harvest network fee sink account. +harvestNetworkFeeSinkAddressV1; NBUTOBVT5JQDCV6UEPCPFHWWOAOPOCLA5AY5FLI; ; +harvestNetworkFeeSinkAddress; NAVORTEX3IPBAUWQBBI3I3BDIOS4AVHPZLCFC7Y; Address; Address of the harvest network fee sink account. maxTransactionsPerBlock; 6'000; uint32_t; Maximum number of transactions per block. - -fork_heights -totalVotingBalanceCalculationFix; 528'000; uint32_t; Height of fork to fix TotalVotingBalance calculation. +treasuryReissuanceBlockTransactionsHash; 1A95DA607D545C7E5103EC8D3411E6E505D5B7567E8F3857CD6AEBAD90D3B07F; ; +treasuryReissuanceFallbackBlockTransactionsHash; E1DFEA3F15CDB974EA621A4A9E60B2EC676802DEAA542FE665D2FA364BB4C13D; ; plugin:catapult.plugins.accountlink dummy; to trigger plugin load @@ -644,7 +709,8 @@ plugin:catapult.plugins.mosaic maxMosaicsPerAccount; 1'000; uint16_t; Maximum number of mosaics that an account can own. maxMosaicDuration; 3650d; utils::BlockSpan; Maximum mosaic duration. maxMosaicDivisibility; 6; uint8_t; Maximum mosaic divisibility. -mosaicRentalFeeSinkAddress; NC733XE7DF46Q7QYLIIZBBSCJN2BEEP5FQ6PAYA; Address; Address of the mosaic rental fee sink account. +mosaicRentalFeeSinkAddressV1; NC733XE7DF46Q7QYLIIZBBSCJN2BEEP5FQ6PAYA; ; +mosaicRentalFeeSinkAddress; NCVORTEX4XD5IQASZQEHDWUXT33XBOTBMKFDCLI; Address; Address of the mosaic rental fee sink account. mosaicRentalFee; 500000; Amount; Mosaic rental fee. plugin:catapult.plugins.multisig @@ -660,7 +726,8 @@ minNamespaceDuration; 30d; utils::BlockSpan; Minimum namespace duration. maxNamespaceDuration; 1825d; utils::BlockSpan; Maximum namespace duration. namespaceGracePeriodDuration; 30d; utils::BlockSpan; Grace period during which time only the previous owner can renew an expired namespace. reservedRootNamespaceNames; symbol, symbl, xym, xem, nem, user, account, org, com, biz, net, edu, mil, gov, info; unordered_set; Reserved root namespaces that cannot be claimed. -namespaceRentalFeeSinkAddress; NBDTBUD6R32ZYJWDEWLJM4YMOX3OOILHGDUMTSA; Address; Address of the namespace rental fee sink account. +namespaceRentalFeeSinkAddressV1; NBDTBUD6R32ZYJWDEWLJM4YMOX3OOILHGDUMTSA; ; +namespaceRentalFeeSinkAddress; NCVORTEX4XD5IQASZQEHDWUXT33XBOTBMKFDCLI; Address; Address of the namespace rental fee sink account. rootNamespaceRentalFeePerBlock; 2; Amount; Root namespace rental fee per block. childNamespaceRentalFee; 100000; Amount; Child namespace rental fee. @@ -673,6 +740,22 @@ maxMosaicRestrictionValues; 20; uint8_t; Maximum number of mosaic restriction va plugin:catapult.plugins.transfer maxMessageSize; 1024; uint16_t; Maximum transaction message size. +fork_heights +totalVotingBalanceCalculationFix; 528'000; uint32_t; Height of fork to fix TotalVotingBalance calculation. +treasuryReissuance; 689'761; ; + +treasury_reissuance_transaction_signatures +0BBEADD37539444D75C09A245102D2B883267925398504623835DCD625290DEE4FA2371341050C49C001DEDD1C9FE241EA4A7DB335B2069FD4DAFF77AF734C03; true +89447704270E8B2F8EED19526587DB58870D90A02ACEF8AE2A54311DEB95C227201CD39662A0229D5746FFB84074EA6C7DD9620A2CE5AA69065C508DC0335201; true +D19BCD440545CF785D88F903141DE794F2D57012509BC224B25BFCA220267D1ADD42182702F50C1A4E95D0F21604E4F9EEEEF329932FCD0C76B43992B0D90B0D; true +C478DB6053C639AFC96F5D965159DC95449E5EE69A62E5FA28DF42D85C031B3A131B3AC403D9BFF27E1E64FD8012D05C720F0D2A8654D9F4BC48C8DD2DCEBC03; true +C0BAE301EC15B514C5685A661BC3E23A6596CE9DC412A83F67A8C8611A4415B1B0447E8C09D2816CAE0D750C4AB1ED8FE9C85C05D448C2114147A2C935030708; true +A317F4EB085C8D3D80435669EF54C6C9C9AD9B57165B14CF051F43879D0112E3A79591DD6D469BFAA850891FA2CB601BA58CD1BAEBFF5D84C49179AC7FE14706; true +FDB98C472D0B98FDD766DA177366DEB2DB0E79721BD73DA96A84622A98932DA75BAA327BA9E23D448C6F25344654A6F17F7734C14D1530B327F911A97B4DE30A; true + +treasury_reissuance_fallback_transaction_signatures +E29FA2456E505044B2087D4D4FFC390D3E2BDAEF2233E10E812C8677D1DE95DDB5D7A696D8C697DB74D07DC9AB863659EE9C6E984BE83E394AE632D21129EC0F; true + config-node.properties node @@ -693,7 +776,7 @@ shortLivedCacheBlockDuration; 100m; utils::TimeSpan; Duration of a block in the shortLivedCachePruneInterval; 90s; utils::TimeSpan; Time between short lived cache pruning. shortLivedCacheMaxSize; 10'000'000; uint32_t; Maximum size of a short lived cache. minFeeMultiplier; 100; BlockFeeMultiplier; Minimum fee multiplier of transactions to propagate and include in blocks. -maxTimeBehindPullTransactionsStart; 5m; ; +maxTimeBehindPullTransactionsStart; 24h; ; transactionSelectionStrategy; oldest; model::TransactionSelectionStrategy; Transaction selection strategy used for syncing and harvesting unconfirmed transactions. unconfirmedTransactionsCacheMaxResponseSize; 5MB; utils::FileSize; Maximum size of an unconfirmed transactions response. unconfirmedTransactionsCacheMaxSize; 20MB; uint32_t; Maximum size of the unconfirmed transactions cache. @@ -711,7 +794,7 @@ transactionDisruptorMaxMemorySize; 20MB; ; enableDispatcherAbortWhenFull; false; bool; Set to true if the process should terminate when any dispatcher is full. enableDispatcherInputAuditing; false; bool; Set to true if all dispatcher inputs should be audited. maxTrackedNodes; 5'000; uint32_t; Maximum number of nodes to track in memory. -minPartnerNodeVersion; 1.0.1.0; ; +minPartnerNodeVersion; 1.0.2.0; ; maxPartnerNodeVersion; 1.0.255.255; ; trustedHosts; 127.0.0.1, 172.20.0.25; unordered_set; Trusted hosts that are allowed to execute protected API calls on this node. localNetworks; 127.0.0.1, 172.20.0.25; unordered_set; Networks that should be treated as local. @@ -729,7 +812,7 @@ maxWriteBatchSize; 5MB localnode host; ; string; Node host (leave empty to auto-detect IP). friendlyName; myFriendlyName; string; Node friendly name (leave empty to use address). -version; 1.0.2.0; uint32_t; Node version. +version; ; uint32_t; Node version. roles; Peer,Api; ionet::NodeRoles; Node roles. outgoing_connections diff --git a/test/reports/mainnet-dual/node-config.rst b/test/reports/mainnet-dual/node-config.rst index 9e6cd5b16..7a01dbe1d 100644 --- a/test/reports/mainnet-dual/node-config.rst +++ b/test/reports/mainnet-dual/node-config.rst @@ -93,6 +93,70 @@ config-finalization.properties maxHashesPerPoint; 256 prevoteBlocksMultiple; 4 unfinalizedBlocksDuration; 10m + treasuryReissuanceEpoch; 481 + **treasury_reissuance_epoch_ineligible_voter_addresses**; + ND6667LJBJJ6UMJSZKN2BLHQCS3WNZ3W4UGCFKI; true + NCKAC225JEFJTB3EO64MIVYF5D7YGZM2ZFXRJNI; true + NACXOOKIDID7S75S4FFSC7KBBIBHOBUXB5VSE7A; true + NCVQPB2LZ6UCYKGYJAMCC7V4JGXA35BBY44BMHY; true + NDSQX6J2QALD2XTU5NQ4FWA2MMEFKBOBEB2BIOQ; true + NDLFVQ3C25P5VO2VWP6AMHPIJT6FZYTXNJD4ZAY; true + NCXX3KEIEZ3NABMUU45GM7X7BLMPMQHFOZMMF4Q; true + NDF4ZCXFKIU5DSJEVBOOI2BDZMDKJTGJVBD6JRY; true + NCTTMDTZUUQVN4OKTSF3FTEHJQL2QOGAV25MDCA; true + NDLORKVADZSXTIVAA2FYLDMM7I32AIWE7HDWGUQ; true + NCQADXOA7ZHLUW2567H33HNNEKCOCN2OJ53PXIQ; true + NDX4GP6OL32EOSGXSB5FTGKXDJZP4D535ZZYDFI; true + NCE3EP762222D5D2UAF6KIFL7XZ7U4TPFWBYVHA; true + NDRLHNV4W7W2M527QOIP35OI3HOMAGTCJDPFDEQ; true + NDNGH7WJHSMULMCKYE333V6WU4CQDWXZIJK2VCY; true + NB5NIEQF7FM7LLSFASHOQF4X3F6IPDYSIGR3UVA; true + NDC3U2UERNMRYFQA45XC74TEEETTZPRUVWKFPAY; true + NBNCW3DUUHGBCVJ53LYSYYNMKJ52TLR33C5U53A; true + NCAXT7RH6SUPXEU75EIPAPF7DM4VWUBC5AW2L4Q; true + NALOQMBU45WOLZ4BCBYZX3N2Y2VSYQFOXGAO34A; true + NA2KVKEQDZZMM3NGXYVBHZ46JHM46UWIX3KJ4AY; true + NBI2NEBVAD45WWV44H3A53AQ5675Z4G3ZDGDYLI; true + NB5ORUTTH2QYHEVTDBB5WPQI4US22FNMODFRK5Y; true + NDMR4GMUWGMODWY4FF2VZ3CEC2F56HTD3T6EJYY; true + NCBLL63WUAL7FBNPZQISGJR4WZNB7RVWCWG25MI; true + NBGGUKW3GEUFHKTO4DYSGDTHIVPKAME3T2XSCGY; true + NCASTBFHXMHGQB2UJVUDSW7ZI4N2FDW54OTSHKQ; true + ND726EB3B2VG77J3EEQSGNGUX3SS6L2IEBS7PIY; true + ND2MRMODKMLCFJWPFJ4MDFI76R7FLZVKIIVKD3A; true + NDG6ORUW4PVWVQJRQ5AXADQBUQVL3KBX7AW7MUY; true + NBQS3VKGOJ3YNIABN4Y4SFUDBDQHARUIVS6IMGQ; true + NCC3VKV3V2HCAP2KTXJUWSXCJ3B6U32EKR6VU5I; true + NBUW4OTD42VHELNPCLPQCUHNBHR47PQKLP2EKXA; true + NDBKLXZWYBMUUTNRRZ5ESRAJYMQIMHGLGAYLTGY; true + NABH3A5VDLYAVA73OV246JTVMAIPD2WEMAQL27I; true + NCVG74MGUGR3PLVBWVNNACD6R37JA4RCQMXY3DY; true + NDQLBLKXVOK2YS5G7J3AYYKTNW3S3RRK6RQONAQ; true + NDTNPG2NUA3MPVDXHLC6D5PSKM4JLLTMQJ5HEDY; true + ND4MLYCECHPACYSDDQUFMPXONSIQLPAWNVBWSIA; true + NCNRS6KDPHV4MNMXOEGYD6LNRBMWUR7NT4SZI7I; true + NBRENIWJUCSUU7RJ5S2DEJVXAOJOTZZDKEFOC3I; true + NA7YZPY222RVYQMUM65ZSVFSPAHL55UWO3S35FY; true + NCVR72OUOHVGTVLYBKI7PLUDTIAYPRUWPMJJP3Q; true + NDE57ICE4UOAPUV3E4CYU3PBA2X4ABUGRGKDFBA; true + NBBBCIKJV45U7PNYTNXETH2UFZLJ3C6TJKLJDQQ; true + NCRLDB2O2QDPU57PEG3D3AIFSGPGCZU7VVTKBUY; true + NC7QENF6OO2FRYV7Q4B5Q74LRSC54Y3YNYN5O3Y; true + NAL4XHZU6MANNNFQI4Z2WNMU3KRI2YW2MRRMHLI; true + NC5CFRDWEZVCMGQ4Y77OEFSQLMQ3V4EL7JERY2A; true + NAIPUZBSDXZIHQKKILAFT3F43IQPS4LOZCH2H4Q; true + ND6ZNSQG3I7VWLWSJ3DTYVPEZSJRGSEERW2F7DI; true + NC54KVIISZCMMB3ABAMV6NQ6DAUIYYVKQ23S73Q; true + NBNRFJSGE53UNHBGZIHYZXPG7SHLQISJN5REGIY; true + NCFFJV3VTAK6BJZNV6ZRUZKUJPOWST6MYFAAK5A; true + NAAZKYH4V6SARDIJRGFXYEZIHVRWY7R2T62QFYA; true + NAGCLXJZHZSBM5ILN4LQBDKU4NYVHB6ZLGRTKJI; true + NBGEJ36QK43DR4MYB6XFUFLSVFLULX3HBVNRCVY; true + NCGCVCURBA2GCKPEGEA2Q6HKFEHYITKUNWRLMEA; true + NA5ZUGHBUUHO63E5OQQND7CYK7UZ3HVQONR2O6Y; true + NC2GXL6FQXZY3FXZAYJLBDQHBKSANZLGP4PL7VA; true + NB3WMVRI4RM3O3NUSWBZM7U4EZMKADSOFDPPJRQ; true + NCFH35TMUJ5QJL6LTBYRBO7ERMM4NIBH7TL6TFY; true config-harvesting.properties ============================ @@ -619,7 +683,7 @@ config-network.properties :delim: ; **network**; ; ; - identifier; public; NetworkIdentifier; Network identifier. + identifier; mainnet; NetworkIdentifier; Network identifier. nemesisSignerPublicKey; BE0B4CF546B7B4F4BBFCFF9F574FDA527C07A53D3FC76F8BB7DB746F8E8E0A9F; Key; Nemesis public key. nodeEqualityStrategy; host; NodeIdentityEqualityStrategy; Node equality strategy. generationHashSeed; 57F7DA205008026C776CB6AED843393F04CD458E0AA2D9F1D5F31A402072B2D6; ; @@ -650,10 +714,11 @@ config-network.properties maxVotingKeyLifetime; 360; uint32_t; Maximum number of finalization rounds for which voting key can be registered. harvestBeneficiaryPercentage; 25; uint8_t; Percentage of the harvested fee that is collected by the beneficiary account. harvestNetworkPercentage; 5; uint8_t; Percentage of the harvested fee that is collected by the network. - harvestNetworkFeeSinkAddress; NBUTOBVT5JQDCV6UEPCPFHWWOAOPOCLA5AY5FLI; Address; Address of the harvest network fee sink account. + harvestNetworkFeeSinkAddressV1; NBUTOBVT5JQDCV6UEPCPFHWWOAOPOCLA5AY5FLI; ; + harvestNetworkFeeSinkAddress; NAVORTEX3IPBAUWQBBI3I3BDIOS4AVHPZLCFC7Y; Address; Address of the harvest network fee sink account. maxTransactionsPerBlock; 6'000; uint32_t; Maximum number of transactions per block. - **fork_heights**; ; ; - totalVotingBalanceCalculationFix; 528'000; uint32_t; Height of fork to fix TotalVotingBalance calculation. + treasuryReissuanceBlockTransactionsHash; 1A95DA607D545C7E5103EC8D3411E6E505D5B7567E8F3857CD6AEBAD90D3B07F; ; + treasuryReissuanceFallbackBlockTransactionsHash; E1DFEA3F15CDB974EA621A4A9E60B2EC676802DEAA542FE665D2FA364BB4C13D; ; **plugin:catapult.plugins.accountlink**; dummy; to trigger plugin load **plugin:catapult.plugins.aggregate**; ; ; @@ -675,7 +740,8 @@ config-network.properties maxMosaicsPerAccount; 1'000; uint16_t; Maximum number of mosaics that an account can own. maxMosaicDuration; 3650d; utils::BlockSpan; Maximum mosaic duration. maxMosaicDivisibility; 6; uint8_t; Maximum mosaic divisibility. - mosaicRentalFeeSinkAddress; NC733XE7DF46Q7QYLIIZBBSCJN2BEEP5FQ6PAYA; Address; Address of the mosaic rental fee sink account. + mosaicRentalFeeSinkAddressV1; NC733XE7DF46Q7QYLIIZBBSCJN2BEEP5FQ6PAYA; ; + mosaicRentalFeeSinkAddress; NCVORTEX4XD5IQASZQEHDWUXT33XBOTBMKFDCLI; Address; Address of the mosaic rental fee sink account. mosaicRentalFee; 500000; Amount; Mosaic rental fee. **plugin:catapult.plugins.multisig**; ; ; maxMultisigDepth; 3; uint8_t; Maximum number of multisig levels. @@ -689,7 +755,8 @@ config-network.properties maxNamespaceDuration; 1825d; utils::BlockSpan; Maximum namespace duration. namespaceGracePeriodDuration; 30d; utils::BlockSpan; Grace period during which time only the previous owner can renew an expired namespace. reservedRootNamespaceNames; symbol, symbl, xym, xem, nem, user, account, org, com, biz, net, edu, mil, gov, info; unordered_set; Reserved root namespaces that cannot be claimed. - namespaceRentalFeeSinkAddress; NBDTBUD6R32ZYJWDEWLJM4YMOX3OOILHGDUMTSA; Address; Address of the namespace rental fee sink account. + namespaceRentalFeeSinkAddressV1; NBDTBUD6R32ZYJWDEWLJM4YMOX3OOILHGDUMTSA; ; + namespaceRentalFeeSinkAddress; NCVORTEX4XD5IQASZQEHDWUXT33XBOTBMKFDCLI; Address; Address of the namespace rental fee sink account. rootNamespaceRentalFeePerBlock; 2; Amount; Root namespace rental fee per block. childNamespaceRentalFee; 100000; Amount; Child namespace rental fee. **plugin:catapult.plugins.restrictionaccount**; ; ; @@ -698,6 +765,19 @@ config-network.properties maxMosaicRestrictionValues; 20; uint8_t; Maximum number of mosaic restriction values. **plugin:catapult.plugins.transfer**; ; ; maxMessageSize; 1024; uint16_t; Maximum transaction message size. + **fork_heights**; ; ; + totalVotingBalanceCalculationFix; 528'000; uint32_t; Height of fork to fix TotalVotingBalance calculation. + treasuryReissuance; 689'761; ; + **treasury_reissuance_transaction_signatures**; + 0BBEADD37539444D75C09A245102D2B883267925398504623835DCD625290DEE4FA2371341050C49C001DEDD1C9FE241EA4A7DB335B2069FD4DAFF77AF734C03; true + 89447704270E8B2F8EED19526587DB58870D90A02ACEF8AE2A54311DEB95C227201CD39662A0229D5746FFB84074EA6C7DD9620A2CE5AA69065C508DC0335201; true + D19BCD440545CF785D88F903141DE794F2D57012509BC224B25BFCA220267D1ADD42182702F50C1A4E95D0F21604E4F9EEEEF329932FCD0C76B43992B0D90B0D; true + C478DB6053C639AFC96F5D965159DC95449E5EE69A62E5FA28DF42D85C031B3A131B3AC403D9BFF27E1E64FD8012D05C720F0D2A8654D9F4BC48C8DD2DCEBC03; true + C0BAE301EC15B514C5685A661BC3E23A6596CE9DC412A83F67A8C8611A4415B1B0447E8C09D2816CAE0D750C4AB1ED8FE9C85C05D448C2114147A2C935030708; true + A317F4EB085C8D3D80435669EF54C6C9C9AD9B57165B14CF051F43879D0112E3A79591DD6D469BFAA850891FA2CB601BA58CD1BAEBFF5D84C49179AC7FE14706; true + FDB98C472D0B98FDD766DA177366DEB2DB0E79721BD73DA96A84622A98932DA75BAA327BA9E23D448C6F25344654A6F17F7734C14D1530B327F911A97B4DE30A; true + **treasury_reissuance_fallback_transaction_signatures**; + E29FA2456E505044B2087D4D4FFC390D3E2BDAEF2233E10E812C8677D1DE95DDB5D7A696D8C697DB74D07DC9AB863659EE9C6E984BE83E394AE632D21129EC0F; true config-node.properties ====================== @@ -723,7 +803,7 @@ config-node.properties shortLivedCachePruneInterval; 90s; utils::TimeSpan; Time between short lived cache pruning. shortLivedCacheMaxSize; 10'000'000; uint32_t; Maximum size of a short lived cache. minFeeMultiplier; 100; BlockFeeMultiplier; Minimum fee multiplier of transactions to propagate and include in blocks. - maxTimeBehindPullTransactionsStart; 5m; ; + maxTimeBehindPullTransactionsStart; 24h; ; transactionSelectionStrategy; oldest; model::TransactionSelectionStrategy; Transaction selection strategy used for syncing and harvesting unconfirmed transactions. unconfirmedTransactionsCacheMaxResponseSize; 5MB; utils::FileSize; Maximum size of an unconfirmed transactions response. unconfirmedTransactionsCacheMaxSize; 20MB; uint32_t; Maximum size of the unconfirmed transactions cache. @@ -741,7 +821,7 @@ config-node.properties enableDispatcherAbortWhenFull; false; bool; Set to true if the process should terminate when any dispatcher is full. enableDispatcherInputAuditing; false; bool; Set to true if all dispatcher inputs should be audited. maxTrackedNodes; 5'000; uint32_t; Maximum number of nodes to track in memory. - minPartnerNodeVersion; 1.0.1.0; ; + minPartnerNodeVersion; 1.0.2.0; ; maxPartnerNodeVersion; 1.0.255.255; ; trustedHosts; 127.0.0.1, 172.20.0.25; unordered_set; Trusted hosts that are allowed to execute protected API calls on this node. localNetworks; 127.0.0.1, 172.20.0.25; unordered_set; Networks that should be treated as local. @@ -757,7 +837,7 @@ config-node.properties **localnode**; ; ; host; ; string; Node host (leave empty to auto-detect IP). friendlyName; myFriendlyName; string; Node friendly name (leave empty to use address). - version; 1.0.2.0; uint32_t; Node version. + version; ; uint32_t; Node version. roles; Peer,Api; ionet::NodeRoles; Node roles. **outgoing_connections**; ; ; maxConnections; 10; uint16_t; Maximum number of active connections. diff --git a/test/reports/mainnet-dual/rest-gateway-rest.json b/test/reports/mainnet-dual/rest-gateway-rest.json index 060614d72..5f351fdd1 100644 --- a/test/reports/mainnet-dual/rest-gateway-rest.json +++ b/test/reports/mainnet-dual/rest-gateway-rest.json @@ -1,9 +1,12 @@ { "network": { - "name": "public", + "name": "mainnet", "description": "catapult public main network" }, "port": 3000, + "protocol": "HTTP", + "sslKeyPath": "/symbol-workdir/restSSL.key", + "sslCertificatePath": "/symbol-workdir/restSSL.crt", "crossDomain": { "allowedHosts": [ "*" diff --git a/test/reports/mainnet-peer/node-config.csv b/test/reports/mainnet-peer/node-config.csv index 53104d32c..4e5b1755d 100644 --- a/test/reports/mainnet-peer/node-config.csv +++ b/test/reports/mainnet-peer/node-config.csv @@ -73,6 +73,71 @@ messageSynchronizationMaxResponseSize; 20MB maxHashesPerPoint; 256 prevoteBlocksMultiple; 4 unfinalizedBlocksDuration; 10m +treasuryReissuanceEpoch; 481 + +treasury_reissuance_epoch_ineligible_voter_addresses +ND6667LJBJJ6UMJSZKN2BLHQCS3WNZ3W4UGCFKI; true +NCKAC225JEFJTB3EO64MIVYF5D7YGZM2ZFXRJNI; true +NACXOOKIDID7S75S4FFSC7KBBIBHOBUXB5VSE7A; true +NCVQPB2LZ6UCYKGYJAMCC7V4JGXA35BBY44BMHY; true +NDSQX6J2QALD2XTU5NQ4FWA2MMEFKBOBEB2BIOQ; true +NDLFVQ3C25P5VO2VWP6AMHPIJT6FZYTXNJD4ZAY; true +NCXX3KEIEZ3NABMUU45GM7X7BLMPMQHFOZMMF4Q; true +NDF4ZCXFKIU5DSJEVBOOI2BDZMDKJTGJVBD6JRY; true +NCTTMDTZUUQVN4OKTSF3FTEHJQL2QOGAV25MDCA; true +NDLORKVADZSXTIVAA2FYLDMM7I32AIWE7HDWGUQ; true +NCQADXOA7ZHLUW2567H33HNNEKCOCN2OJ53PXIQ; true +NDX4GP6OL32EOSGXSB5FTGKXDJZP4D535ZZYDFI; true +NCE3EP762222D5D2UAF6KIFL7XZ7U4TPFWBYVHA; true +NDRLHNV4W7W2M527QOIP35OI3HOMAGTCJDPFDEQ; true +NDNGH7WJHSMULMCKYE333V6WU4CQDWXZIJK2VCY; true +NB5NIEQF7FM7LLSFASHOQF4X3F6IPDYSIGR3UVA; true +NDC3U2UERNMRYFQA45XC74TEEETTZPRUVWKFPAY; true +NBNCW3DUUHGBCVJ53LYSYYNMKJ52TLR33C5U53A; true +NCAXT7RH6SUPXEU75EIPAPF7DM4VWUBC5AW2L4Q; true +NALOQMBU45WOLZ4BCBYZX3N2Y2VSYQFOXGAO34A; true +NA2KVKEQDZZMM3NGXYVBHZ46JHM46UWIX3KJ4AY; true +NBI2NEBVAD45WWV44H3A53AQ5675Z4G3ZDGDYLI; true +NB5ORUTTH2QYHEVTDBB5WPQI4US22FNMODFRK5Y; true +NDMR4GMUWGMODWY4FF2VZ3CEC2F56HTD3T6EJYY; true +NCBLL63WUAL7FBNPZQISGJR4WZNB7RVWCWG25MI; true +NBGGUKW3GEUFHKTO4DYSGDTHIVPKAME3T2XSCGY; true +NCASTBFHXMHGQB2UJVUDSW7ZI4N2FDW54OTSHKQ; true +ND726EB3B2VG77J3EEQSGNGUX3SS6L2IEBS7PIY; true +ND2MRMODKMLCFJWPFJ4MDFI76R7FLZVKIIVKD3A; true +NDG6ORUW4PVWVQJRQ5AXADQBUQVL3KBX7AW7MUY; true +NBQS3VKGOJ3YNIABN4Y4SFUDBDQHARUIVS6IMGQ; true +NCC3VKV3V2HCAP2KTXJUWSXCJ3B6U32EKR6VU5I; true +NBUW4OTD42VHELNPCLPQCUHNBHR47PQKLP2EKXA; true +NDBKLXZWYBMUUTNRRZ5ESRAJYMQIMHGLGAYLTGY; true +NABH3A5VDLYAVA73OV246JTVMAIPD2WEMAQL27I; true +NCVG74MGUGR3PLVBWVNNACD6R37JA4RCQMXY3DY; true +NDQLBLKXVOK2YS5G7J3AYYKTNW3S3RRK6RQONAQ; true +NDTNPG2NUA3MPVDXHLC6D5PSKM4JLLTMQJ5HEDY; true +ND4MLYCECHPACYSDDQUFMPXONSIQLPAWNVBWSIA; true +NCNRS6KDPHV4MNMXOEGYD6LNRBMWUR7NT4SZI7I; true +NBRENIWJUCSUU7RJ5S2DEJVXAOJOTZZDKEFOC3I; true +NA7YZPY222RVYQMUM65ZSVFSPAHL55UWO3S35FY; true +NCVR72OUOHVGTVLYBKI7PLUDTIAYPRUWPMJJP3Q; true +NDE57ICE4UOAPUV3E4CYU3PBA2X4ABUGRGKDFBA; true +NBBBCIKJV45U7PNYTNXETH2UFZLJ3C6TJKLJDQQ; true +NCRLDB2O2QDPU57PEG3D3AIFSGPGCZU7VVTKBUY; true +NC7QENF6OO2FRYV7Q4B5Q74LRSC54Y3YNYN5O3Y; true +NAL4XHZU6MANNNFQI4Z2WNMU3KRI2YW2MRRMHLI; true +NC5CFRDWEZVCMGQ4Y77OEFSQLMQ3V4EL7JERY2A; true +NAIPUZBSDXZIHQKKILAFT3F43IQPS4LOZCH2H4Q; true +ND6ZNSQG3I7VWLWSJ3DTYVPEZSJRGSEERW2F7DI; true +NC54KVIISZCMMB3ABAMV6NQ6DAUIYYVKQ23S73Q; true +NBNRFJSGE53UNHBGZIHYZXPG7SHLQISJN5REGIY; true +NCFFJV3VTAK6BJZNV6ZRUZKUJPOWST6MYFAAK5A; true +NAAZKYH4V6SARDIJRGFXYEZIHVRWY7R2T62QFYA; true +NAGCLXJZHZSBM5ILN4LQBDKU4NYVHB6ZLGRTKJI; true +NBGEJ36QK43DR4MYB6XFUFLSVFLULX3HBVNRCVY; true +NCGCVCURBA2GCKPEGEA2Q6HKFEHYITKUNWRLMEA; true +NA5ZUGHBUUHO63E5OQQND7CYK7UZ3HVQONR2O6Y; true +NC2GXL6FQXZY3FXZAYJLBDQHBKSANZLGP4PL7VA; true +NB3WMVRI4RM3O3NUSWBZM7U4EZMKADSOFDPPJRQ; true +NCFH35TMUJ5QJL6LTBYRBO7ERMM4NIBH7TL6TFY; true config-harvesting.properties @@ -580,7 +645,7 @@ listenInterface; 0.0.0.0 config-network.properties network -identifier; public; NetworkIdentifier; Network identifier. +identifier; mainnet; NetworkIdentifier; Network identifier. nemesisSignerPublicKey; BE0B4CF546B7B4F4BBFCFF9F574FDA527C07A53D3FC76F8BB7DB746F8E8E0A9F; Key; Nemesis public key. nodeEqualityStrategy; host; NodeIdentityEqualityStrategy; Node equality strategy. generationHashSeed; 57F7DA205008026C776CB6AED843393F04CD458E0AA2D9F1D5F31A402072B2D6; ; @@ -612,11 +677,11 @@ minVotingKeyLifetime; 112; uint32_t; Minimum number of finalization rounds for w maxVotingKeyLifetime; 360; uint32_t; Maximum number of finalization rounds for which voting key can be registered. harvestBeneficiaryPercentage; 25; uint8_t; Percentage of the harvested fee that is collected by the beneficiary account. harvestNetworkPercentage; 5; uint8_t; Percentage of the harvested fee that is collected by the network. -harvestNetworkFeeSinkAddress; NBUTOBVT5JQDCV6UEPCPFHWWOAOPOCLA5AY5FLI; Address; Address of the harvest network fee sink account. +harvestNetworkFeeSinkAddressV1; NBUTOBVT5JQDCV6UEPCPFHWWOAOPOCLA5AY5FLI; ; +harvestNetworkFeeSinkAddress; NAVORTEX3IPBAUWQBBI3I3BDIOS4AVHPZLCFC7Y; Address; Address of the harvest network fee sink account. maxTransactionsPerBlock; 6'000; uint32_t; Maximum number of transactions per block. - -fork_heights -totalVotingBalanceCalculationFix; 528'000; uint32_t; Height of fork to fix TotalVotingBalance calculation. +treasuryReissuanceBlockTransactionsHash; 1A95DA607D545C7E5103EC8D3411E6E505D5B7567E8F3857CD6AEBAD90D3B07F; ; +treasuryReissuanceFallbackBlockTransactionsHash; E1DFEA3F15CDB974EA621A4A9E60B2EC676802DEAA542FE665D2FA364BB4C13D; ; plugin:catapult.plugins.accountlink dummy; to trigger plugin load @@ -644,7 +709,8 @@ plugin:catapult.plugins.mosaic maxMosaicsPerAccount; 1'000; uint16_t; Maximum number of mosaics that an account can own. maxMosaicDuration; 3650d; utils::BlockSpan; Maximum mosaic duration. maxMosaicDivisibility; 6; uint8_t; Maximum mosaic divisibility. -mosaicRentalFeeSinkAddress; NC733XE7DF46Q7QYLIIZBBSCJN2BEEP5FQ6PAYA; Address; Address of the mosaic rental fee sink account. +mosaicRentalFeeSinkAddressV1; NC733XE7DF46Q7QYLIIZBBSCJN2BEEP5FQ6PAYA; ; +mosaicRentalFeeSinkAddress; NCVORTEX4XD5IQASZQEHDWUXT33XBOTBMKFDCLI; Address; Address of the mosaic rental fee sink account. mosaicRentalFee; 500000; Amount; Mosaic rental fee. plugin:catapult.plugins.multisig @@ -660,7 +726,8 @@ minNamespaceDuration; 30d; utils::BlockSpan; Minimum namespace duration. maxNamespaceDuration; 1825d; utils::BlockSpan; Maximum namespace duration. namespaceGracePeriodDuration; 30d; utils::BlockSpan; Grace period during which time only the previous owner can renew an expired namespace. reservedRootNamespaceNames; symbol, symbl, xym, xem, nem, user, account, org, com, biz, net, edu, mil, gov, info; unordered_set; Reserved root namespaces that cannot be claimed. -namespaceRentalFeeSinkAddress; NBDTBUD6R32ZYJWDEWLJM4YMOX3OOILHGDUMTSA; Address; Address of the namespace rental fee sink account. +namespaceRentalFeeSinkAddressV1; NBDTBUD6R32ZYJWDEWLJM4YMOX3OOILHGDUMTSA; ; +namespaceRentalFeeSinkAddress; NCVORTEX4XD5IQASZQEHDWUXT33XBOTBMKFDCLI; Address; Address of the namespace rental fee sink account. rootNamespaceRentalFeePerBlock; 2; Amount; Root namespace rental fee per block. childNamespaceRentalFee; 100000; Amount; Child namespace rental fee. @@ -673,6 +740,22 @@ maxMosaicRestrictionValues; 20; uint8_t; Maximum number of mosaic restriction va plugin:catapult.plugins.transfer maxMessageSize; 1024; uint16_t; Maximum transaction message size. +fork_heights +totalVotingBalanceCalculationFix; 528'000; uint32_t; Height of fork to fix TotalVotingBalance calculation. +treasuryReissuance; 689'761; ; + +treasury_reissuance_transaction_signatures +0BBEADD37539444D75C09A245102D2B883267925398504623835DCD625290DEE4FA2371341050C49C001DEDD1C9FE241EA4A7DB335B2069FD4DAFF77AF734C03; true +89447704270E8B2F8EED19526587DB58870D90A02ACEF8AE2A54311DEB95C227201CD39662A0229D5746FFB84074EA6C7DD9620A2CE5AA69065C508DC0335201; true +D19BCD440545CF785D88F903141DE794F2D57012509BC224B25BFCA220267D1ADD42182702F50C1A4E95D0F21604E4F9EEEEF329932FCD0C76B43992B0D90B0D; true +C478DB6053C639AFC96F5D965159DC95449E5EE69A62E5FA28DF42D85C031B3A131B3AC403D9BFF27E1E64FD8012D05C720F0D2A8654D9F4BC48C8DD2DCEBC03; true +C0BAE301EC15B514C5685A661BC3E23A6596CE9DC412A83F67A8C8611A4415B1B0447E8C09D2816CAE0D750C4AB1ED8FE9C85C05D448C2114147A2C935030708; true +A317F4EB085C8D3D80435669EF54C6C9C9AD9B57165B14CF051F43879D0112E3A79591DD6D469BFAA850891FA2CB601BA58CD1BAEBFF5D84C49179AC7FE14706; true +FDB98C472D0B98FDD766DA177366DEB2DB0E79721BD73DA96A84622A98932DA75BAA327BA9E23D448C6F25344654A6F17F7734C14D1530B327F911A97B4DE30A; true + +treasury_reissuance_fallback_transaction_signatures +E29FA2456E505044B2087D4D4FFC390D3E2BDAEF2233E10E812C8677D1DE95DDB5D7A696D8C697DB74D07DC9AB863659EE9C6E984BE83E394AE632D21129EC0F; true + config-node.properties node @@ -693,7 +776,7 @@ shortLivedCacheBlockDuration; 100m; utils::TimeSpan; Duration of a block in the shortLivedCachePruneInterval; 90s; utils::TimeSpan; Time between short lived cache pruning. shortLivedCacheMaxSize; 10'000'000; uint32_t; Maximum size of a short lived cache. minFeeMultiplier; 100; BlockFeeMultiplier; Minimum fee multiplier of transactions to propagate and include in blocks. -maxTimeBehindPullTransactionsStart; 5m; ; +maxTimeBehindPullTransactionsStart; 24h; ; transactionSelectionStrategy; oldest; model::TransactionSelectionStrategy; Transaction selection strategy used for syncing and harvesting unconfirmed transactions. unconfirmedTransactionsCacheMaxResponseSize; 5MB; utils::FileSize; Maximum size of an unconfirmed transactions response. unconfirmedTransactionsCacheMaxSize; 20MB; uint32_t; Maximum size of the unconfirmed transactions cache. @@ -711,7 +794,7 @@ transactionDisruptorMaxMemorySize; 20MB; ; enableDispatcherAbortWhenFull; false; bool; Set to true if the process should terminate when any dispatcher is full. enableDispatcherInputAuditing; false; bool; Set to true if all dispatcher inputs should be audited. maxTrackedNodes; 5'000; uint32_t; Maximum number of nodes to track in memory. -minPartnerNodeVersion; 1.0.1.0; ; +minPartnerNodeVersion; 1.0.2.0; ; maxPartnerNodeVersion; 1.0.255.255; ; trustedHosts; 127.0.0.1; unordered_set; Trusted hosts that are allowed to execute protected API calls on this node. localNetworks; 127.0.0.1; unordered_set; Networks that should be treated as local. @@ -729,7 +812,7 @@ maxWriteBatchSize; 5MB localnode host; ; string; Node host (leave empty to auto-detect IP). friendlyName; myFriendlyName; string; Node friendly name (leave empty to use address). -version; 1.0.2.0; uint32_t; Node version. +version; ; uint32_t; Node version. roles; Peer; ionet::NodeRoles; Node roles. outgoing_connections diff --git a/test/reports/mainnet-peer/node-config.rst b/test/reports/mainnet-peer/node-config.rst index 56793aebd..a9061e762 100644 --- a/test/reports/mainnet-peer/node-config.rst +++ b/test/reports/mainnet-peer/node-config.rst @@ -93,6 +93,70 @@ config-finalization.properties maxHashesPerPoint; 256 prevoteBlocksMultiple; 4 unfinalizedBlocksDuration; 10m + treasuryReissuanceEpoch; 481 + **treasury_reissuance_epoch_ineligible_voter_addresses**; + ND6667LJBJJ6UMJSZKN2BLHQCS3WNZ3W4UGCFKI; true + NCKAC225JEFJTB3EO64MIVYF5D7YGZM2ZFXRJNI; true + NACXOOKIDID7S75S4FFSC7KBBIBHOBUXB5VSE7A; true + NCVQPB2LZ6UCYKGYJAMCC7V4JGXA35BBY44BMHY; true + NDSQX6J2QALD2XTU5NQ4FWA2MMEFKBOBEB2BIOQ; true + NDLFVQ3C25P5VO2VWP6AMHPIJT6FZYTXNJD4ZAY; true + NCXX3KEIEZ3NABMUU45GM7X7BLMPMQHFOZMMF4Q; true + NDF4ZCXFKIU5DSJEVBOOI2BDZMDKJTGJVBD6JRY; true + NCTTMDTZUUQVN4OKTSF3FTEHJQL2QOGAV25MDCA; true + NDLORKVADZSXTIVAA2FYLDMM7I32AIWE7HDWGUQ; true + NCQADXOA7ZHLUW2567H33HNNEKCOCN2OJ53PXIQ; true + NDX4GP6OL32EOSGXSB5FTGKXDJZP4D535ZZYDFI; true + NCE3EP762222D5D2UAF6KIFL7XZ7U4TPFWBYVHA; true + NDRLHNV4W7W2M527QOIP35OI3HOMAGTCJDPFDEQ; true + NDNGH7WJHSMULMCKYE333V6WU4CQDWXZIJK2VCY; true + NB5NIEQF7FM7LLSFASHOQF4X3F6IPDYSIGR3UVA; true + NDC3U2UERNMRYFQA45XC74TEEETTZPRUVWKFPAY; true + NBNCW3DUUHGBCVJ53LYSYYNMKJ52TLR33C5U53A; true + NCAXT7RH6SUPXEU75EIPAPF7DM4VWUBC5AW2L4Q; true + NALOQMBU45WOLZ4BCBYZX3N2Y2VSYQFOXGAO34A; true + NA2KVKEQDZZMM3NGXYVBHZ46JHM46UWIX3KJ4AY; true + NBI2NEBVAD45WWV44H3A53AQ5675Z4G3ZDGDYLI; true + NB5ORUTTH2QYHEVTDBB5WPQI4US22FNMODFRK5Y; true + NDMR4GMUWGMODWY4FF2VZ3CEC2F56HTD3T6EJYY; true + NCBLL63WUAL7FBNPZQISGJR4WZNB7RVWCWG25MI; true + NBGGUKW3GEUFHKTO4DYSGDTHIVPKAME3T2XSCGY; true + NCASTBFHXMHGQB2UJVUDSW7ZI4N2FDW54OTSHKQ; true + ND726EB3B2VG77J3EEQSGNGUX3SS6L2IEBS7PIY; true + ND2MRMODKMLCFJWPFJ4MDFI76R7FLZVKIIVKD3A; true + NDG6ORUW4PVWVQJRQ5AXADQBUQVL3KBX7AW7MUY; true + NBQS3VKGOJ3YNIABN4Y4SFUDBDQHARUIVS6IMGQ; true + NCC3VKV3V2HCAP2KTXJUWSXCJ3B6U32EKR6VU5I; true + NBUW4OTD42VHELNPCLPQCUHNBHR47PQKLP2EKXA; true + NDBKLXZWYBMUUTNRRZ5ESRAJYMQIMHGLGAYLTGY; true + NABH3A5VDLYAVA73OV246JTVMAIPD2WEMAQL27I; true + NCVG74MGUGR3PLVBWVNNACD6R37JA4RCQMXY3DY; true + NDQLBLKXVOK2YS5G7J3AYYKTNW3S3RRK6RQONAQ; true + NDTNPG2NUA3MPVDXHLC6D5PSKM4JLLTMQJ5HEDY; true + ND4MLYCECHPACYSDDQUFMPXONSIQLPAWNVBWSIA; true + NCNRS6KDPHV4MNMXOEGYD6LNRBMWUR7NT4SZI7I; true + NBRENIWJUCSUU7RJ5S2DEJVXAOJOTZZDKEFOC3I; true + NA7YZPY222RVYQMUM65ZSVFSPAHL55UWO3S35FY; true + NCVR72OUOHVGTVLYBKI7PLUDTIAYPRUWPMJJP3Q; true + NDE57ICE4UOAPUV3E4CYU3PBA2X4ABUGRGKDFBA; true + NBBBCIKJV45U7PNYTNXETH2UFZLJ3C6TJKLJDQQ; true + NCRLDB2O2QDPU57PEG3D3AIFSGPGCZU7VVTKBUY; true + NC7QENF6OO2FRYV7Q4B5Q74LRSC54Y3YNYN5O3Y; true + NAL4XHZU6MANNNFQI4Z2WNMU3KRI2YW2MRRMHLI; true + NC5CFRDWEZVCMGQ4Y77OEFSQLMQ3V4EL7JERY2A; true + NAIPUZBSDXZIHQKKILAFT3F43IQPS4LOZCH2H4Q; true + ND6ZNSQG3I7VWLWSJ3DTYVPEZSJRGSEERW2F7DI; true + NC54KVIISZCMMB3ABAMV6NQ6DAUIYYVKQ23S73Q; true + NBNRFJSGE53UNHBGZIHYZXPG7SHLQISJN5REGIY; true + NCFFJV3VTAK6BJZNV6ZRUZKUJPOWST6MYFAAK5A; true + NAAZKYH4V6SARDIJRGFXYEZIHVRWY7R2T62QFYA; true + NAGCLXJZHZSBM5ILN4LQBDKU4NYVHB6ZLGRTKJI; true + NBGEJ36QK43DR4MYB6XFUFLSVFLULX3HBVNRCVY; true + NCGCVCURBA2GCKPEGEA2Q6HKFEHYITKUNWRLMEA; true + NA5ZUGHBUUHO63E5OQQND7CYK7UZ3HVQONR2O6Y; true + NC2GXL6FQXZY3FXZAYJLBDQHBKSANZLGP4PL7VA; true + NB3WMVRI4RM3O3NUSWBZM7U4EZMKADSOFDPPJRQ; true + NCFH35TMUJ5QJL6LTBYRBO7ERMM4NIBH7TL6TFY; true config-harvesting.properties ============================ @@ -619,7 +683,7 @@ config-network.properties :delim: ; **network**; ; ; - identifier; public; NetworkIdentifier; Network identifier. + identifier; mainnet; NetworkIdentifier; Network identifier. nemesisSignerPublicKey; BE0B4CF546B7B4F4BBFCFF9F574FDA527C07A53D3FC76F8BB7DB746F8E8E0A9F; Key; Nemesis public key. nodeEqualityStrategy; host; NodeIdentityEqualityStrategy; Node equality strategy. generationHashSeed; 57F7DA205008026C776CB6AED843393F04CD458E0AA2D9F1D5F31A402072B2D6; ; @@ -650,10 +714,11 @@ config-network.properties maxVotingKeyLifetime; 360; uint32_t; Maximum number of finalization rounds for which voting key can be registered. harvestBeneficiaryPercentage; 25; uint8_t; Percentage of the harvested fee that is collected by the beneficiary account. harvestNetworkPercentage; 5; uint8_t; Percentage of the harvested fee that is collected by the network. - harvestNetworkFeeSinkAddress; NBUTOBVT5JQDCV6UEPCPFHWWOAOPOCLA5AY5FLI; Address; Address of the harvest network fee sink account. + harvestNetworkFeeSinkAddressV1; NBUTOBVT5JQDCV6UEPCPFHWWOAOPOCLA5AY5FLI; ; + harvestNetworkFeeSinkAddress; NAVORTEX3IPBAUWQBBI3I3BDIOS4AVHPZLCFC7Y; Address; Address of the harvest network fee sink account. maxTransactionsPerBlock; 6'000; uint32_t; Maximum number of transactions per block. - **fork_heights**; ; ; - totalVotingBalanceCalculationFix; 528'000; uint32_t; Height of fork to fix TotalVotingBalance calculation. + treasuryReissuanceBlockTransactionsHash; 1A95DA607D545C7E5103EC8D3411E6E505D5B7567E8F3857CD6AEBAD90D3B07F; ; + treasuryReissuanceFallbackBlockTransactionsHash; E1DFEA3F15CDB974EA621A4A9E60B2EC676802DEAA542FE665D2FA364BB4C13D; ; **plugin:catapult.plugins.accountlink**; dummy; to trigger plugin load **plugin:catapult.plugins.aggregate**; ; ; @@ -675,7 +740,8 @@ config-network.properties maxMosaicsPerAccount; 1'000; uint16_t; Maximum number of mosaics that an account can own. maxMosaicDuration; 3650d; utils::BlockSpan; Maximum mosaic duration. maxMosaicDivisibility; 6; uint8_t; Maximum mosaic divisibility. - mosaicRentalFeeSinkAddress; NC733XE7DF46Q7QYLIIZBBSCJN2BEEP5FQ6PAYA; Address; Address of the mosaic rental fee sink account. + mosaicRentalFeeSinkAddressV1; NC733XE7DF46Q7QYLIIZBBSCJN2BEEP5FQ6PAYA; ; + mosaicRentalFeeSinkAddress; NCVORTEX4XD5IQASZQEHDWUXT33XBOTBMKFDCLI; Address; Address of the mosaic rental fee sink account. mosaicRentalFee; 500000; Amount; Mosaic rental fee. **plugin:catapult.plugins.multisig**; ; ; maxMultisigDepth; 3; uint8_t; Maximum number of multisig levels. @@ -689,7 +755,8 @@ config-network.properties maxNamespaceDuration; 1825d; utils::BlockSpan; Maximum namespace duration. namespaceGracePeriodDuration; 30d; utils::BlockSpan; Grace period during which time only the previous owner can renew an expired namespace. reservedRootNamespaceNames; symbol, symbl, xym, xem, nem, user, account, org, com, biz, net, edu, mil, gov, info; unordered_set; Reserved root namespaces that cannot be claimed. - namespaceRentalFeeSinkAddress; NBDTBUD6R32ZYJWDEWLJM4YMOX3OOILHGDUMTSA; Address; Address of the namespace rental fee sink account. + namespaceRentalFeeSinkAddressV1; NBDTBUD6R32ZYJWDEWLJM4YMOX3OOILHGDUMTSA; ; + namespaceRentalFeeSinkAddress; NCVORTEX4XD5IQASZQEHDWUXT33XBOTBMKFDCLI; Address; Address of the namespace rental fee sink account. rootNamespaceRentalFeePerBlock; 2; Amount; Root namespace rental fee per block. childNamespaceRentalFee; 100000; Amount; Child namespace rental fee. **plugin:catapult.plugins.restrictionaccount**; ; ; @@ -698,6 +765,19 @@ config-network.properties maxMosaicRestrictionValues; 20; uint8_t; Maximum number of mosaic restriction values. **plugin:catapult.plugins.transfer**; ; ; maxMessageSize; 1024; uint16_t; Maximum transaction message size. + **fork_heights**; ; ; + totalVotingBalanceCalculationFix; 528'000; uint32_t; Height of fork to fix TotalVotingBalance calculation. + treasuryReissuance; 689'761; ; + **treasury_reissuance_transaction_signatures**; + 0BBEADD37539444D75C09A245102D2B883267925398504623835DCD625290DEE4FA2371341050C49C001DEDD1C9FE241EA4A7DB335B2069FD4DAFF77AF734C03; true + 89447704270E8B2F8EED19526587DB58870D90A02ACEF8AE2A54311DEB95C227201CD39662A0229D5746FFB84074EA6C7DD9620A2CE5AA69065C508DC0335201; true + D19BCD440545CF785D88F903141DE794F2D57012509BC224B25BFCA220267D1ADD42182702F50C1A4E95D0F21604E4F9EEEEF329932FCD0C76B43992B0D90B0D; true + C478DB6053C639AFC96F5D965159DC95449E5EE69A62E5FA28DF42D85C031B3A131B3AC403D9BFF27E1E64FD8012D05C720F0D2A8654D9F4BC48C8DD2DCEBC03; true + C0BAE301EC15B514C5685A661BC3E23A6596CE9DC412A83F67A8C8611A4415B1B0447E8C09D2816CAE0D750C4AB1ED8FE9C85C05D448C2114147A2C935030708; true + A317F4EB085C8D3D80435669EF54C6C9C9AD9B57165B14CF051F43879D0112E3A79591DD6D469BFAA850891FA2CB601BA58CD1BAEBFF5D84C49179AC7FE14706; true + FDB98C472D0B98FDD766DA177366DEB2DB0E79721BD73DA96A84622A98932DA75BAA327BA9E23D448C6F25344654A6F17F7734C14D1530B327F911A97B4DE30A; true + **treasury_reissuance_fallback_transaction_signatures**; + E29FA2456E505044B2087D4D4FFC390D3E2BDAEF2233E10E812C8677D1DE95DDB5D7A696D8C697DB74D07DC9AB863659EE9C6E984BE83E394AE632D21129EC0F; true config-node.properties ====================== @@ -723,7 +803,7 @@ config-node.properties shortLivedCachePruneInterval; 90s; utils::TimeSpan; Time between short lived cache pruning. shortLivedCacheMaxSize; 10'000'000; uint32_t; Maximum size of a short lived cache. minFeeMultiplier; 100; BlockFeeMultiplier; Minimum fee multiplier of transactions to propagate and include in blocks. - maxTimeBehindPullTransactionsStart; 5m; ; + maxTimeBehindPullTransactionsStart; 24h; ; transactionSelectionStrategy; oldest; model::TransactionSelectionStrategy; Transaction selection strategy used for syncing and harvesting unconfirmed transactions. unconfirmedTransactionsCacheMaxResponseSize; 5MB; utils::FileSize; Maximum size of an unconfirmed transactions response. unconfirmedTransactionsCacheMaxSize; 20MB; uint32_t; Maximum size of the unconfirmed transactions cache. @@ -741,7 +821,7 @@ config-node.properties enableDispatcherAbortWhenFull; false; bool; Set to true if the process should terminate when any dispatcher is full. enableDispatcherInputAuditing; false; bool; Set to true if all dispatcher inputs should be audited. maxTrackedNodes; 5'000; uint32_t; Maximum number of nodes to track in memory. - minPartnerNodeVersion; 1.0.1.0; ; + minPartnerNodeVersion; 1.0.2.0; ; maxPartnerNodeVersion; 1.0.255.255; ; trustedHosts; 127.0.0.1; unordered_set; Trusted hosts that are allowed to execute protected API calls on this node. localNetworks; 127.0.0.1; unordered_set; Networks that should be treated as local. @@ -757,7 +837,7 @@ config-node.properties **localnode**; ; ; host; ; string; Node host (leave empty to auto-detect IP). friendlyName; myFriendlyName; string; Node friendly name (leave empty to use address). - version; 1.0.2.0; uint32_t; Node version. + version; ; uint32_t; Node version. roles; Peer; ionet::NodeRoles; Node roles. **outgoing_connections**; ; ; maxConnections; 10; uint16_t; Maximum number of active connections. diff --git a/test/reports/testnet-api/node-config.csv b/test/reports/testnet-api/node-config.csv index b807d6b10..ff9d12504 100644 --- a/test/reports/testnet-api/node-config.csv +++ b/test/reports/testnet-api/node-config.csv @@ -73,6 +73,9 @@ messageSynchronizationMaxResponseSize; 20MB maxHashesPerPoint; 256 prevoteBlocksMultiple; 4 unfinalizedBlocksDuration; 10m +treasuryReissuanceEpoch; 0 + +treasury_reissuance_epoch_ineligible_voter_addresses config-inflation.properties @@ -570,7 +573,7 @@ listenInterface; 0.0.0.0 config-network.properties network -identifier; public-test; NetworkIdentifier; Network identifier. +identifier; testnet; NetworkIdentifier; Network identifier. nemesisSignerPublicKey; 2267B24107405779DDF0D8FBEABD8142B97105F356F3737B1FC02220E8F90FF2; Key; Nemesis public key. nodeEqualityStrategy; host; NodeIdentityEqualityStrategy; Node equality strategy. generationHashSeed; 3B5E1FA6445653C971A50687E75E6D09FB30481055E3990C84B25E9222DC1155; ; @@ -602,11 +605,11 @@ minVotingKeyLifetime; 28; uint32_t; Minimum number of finalization rounds for wh maxVotingKeyLifetime; 720; uint32_t; Maximum number of finalization rounds for which voting key can be registered. harvestBeneficiaryPercentage; 25; uint8_t; Percentage of the harvested fee that is collected by the beneficiary account. harvestNetworkPercentage; 5; uint8_t; Percentage of the harvested fee that is collected by the network. +harvestNetworkFeeSinkAddressV1; TCZ3UZPWWC5NR6TGGYEJ2MT4Z5ZLR3XTIVI4RHA; ; harvestNetworkFeeSinkAddress; TCZ3UZPWWC5NR6TGGYEJ2MT4Z5ZLR3XTIVI4RHA; Address; Address of the harvest network fee sink account. maxTransactionsPerBlock; 6'000; uint32_t; Maximum number of transactions per block. - -fork_heights -totalVotingBalanceCalculationFix; 398'520; uint32_t; Height of fork to fix TotalVotingBalance calculation. +treasuryReissuanceBlockTransactionsHash; 0000000000000000000000000000000000000000000000000000000000000000; ; +treasuryReissuanceFallbackBlockTransactionsHash; 0000000000000000000000000000000000000000000000000000000000000000; ; plugin:catapult.plugins.accountlink dummy; to trigger plugin load @@ -634,6 +637,7 @@ plugin:catapult.plugins.mosaic maxMosaicsPerAccount; 1'000; uint16_t; Maximum number of mosaics that an account can own. maxMosaicDuration; 3650d; utils::BlockSpan; Maximum mosaic duration. maxMosaicDivisibility; 6; uint8_t; Maximum mosaic divisibility. +mosaicRentalFeeSinkAddressV1; TAFNXW3VXVFTGTVGATKQAR75ALQX7DQXQJRWWTA; ; mosaicRentalFeeSinkAddress; TAFNXW3VXVFTGTVGATKQAR75ALQX7DQXQJRWWTA; Address; Address of the mosaic rental fee sink account. mosaicRentalFee; 500000; Amount; Mosaic rental fee. @@ -650,6 +654,7 @@ minNamespaceDuration; 30d; utils::BlockSpan; Minimum namespace duration. maxNamespaceDuration; 1825d; utils::BlockSpan; Maximum namespace duration. namespaceGracePeriodDuration; 1d; utils::BlockSpan; Grace period during which time only the previous owner can renew an expired namespace. reservedRootNamespaceNames; symbol, symbl, xym, xem, nem, user, account, org, com, biz, net, edu, mil, gov, info; unordered_set; Reserved root namespaces that cannot be claimed. +namespaceRentalFeeSinkAddressV1; TATBDUEWS2X2BKKBPVB7SY4Z626YCAERGA3IF5A; ; namespaceRentalFeeSinkAddress; TATBDUEWS2X2BKKBPVB7SY4Z626YCAERGA3IF5A; Address; Address of the namespace rental fee sink account. rootNamespaceRentalFeePerBlock; 2; Amount; Root namespace rental fee per block. childNamespaceRentalFee; 100000; Amount; Child namespace rental fee. @@ -663,6 +668,14 @@ maxMosaicRestrictionValues; 20; uint8_t; Maximum number of mosaic restriction va plugin:catapult.plugins.transfer maxMessageSize; 1024; uint16_t; Maximum transaction message size. +fork_heights +totalVotingBalanceCalculationFix; 398'520; uint32_t; Height of fork to fix TotalVotingBalance calculation. +treasuryReissuance; 0; ; + +treasury_reissuance_transaction_signatures + +treasury_reissuance_fallback_transaction_signatures + config-node.properties node @@ -683,7 +696,7 @@ shortLivedCacheBlockDuration; 100m; utils::TimeSpan; Duration of a block in the shortLivedCachePruneInterval; 90s; utils::TimeSpan; Time between short lived cache pruning. shortLivedCacheMaxSize; 10'000'000; uint32_t; Maximum size of a short lived cache. minFeeMultiplier; 100; BlockFeeMultiplier; Minimum fee multiplier of transactions to propagate and include in blocks. -maxTimeBehindPullTransactionsStart; 5m; ; +maxTimeBehindPullTransactionsStart; 24h; ; transactionSelectionStrategy; oldest; model::TransactionSelectionStrategy; Transaction selection strategy used for syncing and harvesting unconfirmed transactions. unconfirmedTransactionsCacheMaxResponseSize; 5MB; utils::FileSize; Maximum size of an unconfirmed transactions response. unconfirmedTransactionsCacheMaxSize; 20MB; uint32_t; Maximum size of the unconfirmed transactions cache. @@ -701,7 +714,7 @@ transactionDisruptorMaxMemorySize; 20MB; ; enableDispatcherAbortWhenFull; false; bool; Set to true if the process should terminate when any dispatcher is full. enableDispatcherInputAuditing; false; bool; Set to true if all dispatcher inputs should be audited. maxTrackedNodes; 5'000; uint32_t; Maximum number of nodes to track in memory. -minPartnerNodeVersion; 1.0.1.0; ; +minPartnerNodeVersion; 1.0.2.0; ; maxPartnerNodeVersion; 1.0.255.255; ; trustedHosts; 127.0.0.1, 172.20.0.25; unordered_set; Trusted hosts that are allowed to execute protected API calls on this node. localNetworks; 127.0.0.1, 172.20.0.25; unordered_set; Networks that should be treated as local. @@ -719,7 +732,7 @@ maxWriteBatchSize; 5MB localnode host; ; string; Node host (leave empty to auto-detect IP). friendlyName; myFriendlyName; string; Node friendly name (leave empty to use address). -version; 1.0.2.0; uint32_t; Node version. +version; ; uint32_t; Node version. roles; Api; ionet::NodeRoles; Node roles. outgoing_connections diff --git a/test/reports/testnet-api/node-config.rst b/test/reports/testnet-api/node-config.rst index ad5b04fcd..41e758ce6 100644 --- a/test/reports/testnet-api/node-config.rst +++ b/test/reports/testnet-api/node-config.rst @@ -93,6 +93,8 @@ config-finalization.properties maxHashesPerPoint; 256 prevoteBlocksMultiple; 4 unfinalizedBlocksDuration; 10m + treasuryReissuanceEpoch; 0 + **treasury_reissuance_epoch_ineligible_voter_addresses**; config-inflation.properties =========================== @@ -605,7 +607,7 @@ config-network.properties :delim: ; **network**; ; ; - identifier; public-test; NetworkIdentifier; Network identifier. + identifier; testnet; NetworkIdentifier; Network identifier. nemesisSignerPublicKey; 2267B24107405779DDF0D8FBEABD8142B97105F356F3737B1FC02220E8F90FF2; Key; Nemesis public key. nodeEqualityStrategy; host; NodeIdentityEqualityStrategy; Node equality strategy. generationHashSeed; 3B5E1FA6445653C971A50687E75E6D09FB30481055E3990C84B25E9222DC1155; ; @@ -636,10 +638,11 @@ config-network.properties maxVotingKeyLifetime; 720; uint32_t; Maximum number of finalization rounds for which voting key can be registered. harvestBeneficiaryPercentage; 25; uint8_t; Percentage of the harvested fee that is collected by the beneficiary account. harvestNetworkPercentage; 5; uint8_t; Percentage of the harvested fee that is collected by the network. + harvestNetworkFeeSinkAddressV1; TCZ3UZPWWC5NR6TGGYEJ2MT4Z5ZLR3XTIVI4RHA; ; harvestNetworkFeeSinkAddress; TCZ3UZPWWC5NR6TGGYEJ2MT4Z5ZLR3XTIVI4RHA; Address; Address of the harvest network fee sink account. maxTransactionsPerBlock; 6'000; uint32_t; Maximum number of transactions per block. - **fork_heights**; ; ; - totalVotingBalanceCalculationFix; 398'520; uint32_t; Height of fork to fix TotalVotingBalance calculation. + treasuryReissuanceBlockTransactionsHash; 0000000000000000000000000000000000000000000000000000000000000000; ; + treasuryReissuanceFallbackBlockTransactionsHash; 0000000000000000000000000000000000000000000000000000000000000000; ; **plugin:catapult.plugins.accountlink**; dummy; to trigger plugin load **plugin:catapult.plugins.aggregate**; ; ; @@ -661,6 +664,7 @@ config-network.properties maxMosaicsPerAccount; 1'000; uint16_t; Maximum number of mosaics that an account can own. maxMosaicDuration; 3650d; utils::BlockSpan; Maximum mosaic duration. maxMosaicDivisibility; 6; uint8_t; Maximum mosaic divisibility. + mosaicRentalFeeSinkAddressV1; TAFNXW3VXVFTGTVGATKQAR75ALQX7DQXQJRWWTA; ; mosaicRentalFeeSinkAddress; TAFNXW3VXVFTGTVGATKQAR75ALQX7DQXQJRWWTA; Address; Address of the mosaic rental fee sink account. mosaicRentalFee; 500000; Amount; Mosaic rental fee. **plugin:catapult.plugins.multisig**; ; ; @@ -675,6 +679,7 @@ config-network.properties maxNamespaceDuration; 1825d; utils::BlockSpan; Maximum namespace duration. namespaceGracePeriodDuration; 1d; utils::BlockSpan; Grace period during which time only the previous owner can renew an expired namespace. reservedRootNamespaceNames; symbol, symbl, xym, xem, nem, user, account, org, com, biz, net, edu, mil, gov, info; unordered_set; Reserved root namespaces that cannot be claimed. + namespaceRentalFeeSinkAddressV1; TATBDUEWS2X2BKKBPVB7SY4Z626YCAERGA3IF5A; ; namespaceRentalFeeSinkAddress; TATBDUEWS2X2BKKBPVB7SY4Z626YCAERGA3IF5A; Address; Address of the namespace rental fee sink account. rootNamespaceRentalFeePerBlock; 2; Amount; Root namespace rental fee per block. childNamespaceRentalFee; 100000; Amount; Child namespace rental fee. @@ -684,6 +689,11 @@ config-network.properties maxMosaicRestrictionValues; 20; uint8_t; Maximum number of mosaic restriction values. **plugin:catapult.plugins.transfer**; ; ; maxMessageSize; 1024; uint16_t; Maximum transaction message size. + **fork_heights**; ; ; + totalVotingBalanceCalculationFix; 398'520; uint32_t; Height of fork to fix TotalVotingBalance calculation. + treasuryReissuance; 0; ; + **treasury_reissuance_transaction_signatures**; + **treasury_reissuance_fallback_transaction_signatures**; config-node.properties ====================== @@ -709,7 +719,7 @@ config-node.properties shortLivedCachePruneInterval; 90s; utils::TimeSpan; Time between short lived cache pruning. shortLivedCacheMaxSize; 10'000'000; uint32_t; Maximum size of a short lived cache. minFeeMultiplier; 100; BlockFeeMultiplier; Minimum fee multiplier of transactions to propagate and include in blocks. - maxTimeBehindPullTransactionsStart; 5m; ; + maxTimeBehindPullTransactionsStart; 24h; ; transactionSelectionStrategy; oldest; model::TransactionSelectionStrategy; Transaction selection strategy used for syncing and harvesting unconfirmed transactions. unconfirmedTransactionsCacheMaxResponseSize; 5MB; utils::FileSize; Maximum size of an unconfirmed transactions response. unconfirmedTransactionsCacheMaxSize; 20MB; uint32_t; Maximum size of the unconfirmed transactions cache. @@ -727,7 +737,7 @@ config-node.properties enableDispatcherAbortWhenFull; false; bool; Set to true if the process should terminate when any dispatcher is full. enableDispatcherInputAuditing; false; bool; Set to true if all dispatcher inputs should be audited. maxTrackedNodes; 5'000; uint32_t; Maximum number of nodes to track in memory. - minPartnerNodeVersion; 1.0.1.0; ; + minPartnerNodeVersion; 1.0.2.0; ; maxPartnerNodeVersion; 1.0.255.255; ; trustedHosts; 127.0.0.1, 172.20.0.25; unordered_set; Trusted hosts that are allowed to execute protected API calls on this node. localNetworks; 127.0.0.1, 172.20.0.25; unordered_set; Networks that should be treated as local. @@ -743,7 +753,7 @@ config-node.properties **localnode**; ; ; host; ; string; Node host (leave empty to auto-detect IP). friendlyName; myFriendlyName; string; Node friendly name (leave empty to use address). - version; 1.0.2.0; uint32_t; Node version. + version; ; uint32_t; Node version. roles; Api; ionet::NodeRoles; Node roles. **outgoing_connections**; ; ; maxConnections; 10; uint16_t; Maximum number of active connections. diff --git a/test/reports/testnet-api/rest-gateway-rest.json b/test/reports/testnet-api/rest-gateway-rest.json index d01383936..0a2dc6013 100644 --- a/test/reports/testnet-api/rest-gateway-rest.json +++ b/test/reports/testnet-api/rest-gateway-rest.json @@ -1,9 +1,12 @@ { "network": { - "name": "publicTest", + "name": "testnet", "description": "catapult public test network" }, "port": 3000, + "protocol": "HTTP", + "sslKeyPath": "/symbol-workdir/restSSL.key", + "sslCertificatePath": "/symbol-workdir/restSSL.crt", "crossDomain": { "allowedHosts": [ "*" diff --git a/test/reports/testnet-dual-voting/node-config.csv b/test/reports/testnet-dual-voting/node-config.csv index 1284b4d5e..bbeaa587b 100644 --- a/test/reports/testnet-dual-voting/node-config.csv +++ b/test/reports/testnet-dual-voting/node-config.csv @@ -73,6 +73,9 @@ messageSynchronizationMaxResponseSize; 20MB maxHashesPerPoint; 256 prevoteBlocksMultiple; 4 unfinalizedBlocksDuration; 0m +treasuryReissuanceEpoch; 0 + +treasury_reissuance_epoch_ineligible_voter_addresses config-harvesting.properties @@ -580,7 +583,7 @@ listenInterface; 0.0.0.0 config-network.properties network -identifier; public-test; NetworkIdentifier; Network identifier. +identifier; testnet; NetworkIdentifier; Network identifier. nemesisSignerPublicKey; 2267B24107405779DDF0D8FBEABD8142B97105F356F3737B1FC02220E8F90FF2; Key; Nemesis public key. nodeEqualityStrategy; host; NodeIdentityEqualityStrategy; Node equality strategy. generationHashSeed; 3B5E1FA6445653C971A50687E75E6D09FB30481055E3990C84B25E9222DC1155; ; @@ -612,11 +615,11 @@ minVotingKeyLifetime; 28; uint32_t; Minimum number of finalization rounds for wh maxVotingKeyLifetime; 720; uint32_t; Maximum number of finalization rounds for which voting key can be registered. harvestBeneficiaryPercentage; 25; uint8_t; Percentage of the harvested fee that is collected by the beneficiary account. harvestNetworkPercentage; 5; uint8_t; Percentage of the harvested fee that is collected by the network. +harvestNetworkFeeSinkAddressV1; TCZ3UZPWWC5NR6TGGYEJ2MT4Z5ZLR3XTIVI4RHA; ; harvestNetworkFeeSinkAddress; TCZ3UZPWWC5NR6TGGYEJ2MT4Z5ZLR3XTIVI4RHA; Address; Address of the harvest network fee sink account. maxTransactionsPerBlock; 6'000; uint32_t; Maximum number of transactions per block. - -fork_heights -totalVotingBalanceCalculationFix; 398'520; uint32_t; Height of fork to fix TotalVotingBalance calculation. +treasuryReissuanceBlockTransactionsHash; 0000000000000000000000000000000000000000000000000000000000000000; ; +treasuryReissuanceFallbackBlockTransactionsHash; 0000000000000000000000000000000000000000000000000000000000000000; ; plugin:catapult.plugins.accountlink dummy; to trigger plugin load @@ -644,6 +647,7 @@ plugin:catapult.plugins.mosaic maxMosaicsPerAccount; 1'000; uint16_t; Maximum number of mosaics that an account can own. maxMosaicDuration; 3650d; utils::BlockSpan; Maximum mosaic duration. maxMosaicDivisibility; 6; uint8_t; Maximum mosaic divisibility. +mosaicRentalFeeSinkAddressV1; TAFNXW3VXVFTGTVGATKQAR75ALQX7DQXQJRWWTA; ; mosaicRentalFeeSinkAddress; TAFNXW3VXVFTGTVGATKQAR75ALQX7DQXQJRWWTA; Address; Address of the mosaic rental fee sink account. mosaicRentalFee; 500000; Amount; Mosaic rental fee. @@ -660,6 +664,7 @@ minNamespaceDuration; 30d; utils::BlockSpan; Minimum namespace duration. maxNamespaceDuration; 1825d; utils::BlockSpan; Maximum namespace duration. namespaceGracePeriodDuration; 1d; utils::BlockSpan; Grace period during which time only the previous owner can renew an expired namespace. reservedRootNamespaceNames; symbol, symbl, xym, xem, nem, user, account, org, com, biz, net, edu, mil, gov, info; unordered_set; Reserved root namespaces that cannot be claimed. +namespaceRentalFeeSinkAddressV1; TATBDUEWS2X2BKKBPVB7SY4Z626YCAERGA3IF5A; ; namespaceRentalFeeSinkAddress; TATBDUEWS2X2BKKBPVB7SY4Z626YCAERGA3IF5A; Address; Address of the namespace rental fee sink account. rootNamespaceRentalFeePerBlock; 2; Amount; Root namespace rental fee per block. childNamespaceRentalFee; 100000; Amount; Child namespace rental fee. @@ -673,6 +678,14 @@ maxMosaicRestrictionValues; 20; uint8_t; Maximum number of mosaic restriction va plugin:catapult.plugins.transfer maxMessageSize; 1024; uint16_t; Maximum transaction message size. +fork_heights +totalVotingBalanceCalculationFix; 398'520; uint32_t; Height of fork to fix TotalVotingBalance calculation. +treasuryReissuance; 0; ; + +treasury_reissuance_transaction_signatures + +treasury_reissuance_fallback_transaction_signatures + config-node.properties node @@ -693,7 +706,7 @@ shortLivedCacheBlockDuration; 100m; utils::TimeSpan; Duration of a block in the shortLivedCachePruneInterval; 90s; utils::TimeSpan; Time between short lived cache pruning. shortLivedCacheMaxSize; 10'000'000; uint32_t; Maximum size of a short lived cache. minFeeMultiplier; 100; BlockFeeMultiplier; Minimum fee multiplier of transactions to propagate and include in blocks. -maxTimeBehindPullTransactionsStart; 5m; ; +maxTimeBehindPullTransactionsStart; 24h; ; transactionSelectionStrategy; oldest; model::TransactionSelectionStrategy; Transaction selection strategy used for syncing and harvesting unconfirmed transactions. unconfirmedTransactionsCacheMaxResponseSize; 5MB; utils::FileSize; Maximum size of an unconfirmed transactions response. unconfirmedTransactionsCacheMaxSize; 20MB; uint32_t; Maximum size of the unconfirmed transactions cache. @@ -711,7 +724,7 @@ transactionDisruptorMaxMemorySize; 20MB; ; enableDispatcherAbortWhenFull; false; bool; Set to true if the process should terminate when any dispatcher is full. enableDispatcherInputAuditing; false; bool; Set to true if all dispatcher inputs should be audited. maxTrackedNodes; 5'000; uint32_t; Maximum number of nodes to track in memory. -minPartnerNodeVersion; 1.0.1.0; ; +minPartnerNodeVersion; 1.0.2.0; ; maxPartnerNodeVersion; 1.0.255.255; ; trustedHosts; 127.0.0.1, 172.20.0.25; unordered_set; Trusted hosts that are allowed to execute protected API calls on this node. localNetworks; 127.0.0.1, 172.20.0.25; unordered_set; Networks that should be treated as local. @@ -729,7 +742,7 @@ maxWriteBatchSize; 5MB localnode host; ; string; Node host (leave empty to auto-detect IP). friendlyName; myFriendlyName; string; Node friendly name (leave empty to use address). -version; 1.0.2.0; uint32_t; Node version. +version; ; uint32_t; Node version. roles; Peer,Api,Voting; ionet::NodeRoles; Node roles. outgoing_connections diff --git a/test/reports/testnet-dual-voting/node-config.rst b/test/reports/testnet-dual-voting/node-config.rst index ea144f8fd..d7879eb2e 100644 --- a/test/reports/testnet-dual-voting/node-config.rst +++ b/test/reports/testnet-dual-voting/node-config.rst @@ -93,6 +93,8 @@ config-finalization.properties maxHashesPerPoint; 256 prevoteBlocksMultiple; 4 unfinalizedBlocksDuration; 0m + treasuryReissuanceEpoch; 0 + **treasury_reissuance_epoch_ineligible_voter_addresses**; config-harvesting.properties ============================ @@ -619,7 +621,7 @@ config-network.properties :delim: ; **network**; ; ; - identifier; public-test; NetworkIdentifier; Network identifier. + identifier; testnet; NetworkIdentifier; Network identifier. nemesisSignerPublicKey; 2267B24107405779DDF0D8FBEABD8142B97105F356F3737B1FC02220E8F90FF2; Key; Nemesis public key. nodeEqualityStrategy; host; NodeIdentityEqualityStrategy; Node equality strategy. generationHashSeed; 3B5E1FA6445653C971A50687E75E6D09FB30481055E3990C84B25E9222DC1155; ; @@ -650,10 +652,11 @@ config-network.properties maxVotingKeyLifetime; 720; uint32_t; Maximum number of finalization rounds for which voting key can be registered. harvestBeneficiaryPercentage; 25; uint8_t; Percentage of the harvested fee that is collected by the beneficiary account. harvestNetworkPercentage; 5; uint8_t; Percentage of the harvested fee that is collected by the network. + harvestNetworkFeeSinkAddressV1; TCZ3UZPWWC5NR6TGGYEJ2MT4Z5ZLR3XTIVI4RHA; ; harvestNetworkFeeSinkAddress; TCZ3UZPWWC5NR6TGGYEJ2MT4Z5ZLR3XTIVI4RHA; Address; Address of the harvest network fee sink account. maxTransactionsPerBlock; 6'000; uint32_t; Maximum number of transactions per block. - **fork_heights**; ; ; - totalVotingBalanceCalculationFix; 398'520; uint32_t; Height of fork to fix TotalVotingBalance calculation. + treasuryReissuanceBlockTransactionsHash; 0000000000000000000000000000000000000000000000000000000000000000; ; + treasuryReissuanceFallbackBlockTransactionsHash; 0000000000000000000000000000000000000000000000000000000000000000; ; **plugin:catapult.plugins.accountlink**; dummy; to trigger plugin load **plugin:catapult.plugins.aggregate**; ; ; @@ -675,6 +678,7 @@ config-network.properties maxMosaicsPerAccount; 1'000; uint16_t; Maximum number of mosaics that an account can own. maxMosaicDuration; 3650d; utils::BlockSpan; Maximum mosaic duration. maxMosaicDivisibility; 6; uint8_t; Maximum mosaic divisibility. + mosaicRentalFeeSinkAddressV1; TAFNXW3VXVFTGTVGATKQAR75ALQX7DQXQJRWWTA; ; mosaicRentalFeeSinkAddress; TAFNXW3VXVFTGTVGATKQAR75ALQX7DQXQJRWWTA; Address; Address of the mosaic rental fee sink account. mosaicRentalFee; 500000; Amount; Mosaic rental fee. **plugin:catapult.plugins.multisig**; ; ; @@ -689,6 +693,7 @@ config-network.properties maxNamespaceDuration; 1825d; utils::BlockSpan; Maximum namespace duration. namespaceGracePeriodDuration; 1d; utils::BlockSpan; Grace period during which time only the previous owner can renew an expired namespace. reservedRootNamespaceNames; symbol, symbl, xym, xem, nem, user, account, org, com, biz, net, edu, mil, gov, info; unordered_set; Reserved root namespaces that cannot be claimed. + namespaceRentalFeeSinkAddressV1; TATBDUEWS2X2BKKBPVB7SY4Z626YCAERGA3IF5A; ; namespaceRentalFeeSinkAddress; TATBDUEWS2X2BKKBPVB7SY4Z626YCAERGA3IF5A; Address; Address of the namespace rental fee sink account. rootNamespaceRentalFeePerBlock; 2; Amount; Root namespace rental fee per block. childNamespaceRentalFee; 100000; Amount; Child namespace rental fee. @@ -698,6 +703,11 @@ config-network.properties maxMosaicRestrictionValues; 20; uint8_t; Maximum number of mosaic restriction values. **plugin:catapult.plugins.transfer**; ; ; maxMessageSize; 1024; uint16_t; Maximum transaction message size. + **fork_heights**; ; ; + totalVotingBalanceCalculationFix; 398'520; uint32_t; Height of fork to fix TotalVotingBalance calculation. + treasuryReissuance; 0; ; + **treasury_reissuance_transaction_signatures**; + **treasury_reissuance_fallback_transaction_signatures**; config-node.properties ====================== @@ -723,7 +733,7 @@ config-node.properties shortLivedCachePruneInterval; 90s; utils::TimeSpan; Time between short lived cache pruning. shortLivedCacheMaxSize; 10'000'000; uint32_t; Maximum size of a short lived cache. minFeeMultiplier; 100; BlockFeeMultiplier; Minimum fee multiplier of transactions to propagate and include in blocks. - maxTimeBehindPullTransactionsStart; 5m; ; + maxTimeBehindPullTransactionsStart; 24h; ; transactionSelectionStrategy; oldest; model::TransactionSelectionStrategy; Transaction selection strategy used for syncing and harvesting unconfirmed transactions. unconfirmedTransactionsCacheMaxResponseSize; 5MB; utils::FileSize; Maximum size of an unconfirmed transactions response. unconfirmedTransactionsCacheMaxSize; 20MB; uint32_t; Maximum size of the unconfirmed transactions cache. @@ -741,7 +751,7 @@ config-node.properties enableDispatcherAbortWhenFull; false; bool; Set to true if the process should terminate when any dispatcher is full. enableDispatcherInputAuditing; false; bool; Set to true if all dispatcher inputs should be audited. maxTrackedNodes; 5'000; uint32_t; Maximum number of nodes to track in memory. - minPartnerNodeVersion; 1.0.1.0; ; + minPartnerNodeVersion; 1.0.2.0; ; maxPartnerNodeVersion; 1.0.255.255; ; trustedHosts; 127.0.0.1, 172.20.0.25; unordered_set; Trusted hosts that are allowed to execute protected API calls on this node. localNetworks; 127.0.0.1, 172.20.0.25; unordered_set; Networks that should be treated as local. @@ -757,7 +767,7 @@ config-node.properties **localnode**; ; ; host; ; string; Node host (leave empty to auto-detect IP). friendlyName; myFriendlyName; string; Node friendly name (leave empty to use address). - version; 1.0.2.0; uint32_t; Node version. + version; ; uint32_t; Node version. roles; Peer,Api,Voting; ionet::NodeRoles; Node roles. **outgoing_connections**; ; ; maxConnections; 10; uint16_t; Maximum number of active connections. diff --git a/test/reports/testnet-dual-voting/rest-gateway-rest.json b/test/reports/testnet-dual-voting/rest-gateway-rest.json index 8cbda7298..d725552c7 100644 --- a/test/reports/testnet-dual-voting/rest-gateway-rest.json +++ b/test/reports/testnet-dual-voting/rest-gateway-rest.json @@ -1,9 +1,12 @@ { "network": { - "name": "publicTest", + "name": "testnet", "description": "catapult public test network" }, "port": 3000, + "protocol": "HTTP", + "sslKeyPath": "/symbol-workdir/restSSL.key", + "sslCertificatePath": "/symbol-workdir/restSSL.crt", "crossDomain": { "allowedHosts": [ "*" diff --git a/test/reports/testnet-peer-non-harvesting-voting/node-config.csv b/test/reports/testnet-peer-non-harvesting-voting/node-config.csv index 993d382b5..5215b0319 100644 --- a/test/reports/testnet-peer-non-harvesting-voting/node-config.csv +++ b/test/reports/testnet-peer-non-harvesting-voting/node-config.csv @@ -73,6 +73,9 @@ messageSynchronizationMaxResponseSize; 20MB maxHashesPerPoint; 256 prevoteBlocksMultiple; 4 unfinalizedBlocksDuration; 0m +treasuryReissuanceEpoch; 0 + +treasury_reissuance_epoch_ineligible_voter_addresses config-inflation.properties @@ -570,7 +573,7 @@ listenInterface; 0.0.0.0 config-network.properties network -identifier; public-test; NetworkIdentifier; Network identifier. +identifier; testnet; NetworkIdentifier; Network identifier. nemesisSignerPublicKey; 2267B24107405779DDF0D8FBEABD8142B97105F356F3737B1FC02220E8F90FF2; Key; Nemesis public key. nodeEqualityStrategy; host; NodeIdentityEqualityStrategy; Node equality strategy. generationHashSeed; 3B5E1FA6445653C971A50687E75E6D09FB30481055E3990C84B25E9222DC1155; ; @@ -602,11 +605,11 @@ minVotingKeyLifetime; 28; uint32_t; Minimum number of finalization rounds for wh maxVotingKeyLifetime; 720; uint32_t; Maximum number of finalization rounds for which voting key can be registered. harvestBeneficiaryPercentage; 25; uint8_t; Percentage of the harvested fee that is collected by the beneficiary account. harvestNetworkPercentage; 5; uint8_t; Percentage of the harvested fee that is collected by the network. +harvestNetworkFeeSinkAddressV1; TCZ3UZPWWC5NR6TGGYEJ2MT4Z5ZLR3XTIVI4RHA; ; harvestNetworkFeeSinkAddress; TCZ3UZPWWC5NR6TGGYEJ2MT4Z5ZLR3XTIVI4RHA; Address; Address of the harvest network fee sink account. maxTransactionsPerBlock; 6'000; uint32_t; Maximum number of transactions per block. - -fork_heights -totalVotingBalanceCalculationFix; 398'520; uint32_t; Height of fork to fix TotalVotingBalance calculation. +treasuryReissuanceBlockTransactionsHash; 0000000000000000000000000000000000000000000000000000000000000000; ; +treasuryReissuanceFallbackBlockTransactionsHash; 0000000000000000000000000000000000000000000000000000000000000000; ; plugin:catapult.plugins.accountlink dummy; to trigger plugin load @@ -634,6 +637,7 @@ plugin:catapult.plugins.mosaic maxMosaicsPerAccount; 1'000; uint16_t; Maximum number of mosaics that an account can own. maxMosaicDuration; 3650d; utils::BlockSpan; Maximum mosaic duration. maxMosaicDivisibility; 6; uint8_t; Maximum mosaic divisibility. +mosaicRentalFeeSinkAddressV1; TAFNXW3VXVFTGTVGATKQAR75ALQX7DQXQJRWWTA; ; mosaicRentalFeeSinkAddress; TAFNXW3VXVFTGTVGATKQAR75ALQX7DQXQJRWWTA; Address; Address of the mosaic rental fee sink account. mosaicRentalFee; 500000; Amount; Mosaic rental fee. @@ -650,6 +654,7 @@ minNamespaceDuration; 30d; utils::BlockSpan; Minimum namespace duration. maxNamespaceDuration; 1825d; utils::BlockSpan; Maximum namespace duration. namespaceGracePeriodDuration; 1d; utils::BlockSpan; Grace period during which time only the previous owner can renew an expired namespace. reservedRootNamespaceNames; symbol, symbl, xym, xem, nem, user, account, org, com, biz, net, edu, mil, gov, info; unordered_set; Reserved root namespaces that cannot be claimed. +namespaceRentalFeeSinkAddressV1; TATBDUEWS2X2BKKBPVB7SY4Z626YCAERGA3IF5A; ; namespaceRentalFeeSinkAddress; TATBDUEWS2X2BKKBPVB7SY4Z626YCAERGA3IF5A; Address; Address of the namespace rental fee sink account. rootNamespaceRentalFeePerBlock; 2; Amount; Root namespace rental fee per block. childNamespaceRentalFee; 100000; Amount; Child namespace rental fee. @@ -663,6 +668,14 @@ maxMosaicRestrictionValues; 20; uint8_t; Maximum number of mosaic restriction va plugin:catapult.plugins.transfer maxMessageSize; 1024; uint16_t; Maximum transaction message size. +fork_heights +totalVotingBalanceCalculationFix; 398'520; uint32_t; Height of fork to fix TotalVotingBalance calculation. +treasuryReissuance; 0; ; + +treasury_reissuance_transaction_signatures + +treasury_reissuance_fallback_transaction_signatures + config-node.properties node @@ -683,7 +696,7 @@ shortLivedCacheBlockDuration; 100m; utils::TimeSpan; Duration of a block in the shortLivedCachePruneInterval; 90s; utils::TimeSpan; Time between short lived cache pruning. shortLivedCacheMaxSize; 10'000'000; uint32_t; Maximum size of a short lived cache. minFeeMultiplier; 100; BlockFeeMultiplier; Minimum fee multiplier of transactions to propagate and include in blocks. -maxTimeBehindPullTransactionsStart; 5m; ; +maxTimeBehindPullTransactionsStart; 24h; ; transactionSelectionStrategy; oldest; model::TransactionSelectionStrategy; Transaction selection strategy used for syncing and harvesting unconfirmed transactions. unconfirmedTransactionsCacheMaxResponseSize; 5MB; utils::FileSize; Maximum size of an unconfirmed transactions response. unconfirmedTransactionsCacheMaxSize; 20MB; uint32_t; Maximum size of the unconfirmed transactions cache. @@ -701,7 +714,7 @@ transactionDisruptorMaxMemorySize; 20MB; ; enableDispatcherAbortWhenFull; false; bool; Set to true if the process should terminate when any dispatcher is full. enableDispatcherInputAuditing; false; bool; Set to true if all dispatcher inputs should be audited. maxTrackedNodes; 5'000; uint32_t; Maximum number of nodes to track in memory. -minPartnerNodeVersion; 1.0.1.0; ; +minPartnerNodeVersion; 1.0.2.0; ; maxPartnerNodeVersion; 1.0.255.255; ; trustedHosts; 127.0.0.1; unordered_set; Trusted hosts that are allowed to execute protected API calls on this node. localNetworks; 127.0.0.1; unordered_set; Networks that should be treated as local. @@ -719,7 +732,7 @@ maxWriteBatchSize; 5MB localnode host; ; string; Node host (leave empty to auto-detect IP). friendlyName; myFriendlyName; string; Node friendly name (leave empty to use address). -version; 1.0.2.0; uint32_t; Node version. +version; ; uint32_t; Node version. roles; Peer,Voting; ionet::NodeRoles; Node roles. outgoing_connections diff --git a/test/reports/testnet-peer-non-harvesting-voting/node-config.rst b/test/reports/testnet-peer-non-harvesting-voting/node-config.rst index 33a100ca1..2940cb12f 100644 --- a/test/reports/testnet-peer-non-harvesting-voting/node-config.rst +++ b/test/reports/testnet-peer-non-harvesting-voting/node-config.rst @@ -93,6 +93,8 @@ config-finalization.properties maxHashesPerPoint; 256 prevoteBlocksMultiple; 4 unfinalizedBlocksDuration; 0m + treasuryReissuanceEpoch; 0 + **treasury_reissuance_epoch_ineligible_voter_addresses**; config-inflation.properties =========================== @@ -605,7 +607,7 @@ config-network.properties :delim: ; **network**; ; ; - identifier; public-test; NetworkIdentifier; Network identifier. + identifier; testnet; NetworkIdentifier; Network identifier. nemesisSignerPublicKey; 2267B24107405779DDF0D8FBEABD8142B97105F356F3737B1FC02220E8F90FF2; Key; Nemesis public key. nodeEqualityStrategy; host; NodeIdentityEqualityStrategy; Node equality strategy. generationHashSeed; 3B5E1FA6445653C971A50687E75E6D09FB30481055E3990C84B25E9222DC1155; ; @@ -636,10 +638,11 @@ config-network.properties maxVotingKeyLifetime; 720; uint32_t; Maximum number of finalization rounds for which voting key can be registered. harvestBeneficiaryPercentage; 25; uint8_t; Percentage of the harvested fee that is collected by the beneficiary account. harvestNetworkPercentage; 5; uint8_t; Percentage of the harvested fee that is collected by the network. + harvestNetworkFeeSinkAddressV1; TCZ3UZPWWC5NR6TGGYEJ2MT4Z5ZLR3XTIVI4RHA; ; harvestNetworkFeeSinkAddress; TCZ3UZPWWC5NR6TGGYEJ2MT4Z5ZLR3XTIVI4RHA; Address; Address of the harvest network fee sink account. maxTransactionsPerBlock; 6'000; uint32_t; Maximum number of transactions per block. - **fork_heights**; ; ; - totalVotingBalanceCalculationFix; 398'520; uint32_t; Height of fork to fix TotalVotingBalance calculation. + treasuryReissuanceBlockTransactionsHash; 0000000000000000000000000000000000000000000000000000000000000000; ; + treasuryReissuanceFallbackBlockTransactionsHash; 0000000000000000000000000000000000000000000000000000000000000000; ; **plugin:catapult.plugins.accountlink**; dummy; to trigger plugin load **plugin:catapult.plugins.aggregate**; ; ; @@ -661,6 +664,7 @@ config-network.properties maxMosaicsPerAccount; 1'000; uint16_t; Maximum number of mosaics that an account can own. maxMosaicDuration; 3650d; utils::BlockSpan; Maximum mosaic duration. maxMosaicDivisibility; 6; uint8_t; Maximum mosaic divisibility. + mosaicRentalFeeSinkAddressV1; TAFNXW3VXVFTGTVGATKQAR75ALQX7DQXQJRWWTA; ; mosaicRentalFeeSinkAddress; TAFNXW3VXVFTGTVGATKQAR75ALQX7DQXQJRWWTA; Address; Address of the mosaic rental fee sink account. mosaicRentalFee; 500000; Amount; Mosaic rental fee. **plugin:catapult.plugins.multisig**; ; ; @@ -675,6 +679,7 @@ config-network.properties maxNamespaceDuration; 1825d; utils::BlockSpan; Maximum namespace duration. namespaceGracePeriodDuration; 1d; utils::BlockSpan; Grace period during which time only the previous owner can renew an expired namespace. reservedRootNamespaceNames; symbol, symbl, xym, xem, nem, user, account, org, com, biz, net, edu, mil, gov, info; unordered_set; Reserved root namespaces that cannot be claimed. + namespaceRentalFeeSinkAddressV1; TATBDUEWS2X2BKKBPVB7SY4Z626YCAERGA3IF5A; ; namespaceRentalFeeSinkAddress; TATBDUEWS2X2BKKBPVB7SY4Z626YCAERGA3IF5A; Address; Address of the namespace rental fee sink account. rootNamespaceRentalFeePerBlock; 2; Amount; Root namespace rental fee per block. childNamespaceRentalFee; 100000; Amount; Child namespace rental fee. @@ -684,6 +689,11 @@ config-network.properties maxMosaicRestrictionValues; 20; uint8_t; Maximum number of mosaic restriction values. **plugin:catapult.plugins.transfer**; ; ; maxMessageSize; 1024; uint16_t; Maximum transaction message size. + **fork_heights**; ; ; + totalVotingBalanceCalculationFix; 398'520; uint32_t; Height of fork to fix TotalVotingBalance calculation. + treasuryReissuance; 0; ; + **treasury_reissuance_transaction_signatures**; + **treasury_reissuance_fallback_transaction_signatures**; config-node.properties ====================== @@ -709,7 +719,7 @@ config-node.properties shortLivedCachePruneInterval; 90s; utils::TimeSpan; Time between short lived cache pruning. shortLivedCacheMaxSize; 10'000'000; uint32_t; Maximum size of a short lived cache. minFeeMultiplier; 100; BlockFeeMultiplier; Minimum fee multiplier of transactions to propagate and include in blocks. - maxTimeBehindPullTransactionsStart; 5m; ; + maxTimeBehindPullTransactionsStart; 24h; ; transactionSelectionStrategy; oldest; model::TransactionSelectionStrategy; Transaction selection strategy used for syncing and harvesting unconfirmed transactions. unconfirmedTransactionsCacheMaxResponseSize; 5MB; utils::FileSize; Maximum size of an unconfirmed transactions response. unconfirmedTransactionsCacheMaxSize; 20MB; uint32_t; Maximum size of the unconfirmed transactions cache. @@ -727,7 +737,7 @@ config-node.properties enableDispatcherAbortWhenFull; false; bool; Set to true if the process should terminate when any dispatcher is full. enableDispatcherInputAuditing; false; bool; Set to true if all dispatcher inputs should be audited. maxTrackedNodes; 5'000; uint32_t; Maximum number of nodes to track in memory. - minPartnerNodeVersion; 1.0.1.0; ; + minPartnerNodeVersion; 1.0.2.0; ; maxPartnerNodeVersion; 1.0.255.255; ; trustedHosts; 127.0.0.1; unordered_set; Trusted hosts that are allowed to execute protected API calls on this node. localNetworks; 127.0.0.1; unordered_set; Networks that should be treated as local. @@ -743,7 +753,7 @@ config-node.properties **localnode**; ; ; host; ; string; Node host (leave empty to auto-detect IP). friendlyName; myFriendlyName; string; Node friendly name (leave empty to use address). - version; 1.0.2.0; uint32_t; Node version. + version; ; uint32_t; Node version. roles; Peer,Voting; ionet::NodeRoles; Node roles. **outgoing_connections**; ; ; maxConnections; 10; uint16_t; Maximum number of active connections. diff --git a/test/reports/testnet-peer-voting/node-config.csv b/test/reports/testnet-peer-voting/node-config.csv index 19e2bbdc0..b0cc5268d 100644 --- a/test/reports/testnet-peer-voting/node-config.csv +++ b/test/reports/testnet-peer-voting/node-config.csv @@ -73,6 +73,9 @@ messageSynchronizationMaxResponseSize; 20MB maxHashesPerPoint; 256 prevoteBlocksMultiple; 4 unfinalizedBlocksDuration; 0m +treasuryReissuanceEpoch; 0 + +treasury_reissuance_epoch_ineligible_voter_addresses config-harvesting.properties @@ -580,7 +583,7 @@ listenInterface; 0.0.0.0 config-network.properties network -identifier; public-test; NetworkIdentifier; Network identifier. +identifier; testnet; NetworkIdentifier; Network identifier. nemesisSignerPublicKey; 2267B24107405779DDF0D8FBEABD8142B97105F356F3737B1FC02220E8F90FF2; Key; Nemesis public key. nodeEqualityStrategy; host; NodeIdentityEqualityStrategy; Node equality strategy. generationHashSeed; 3B5E1FA6445653C971A50687E75E6D09FB30481055E3990C84B25E9222DC1155; ; @@ -612,11 +615,11 @@ minVotingKeyLifetime; 28; uint32_t; Minimum number of finalization rounds for wh maxVotingKeyLifetime; 720; uint32_t; Maximum number of finalization rounds for which voting key can be registered. harvestBeneficiaryPercentage; 25; uint8_t; Percentage of the harvested fee that is collected by the beneficiary account. harvestNetworkPercentage; 5; uint8_t; Percentage of the harvested fee that is collected by the network. +harvestNetworkFeeSinkAddressV1; TCZ3UZPWWC5NR6TGGYEJ2MT4Z5ZLR3XTIVI4RHA; ; harvestNetworkFeeSinkAddress; TCZ3UZPWWC5NR6TGGYEJ2MT4Z5ZLR3XTIVI4RHA; Address; Address of the harvest network fee sink account. maxTransactionsPerBlock; 6'000; uint32_t; Maximum number of transactions per block. - -fork_heights -totalVotingBalanceCalculationFix; 398'520; uint32_t; Height of fork to fix TotalVotingBalance calculation. +treasuryReissuanceBlockTransactionsHash; 0000000000000000000000000000000000000000000000000000000000000000; ; +treasuryReissuanceFallbackBlockTransactionsHash; 0000000000000000000000000000000000000000000000000000000000000000; ; plugin:catapult.plugins.accountlink dummy; to trigger plugin load @@ -644,6 +647,7 @@ plugin:catapult.plugins.mosaic maxMosaicsPerAccount; 1'000; uint16_t; Maximum number of mosaics that an account can own. maxMosaicDuration; 3650d; utils::BlockSpan; Maximum mosaic duration. maxMosaicDivisibility; 6; uint8_t; Maximum mosaic divisibility. +mosaicRentalFeeSinkAddressV1; TAFNXW3VXVFTGTVGATKQAR75ALQX7DQXQJRWWTA; ; mosaicRentalFeeSinkAddress; TAFNXW3VXVFTGTVGATKQAR75ALQX7DQXQJRWWTA; Address; Address of the mosaic rental fee sink account. mosaicRentalFee; 500000; Amount; Mosaic rental fee. @@ -660,6 +664,7 @@ minNamespaceDuration; 30d; utils::BlockSpan; Minimum namespace duration. maxNamespaceDuration; 1825d; utils::BlockSpan; Maximum namespace duration. namespaceGracePeriodDuration; 1d; utils::BlockSpan; Grace period during which time only the previous owner can renew an expired namespace. reservedRootNamespaceNames; symbol, symbl, xym, xem, nem, user, account, org, com, biz, net, edu, mil, gov, info; unordered_set; Reserved root namespaces that cannot be claimed. +namespaceRentalFeeSinkAddressV1; TATBDUEWS2X2BKKBPVB7SY4Z626YCAERGA3IF5A; ; namespaceRentalFeeSinkAddress; TATBDUEWS2X2BKKBPVB7SY4Z626YCAERGA3IF5A; Address; Address of the namespace rental fee sink account. rootNamespaceRentalFeePerBlock; 2; Amount; Root namespace rental fee per block. childNamespaceRentalFee; 100000; Amount; Child namespace rental fee. @@ -673,6 +678,14 @@ maxMosaicRestrictionValues; 20; uint8_t; Maximum number of mosaic restriction va plugin:catapult.plugins.transfer maxMessageSize; 1024; uint16_t; Maximum transaction message size. +fork_heights +totalVotingBalanceCalculationFix; 398'520; uint32_t; Height of fork to fix TotalVotingBalance calculation. +treasuryReissuance; 0; ; + +treasury_reissuance_transaction_signatures + +treasury_reissuance_fallback_transaction_signatures + config-node.properties node @@ -693,7 +706,7 @@ shortLivedCacheBlockDuration; 100m; utils::TimeSpan; Duration of a block in the shortLivedCachePruneInterval; 90s; utils::TimeSpan; Time between short lived cache pruning. shortLivedCacheMaxSize; 10'000'000; uint32_t; Maximum size of a short lived cache. minFeeMultiplier; 100; BlockFeeMultiplier; Minimum fee multiplier of transactions to propagate and include in blocks. -maxTimeBehindPullTransactionsStart; 5m; ; +maxTimeBehindPullTransactionsStart; 24h; ; transactionSelectionStrategy; oldest; model::TransactionSelectionStrategy; Transaction selection strategy used for syncing and harvesting unconfirmed transactions. unconfirmedTransactionsCacheMaxResponseSize; 5MB; utils::FileSize; Maximum size of an unconfirmed transactions response. unconfirmedTransactionsCacheMaxSize; 20MB; uint32_t; Maximum size of the unconfirmed transactions cache. @@ -711,7 +724,7 @@ transactionDisruptorMaxMemorySize; 20MB; ; enableDispatcherAbortWhenFull; false; bool; Set to true if the process should terminate when any dispatcher is full. enableDispatcherInputAuditing; false; bool; Set to true if all dispatcher inputs should be audited. maxTrackedNodes; 5'000; uint32_t; Maximum number of nodes to track in memory. -minPartnerNodeVersion; 1.0.1.0; ; +minPartnerNodeVersion; 1.0.2.0; ; maxPartnerNodeVersion; 1.0.255.255; ; trustedHosts; 127.0.0.1; unordered_set; Trusted hosts that are allowed to execute protected API calls on this node. localNetworks; 127.0.0.1; unordered_set; Networks that should be treated as local. @@ -729,7 +742,7 @@ maxWriteBatchSize; 5MB localnode host; ; string; Node host (leave empty to auto-detect IP). friendlyName; myFriendlyName; string; Node friendly name (leave empty to use address). -version; 1.0.2.0; uint32_t; Node version. +version; ; uint32_t; Node version. roles; Peer,Voting; ionet::NodeRoles; Node roles. outgoing_connections diff --git a/test/reports/testnet-peer-voting/node-config.rst b/test/reports/testnet-peer-voting/node-config.rst index 2a47ea13f..19a93dfa6 100644 --- a/test/reports/testnet-peer-voting/node-config.rst +++ b/test/reports/testnet-peer-voting/node-config.rst @@ -93,6 +93,8 @@ config-finalization.properties maxHashesPerPoint; 256 prevoteBlocksMultiple; 4 unfinalizedBlocksDuration; 0m + treasuryReissuanceEpoch; 0 + **treasury_reissuance_epoch_ineligible_voter_addresses**; config-harvesting.properties ============================ @@ -619,7 +621,7 @@ config-network.properties :delim: ; **network**; ; ; - identifier; public-test; NetworkIdentifier; Network identifier. + identifier; testnet; NetworkIdentifier; Network identifier. nemesisSignerPublicKey; 2267B24107405779DDF0D8FBEABD8142B97105F356F3737B1FC02220E8F90FF2; Key; Nemesis public key. nodeEqualityStrategy; host; NodeIdentityEqualityStrategy; Node equality strategy. generationHashSeed; 3B5E1FA6445653C971A50687E75E6D09FB30481055E3990C84B25E9222DC1155; ; @@ -650,10 +652,11 @@ config-network.properties maxVotingKeyLifetime; 720; uint32_t; Maximum number of finalization rounds for which voting key can be registered. harvestBeneficiaryPercentage; 25; uint8_t; Percentage of the harvested fee that is collected by the beneficiary account. harvestNetworkPercentage; 5; uint8_t; Percentage of the harvested fee that is collected by the network. + harvestNetworkFeeSinkAddressV1; TCZ3UZPWWC5NR6TGGYEJ2MT4Z5ZLR3XTIVI4RHA; ; harvestNetworkFeeSinkAddress; TCZ3UZPWWC5NR6TGGYEJ2MT4Z5ZLR3XTIVI4RHA; Address; Address of the harvest network fee sink account. maxTransactionsPerBlock; 6'000; uint32_t; Maximum number of transactions per block. - **fork_heights**; ; ; - totalVotingBalanceCalculationFix; 398'520; uint32_t; Height of fork to fix TotalVotingBalance calculation. + treasuryReissuanceBlockTransactionsHash; 0000000000000000000000000000000000000000000000000000000000000000; ; + treasuryReissuanceFallbackBlockTransactionsHash; 0000000000000000000000000000000000000000000000000000000000000000; ; **plugin:catapult.plugins.accountlink**; dummy; to trigger plugin load **plugin:catapult.plugins.aggregate**; ; ; @@ -675,6 +678,7 @@ config-network.properties maxMosaicsPerAccount; 1'000; uint16_t; Maximum number of mosaics that an account can own. maxMosaicDuration; 3650d; utils::BlockSpan; Maximum mosaic duration. maxMosaicDivisibility; 6; uint8_t; Maximum mosaic divisibility. + mosaicRentalFeeSinkAddressV1; TAFNXW3VXVFTGTVGATKQAR75ALQX7DQXQJRWWTA; ; mosaicRentalFeeSinkAddress; TAFNXW3VXVFTGTVGATKQAR75ALQX7DQXQJRWWTA; Address; Address of the mosaic rental fee sink account. mosaicRentalFee; 500000; Amount; Mosaic rental fee. **plugin:catapult.plugins.multisig**; ; ; @@ -689,6 +693,7 @@ config-network.properties maxNamespaceDuration; 1825d; utils::BlockSpan; Maximum namespace duration. namespaceGracePeriodDuration; 1d; utils::BlockSpan; Grace period during which time only the previous owner can renew an expired namespace. reservedRootNamespaceNames; symbol, symbl, xym, xem, nem, user, account, org, com, biz, net, edu, mil, gov, info; unordered_set; Reserved root namespaces that cannot be claimed. + namespaceRentalFeeSinkAddressV1; TATBDUEWS2X2BKKBPVB7SY4Z626YCAERGA3IF5A; ; namespaceRentalFeeSinkAddress; TATBDUEWS2X2BKKBPVB7SY4Z626YCAERGA3IF5A; Address; Address of the namespace rental fee sink account. rootNamespaceRentalFeePerBlock; 2; Amount; Root namespace rental fee per block. childNamespaceRentalFee; 100000; Amount; Child namespace rental fee. @@ -698,6 +703,11 @@ config-network.properties maxMosaicRestrictionValues; 20; uint8_t; Maximum number of mosaic restriction values. **plugin:catapult.plugins.transfer**; ; ; maxMessageSize; 1024; uint16_t; Maximum transaction message size. + **fork_heights**; ; ; + totalVotingBalanceCalculationFix; 398'520; uint32_t; Height of fork to fix TotalVotingBalance calculation. + treasuryReissuance; 0; ; + **treasury_reissuance_transaction_signatures**; + **treasury_reissuance_fallback_transaction_signatures**; config-node.properties ====================== @@ -723,7 +733,7 @@ config-node.properties shortLivedCachePruneInterval; 90s; utils::TimeSpan; Time between short lived cache pruning. shortLivedCacheMaxSize; 10'000'000; uint32_t; Maximum size of a short lived cache. minFeeMultiplier; 100; BlockFeeMultiplier; Minimum fee multiplier of transactions to propagate and include in blocks. - maxTimeBehindPullTransactionsStart; 5m; ; + maxTimeBehindPullTransactionsStart; 24h; ; transactionSelectionStrategy; oldest; model::TransactionSelectionStrategy; Transaction selection strategy used for syncing and harvesting unconfirmed transactions. unconfirmedTransactionsCacheMaxResponseSize; 5MB; utils::FileSize; Maximum size of an unconfirmed transactions response. unconfirmedTransactionsCacheMaxSize; 20MB; uint32_t; Maximum size of the unconfirmed transactions cache. @@ -741,7 +751,7 @@ config-node.properties enableDispatcherAbortWhenFull; false; bool; Set to true if the process should terminate when any dispatcher is full. enableDispatcherInputAuditing; false; bool; Set to true if all dispatcher inputs should be audited. maxTrackedNodes; 5'000; uint32_t; Maximum number of nodes to track in memory. - minPartnerNodeVersion; 1.0.1.0; ; + minPartnerNodeVersion; 1.0.2.0; ; maxPartnerNodeVersion; 1.0.255.255; ; trustedHosts; 127.0.0.1; unordered_set; Trusted hosts that are allowed to execute protected API calls on this node. localNetworks; 127.0.0.1; unordered_set; Networks that should be treated as local. @@ -757,7 +767,7 @@ config-node.properties **localnode**; ; ; host; ; string; Node host (leave empty to auto-detect IP). friendlyName; myFriendlyName; string; Node friendly name (leave empty to use address). - version; 1.0.2.0; uint32_t; Node version. + version; ; uint32_t; Node version. roles; Peer,Voting; ionet::NodeRoles; Node roles. **outgoing_connections**; ; ; maxConnections; 10; uint16_t; Maximum number of active connections. diff --git a/test/service/AgentCertificateService.test.ts b/test/service/AgentCertificateService.test.ts deleted file mode 100644 index c4c0d2dbd..000000000 --- a/test/service/AgentCertificateService.test.ts +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2021 NEM - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { expect } from 'chai'; -import { promises as fsPromises, readFileSync } from 'fs'; -import 'mocha'; -import { join } from 'path'; -import { AgentCertificateService, BootstrapUtils, ConfigLoader, Preset } from '../../src/service'; - -describe('AgentCertificateService', () => { - it('createCertificate', async () => { - const target = 'target/tests/AgentCertificateService'; - await BootstrapUtils.deleteFolder(target); - await BootstrapUtils.mkdir(target); - const service = new AgentCertificateService('.', { target: target, user: await BootstrapUtils.getDockerUserGroup() }); - - const presetData = new ConfigLoader().createPresetData({ - root: '.', - preset: Preset.bootstrap, - password: 'abc', - }); - - await service.run( - presetData.networkType, - presetData.symbolServerImage, - 'supernode', - { - agent: { - privateKey: '8D1929CAC89295BE7DBE26B7F830AA42A74D75D7055117DF2973001E3271BDD9', - publicKey: '04794EE7BD0810057870C7739C985D42BB4AAA4B1B9E3A71BFE6373A72D63726', - }, - }, - target, - ); - - const files = await fsPromises.readdir(target); - expect(files).deep.eq([ - 'agent-ca.cnf', - 'agent-ca.csr.pem', - 'agent-ca.key.pem', - 'agent-ca.pubkey.pem', - 'agent-comm.cnf', - 'index.txt', - 'metadata.yml', - 'new_certs', - ]); - - files - .filter((f) => f != 'new_certs') - .forEach((f) => { - expect(readFileSync(join(target, f))).deep.eq(readFileSync(join('test', 'agentCertificates', f))); - }); - }); -}); diff --git a/test/service/AnnounceService.test.ts b/test/service/AnnounceService.test.ts new file mode 100644 index 000000000..b05cd0136 --- /dev/null +++ b/test/service/AnnounceService.test.ts @@ -0,0 +1,345 @@ +import { expect } from 'chai'; +import { of } from 'rxjs'; +import { match, restore, spy, stub } from 'sinon'; +import { + Account, + Address, + AggregateTransaction, + Currency, + Deadline, + Mosaic, + MosaicId, + NetworkType, + PlainMessage, + Transaction, + TransactionService, + TransferTransaction, + UInt64, +} from 'symbol-sdk'; +import { + AnnounceService, + BootstrapService, + CommandUtils, + ConfigService, + Preset, + RemoteNodeService, + RepositoryInfo, +} from '../../src/service'; +import { TransactionUtils } from '../../src/service/TransactionUtils'; + +describe('Announce Service', () => { + let announceService: AnnounceService; + + beforeEach(() => { + announceService = new AnnounceService(); + }); + + afterEach(restore); + + const password = '1234'; + const params = { + ...ConfigService.defaultParams, + ready: true, + target: 'target/tests/testnet-dual', + password, + reset: false, + offline: true, + preset: Preset.testnet, + customPresetObject: { + lastKnownNetworkEpoch: 1, + nodeUseRemoteAccount: true, + nodes: [ + { + mainPrivateKey: 'CA82E7ADAF7AB729A5462A1BD5AA78632390634904A64EB1BB22295E2E1A1BDD', + friendlyName: 'myFriendlyName', + }, + ], + }, + assembly: 'dual', + }; + + const url = 'http://localhost:3000'; + const maxFee = 2_000_000; + const useKnownRestGateways = false; + const networkType = NetworkType.TEST_NET; + const epochAdjustment = 1_616_694_977; + const networkGenerationHash = '3B5E1FA6445653C971A50687E75E6D09FB30481055E3990C84B25E9222DC1155'; + const mainPublicKey = Account.createFromPrivateKey(params.customPresetObject.nodes[0].mainPrivateKey, networkType).publicKey; + + const serviceProviderAccount = Account.createFromPrivateKey( + '6A9A60768C36769C2D756B0CE4DEE3C50CCE2B08A60CFA259289AA4D2706F3C5', + networkType, + ); + const cosigner1 = Account.createFromPrivateKey('41C0163B6A057A4E7B6264AC5BB36C44E0245F8552242BF6A163617C4D616ED3', networkType); + const cosigner2 = Account.createFromPrivateKey('2FBDC1419F22BC049F6E869B144778277C5930D8D07D55E99ADD2282399FDCF5', networkType); + const currencyMosaicId = new MosaicId('091F837E059AE13C'); + + const singleTransactionFactory = { + createTransactions(): Promise { + return Promise.resolve([ + TransferTransaction.create( + Deadline.create(epochAdjustment), + Address.createFromPublicKey(mainPublicKey, networkType), + [new Mosaic(currencyMosaicId, UInt64.fromUint(9_000_000))], + PlainMessage.create('This is a transfer transaction.'), + networkType, + UInt64.fromUint(maxFee), + undefined, + ), + ]); + }, + }; + const multipleTransactionFactory = { + createTransactions(): Promise { + return Promise.resolve([ + TransferTransaction.create( + Deadline.create(epochAdjustment), + Address.createFromPublicKey(mainPublicKey, networkType), + [new Mosaic(currencyMosaicId, UInt64.fromUint(9_000_000))], + PlainMessage.create('Inner tx 1'), + networkType, + UInt64.fromUint(maxFee), + undefined, + ), + TransferTransaction.create( + Deadline.create(epochAdjustment), + Address.createFromPublicKey(mainPublicKey, networkType), + [new Mosaic(currencyMosaicId, UInt64.fromUint(9_000_000))], + PlainMessage.create('Inner tx 2'), + networkType, + UInt64.fromUint(maxFee), + undefined, + ), + ]); + }, + }; + + const stubCommon = (networkType: NetworkType, epochAdjustment: number, currencyMosaicId: MosaicId, networkGenerationHash: string) => { + stub(RemoteNodeService.prototype, 'getBestRepositoryInfo').callsFake(() => + Promise.resolve(({ + repositoryFactory: { + getNetworkType() { + return of(networkType); + }, + createTransactionRepository: stub(), + createReceiptRepository: stub(), + getEpochAdjustment() { + return of(epochAdjustment); + }, + createListener() { + return { + open: stub(), + close: stub(), + }; + }, + getCurrencies() { + return of({ + currency: new Currency({ + mosaicId: currencyMosaicId, + divisibility: 6, + transferable: true, + supplyMutable: false, + restrictable: false, + }), + }); + }, + createNetworkRepository() { + return { + getTransactionFees() { + return of({ minFeeMultiplier: 10 }); + }, + }; + }, + createChainRepository() { + return { + getChainInfo() { + return of({ latestFinalizedBlock: 10 }); + }, + }; + }, + getGenerationHash() { + return of(networkGenerationHash); + }, + }, + } as unknown) as RepositoryInfo), + ); + + stub(announceService, 'getAccountInfo').returns( + Promise.resolve({ + mosaics: [new Mosaic(currencyMosaicId, UInt64.fromUint(100_000_000))], + }), + ); + }; + + it('Main account regular - Announces simple transaction when single transaction given', async () => { + const transactionFactory = singleTransactionFactory; + + const { addresses, presetData } = await new BootstrapService().config(params); + stubCommon(networkType, epochAdjustment, currencyMosaicId, networkGenerationHash); + + const tsAnnounce = stub(TransactionService.prototype, 'announce').returns(of({} as Transaction)); + const announceSimple = spy(announceService, 'announceSimple'); + await announceService.announce( + url, + maxFee, + useKnownRestGateways, + params.ready, + params.target, + presetData, + addresses, + transactionFactory, + ); + + expect(announceSimple.called).to.be.true; + expect(tsAnnounce.calledOnceWith(match({ signerPublicKey: mainPublicKey }), match.any)).to.be.true; + }); + + it('Main account regular- Announces aggregate complete when multiple transactions given', async () => { + const transactionFactory = multipleTransactionFactory; + + const { addresses, presetData } = await new BootstrapService().config(params); + stubCommon(networkType, epochAdjustment, currencyMosaicId, networkGenerationHash); + + const tsAnnounce = stub(TransactionService.prototype, 'announce').returns(of({} as Transaction)); + const announceAggregateComplete = spy(announceService, 'announceAggregateComplete'); + await announceService.announce( + url, + maxFee, + useKnownRestGateways, + params.ready, + params.target, + presetData, + addresses, + transactionFactory, + ); + + expect(announceAggregateComplete.called).to.be.true; + expect(tsAnnounce.calledOnceWith(match({ signerPublicKey: mainPublicKey }), match.any)).to.be.true; + }); + + it('Main account multisig - Announces aggregate complete when single transaction and all required cosignatures given', async () => { + const transactionFactory = multipleTransactionFactory; + const cosigns = [cosigner1, cosigner2]; + const bestCosigner = cosigner1; + + const { addresses, presetData } = await new BootstrapService().config(params); + stubCommon(networkType, epochAdjustment, currencyMosaicId, networkGenerationHash); + + stub(TransactionUtils, 'getMultisigAccount').returns( + Promise.resolve({ + minApproval: 2, + }), + ); + stub(announceService, 'getMultisigBestCosigner').callsFake((multisigAccountInfo, cosigners: Account[]) => { + cosigners.push(...cosigns); + return bestCosigner; + }); + const tsAnnounce = stub(TransactionService.prototype, 'announce').returns(of({} as Transaction)); + const announceAggregateComplete = spy(announceService, 'announceAggregateComplete'); + await announceService.announce( + url, + maxFee, + useKnownRestGateways, + params.ready, + params.target, + presetData, + addresses, + transactionFactory, + ); + + expect(announceAggregateComplete.called).to.be.true; + expect(tsAnnounce.calledOnceWith(match({ signerPublicKey: bestCosigner.publicKey }), match.any)).to.be.true; + }); + + it('Service provider account regular - Announces aggregate bonded', async () => { + const transactionFactory = multipleTransactionFactory; + + const { addresses, presetData } = await new BootstrapService().config(params); + stubCommon(networkType, epochAdjustment, currencyMosaicId, networkGenerationHash); + + stub(CommandUtils, 'resolvePrivateKey').returns(Promise.resolve(serviceProviderAccount.privateKey)); + const tsAnnounce = stub(TransactionService.prototype, 'announce').returns(of({} as Transaction)); + const tsAnnounceBonded = stub(TransactionService.prototype, 'announceAggregateBonded').returns(of({} as AggregateTransaction)); + const announceAggregateBonded = spy(announceService, 'announceAggregateBonded'); + const createBonded = spy(AggregateTransaction, 'createBonded'); + await announceService.announce( + url, + maxFee, + useKnownRestGateways, + params.ready, + params.target, + presetData, + addresses, + transactionFactory, + 'some', + serviceProviderAccount.publicKey, + ); + + expect(announceAggregateBonded.called).to.be.true; + expect(tsAnnounce.calledOnceWith(match({ signerPublicKey: serviceProviderAccount.publicKey }), match.any)).to.be.true; + expect(tsAnnounceBonded.calledOnceWith(match({ signerPublicKey: serviceProviderAccount.publicKey }), match.any)).to.be.true; + expect( + createBonded.calledWith( + match.any, + [ + match({ signer: { publicKey: mainPublicKey } }), + match({ signer: { publicKey: mainPublicKey } }), + match({ signer: { publicKey: serviceProviderAccount.publicKey } }), + ], + match.any, + ), + ).to.be.true; + }); + + it('Service provider account multisig - Announces aggregate bonded', async () => { + const transactionFactory = multipleTransactionFactory; + const cosigns = [cosigner1, cosigner2]; + const bestCosigner = cosigner1; + + const { addresses, presetData } = await new BootstrapService().config(params); + stubCommon(networkType, epochAdjustment, currencyMosaicId, networkGenerationHash); + + stub(TransactionUtils, 'getMultisigAccount').returns( + Promise.resolve({ + minApproval: 2, + }), + ); + stub(announceService, 'getMultisigBestCosigner').callsFake((multisigAccountInfo, cosigners: Account[]) => { + cosigners.push(...cosigns); + return bestCosigner; + }); + + stub(CommandUtils, 'resolvePrivateKey').returns(Promise.resolve(bestCosigner.privateKey)); + const tsAnnounce = stub(TransactionService.prototype, 'announce').returns(of({} as Transaction)); + const tsAnnounceBonded = stub(TransactionService.prototype, 'announceAggregateBonded').returns(of({} as AggregateTransaction)); + const announceAggregateBonded = spy(announceService, 'announceAggregateBonded'); + const createBonded = spy(AggregateTransaction, 'createBonded'); + await announceService.announce( + url, + maxFee, + useKnownRestGateways, + params.ready, + params.target, + presetData, + addresses, + transactionFactory, + 'some', + serviceProviderAccount.publicKey, + ); + + expect(announceAggregateBonded.called).to.be.true; + expect(tsAnnounce.calledOnceWith(match({ signerPublicKey: bestCosigner.publicKey }), match.any)).to.be.true; + expect(tsAnnounceBonded.calledOnceWith(match({ signerPublicKey: bestCosigner.publicKey }), match.any)).to.be.true; + expect( + createBonded.calledWith( + match.any, + [ + match({ signer: { publicKey: mainPublicKey } }), + match({ signer: { publicKey: mainPublicKey } }), + match({ signer: { publicKey: serviceProviderAccount.publicKey } }), + ], + match.any, + ), + ).to.be.true; + }); +}); diff --git a/test/service/BootstrapServce.test.ts b/test/service/BootstrapServce.test.ts index 25f50f631..007886a83 100644 --- a/test/service/BootstrapServce.test.ts +++ b/test/service/BootstrapServce.test.ts @@ -19,7 +19,7 @@ import 'mocha'; import { BootstrapService, Preset, StartParams } from '../../src/service'; describe('BootstrapService', () => { - it(' bootstrap config compose non aws', async () => { + it(' bootstrap config compose bootstrap/default', async () => { const service = new BootstrapService(); const config: StartParams = { report: false, @@ -38,4 +38,25 @@ describe('BootstrapService', () => { const dockerCompose = await service.compose(config); expect(dockerCompose).to.not.undefined; }); + + it(' bootstrap config compose testnet/dual', async () => { + const service = new BootstrapService(); + const config: StartParams = { + report: false, + preset: Preset.testnet, + assembly: 'dual', + reset: true, + upgrade: false, + timeout: 60000 * 5, + target: 'target/tests/BootstrapService.testnet', + detached: true, + user: 'current', + }; + + const configResult = await service.config(config); + expect(configResult.presetData).to.not.null; + expect(configResult.addresses).to.not.null; + const dockerCompose = await service.compose(config); + expect(dockerCompose).to.not.undefined; + }); }); diff --git a/test/service/BootstrapUtils.test.ts b/test/service/BootstrapUtils.test.ts index 076d53b71..b779108d4 100644 --- a/test/service/BootstrapUtils.test.ts +++ b/test/service/BootstrapUtils.test.ts @@ -24,6 +24,7 @@ import { Account, NetworkType } from 'symbol-sdk'; import { ConfigAccount } from '../../src/model'; import { BootstrapUtils, ConfigLoader, CryptoUtils } from '../../src/service'; import assert = require('assert'); +import nock = require('nock'); describe('BootstrapUtils', () => { it('BootstrapUtils dockerUserId', async () => { @@ -57,12 +58,15 @@ describe('BootstrapUtils', () => { expect(BootstrapUtils.toAmount("12'3456'78")).to.be.eq("12'345'678"); }); - it.skip('BootstrapUtils.download', async () => { - BootstrapUtils.deleteFile('boat.png'); // unit test fixed in dev! + it('BootstrapUtils.download', async () => { + const url = 'https://myserver.get'; - const expectedSize = 177762; + BootstrapUtils.deleteFile('boat.png'); + + const expectedSize = 43970; async function download(): Promise { - const result = await BootstrapUtils.download('https://homepages.cae.wisc.edu/~ece533/images/boat.png', 'boat.png'); + nock(url).get('/boat.png').replyWithFile(200, 'test/boat.png', { 'content-length': expectedSize.toString() }); + const result = await BootstrapUtils.download(url + '/boat.png', 'boat.png'); expect(statSync('boat.png').size).eq(expectedSize); return result.downloaded; } @@ -79,13 +83,15 @@ describe('BootstrapUtils', () => { expect(BootstrapUtils.resolveRootFolder()).to.not.undefined; }); - it.skip('BootstrapUtils.download when invalid', async () => { - BootstrapUtils.deleteFile('boat.png'); // unit test fixed in dev! + it('BootstrapUtils.download when invalid', async () => { + BootstrapUtils.deleteFile('boat.png'); try { - await BootstrapUtils.download('https://homepages.cae.wisc.edu/~ece533/images/invalid-boat.png', 'boat.png'); + const url = 'https://myserver.get'; + nock(url).get('/boat.png').reply(404); + await BootstrapUtils.download(url + '/boat.png', 'boat.png'); expect(false).eq(true); } catch (e) { - expect(e.message).eq('Server responded with 404: Not Found'); + expect(e.message).eq('Server responded with 404'); } }); diff --git a/test/service/CertificateService.test.ts b/test/service/CertificateService.test.ts index 27e73035a..fa0c15d6d 100644 --- a/test/service/CertificateService.test.ts +++ b/test/service/CertificateService.test.ts @@ -19,25 +19,10 @@ import { deepStrictEqual } from 'assert'; import { promises as fsPromises, readFileSync } from 'fs'; import 'mocha'; import { join } from 'path'; -import * as sshpk from 'sshpk'; -import { Account, Convert, NetworkType } from 'symbol-sdk'; -import { - BootstrapUtils, - CertificateMetadata, - CertificateService, - ConfigLoader, - ForgeCertificateService, - NodeCertificates, - Preset, -} from '../../src/service'; +import { Account, NetworkType } from 'symbol-sdk'; +import { BootstrapUtils, CertificateMetadata, CertificateService, ConfigLoader, NodeCertificates, Preset } from '../../src/service'; describe('CertificateService', () => { - it('forge create certificate', async () => { - await BootstrapUtils.deleteFolder('./target/tests/unitTests'); - const service = new ForgeCertificateService({ target: './target/tests/unitTests' }); - await service.run('peer-node'); - }); - it('getCertificates from output', async () => { const outputFile = `./test/certificates/output.txt`; const output = BootstrapUtils.loadFileAsText(outputFile); @@ -54,18 +39,6 @@ describe('CertificateService', () => { ]); }); - it('parse public key', async () => { - const nodeCertKey: any = sshpk.parseKey( - '-----BEGIN PUBLIC KEY-----\n' + - 'MCowBQYDK2VwAyEAxpp0FX4tsApDzLYEAH2MNDItqWk2/fnhwAeTj0cT/qk=\n' + - '-----END PUBLIC KEY-----\n', - 'pem', - ); - const publicKey = Convert.uint8ToHex(nodeCertKey.parts[0].data); - expect('C69A74157E2DB00A43CCB604007D8C34322DA96936FDF9E1C007938F4713FEA9').be.eq(publicKey); - console.log(publicKey); - }); - it('createCertificates', async () => { const target = 'target/tests/CertificateService.test'; await BootstrapUtils.deleteFolder(target); diff --git a/test/service/ComposeService.test.ts b/test/service/ComposeService.test.ts index 2a831824b..40d1704b3 100644 --- a/test/service/ComposeService.test.ts +++ b/test/service/ComposeService.test.ts @@ -144,18 +144,32 @@ ${BootstrapUtils.toYaml(dockerCompose)} await assertDockerCompose(params, 'expected-mainnet-peer-compose.yml'); }); - it('Compose testnet supernode', async () => { + it('Compose testnet httpsProxy', async () => { const params = { ...ConfigService.defaultParams, ...LinkService.defaultParams, - target: 'target/tests/testnet-supernode', + target: 'target/tests/testnet-https-proxy', password, - customPreset: './test/unit-test-profiles/supernode.yml', + customPreset: './test/unit-test-profiles/https-proxy.yml', reset: false, preset: Preset.testnet, assembly: 'dual', }; - await assertDockerCompose(params, 'expected-testnet-supernode-compose.yml'); + await assertDockerCompose(params, 'expected-testnet-httpsproxy-compose.yml'); + }); + + it('Compose testnet native ssl', async () => { + const params = { + ...ConfigService.defaultParams, + ...LinkService.defaultParams, + target: 'target/tests/testnet-native-ssl', + password, + customPreset: './test/unit-test-profiles/native-ssl.yml', + reset: false, + preset: Preset.testnet, + assembly: 'dual', + }; + await assertDockerCompose(params, 'expected-testnet-native-ssl-compose.yml'); }); it('Compose testnet dual voting', async () => { diff --git a/test/service/ConfigLoader.test.ts b/test/service/ConfigLoader.test.ts index 6d11288ef..a8fc9a81b 100644 --- a/test/service/ConfigLoader.test.ts +++ b/test/service/ConfigLoader.test.ts @@ -279,7 +279,7 @@ describe('ConfigLoader', () => { it('should generateAccount when old and new are different', () => { const configLoader = new ConfigLoader(); - const networkType = NetworkType.MIJIN_TEST; + const networkType = NetworkType.TEST_NET; const securityMode = PrivateKeySecurityMode.ENCRYPT; const oldAccount = Account.generateNewAccount(networkType); const newAccount = Account.generateNewAccount(networkType); @@ -304,7 +304,7 @@ describe('ConfigLoader', () => { it('should generateAccount when old and new are different', () => { const configLoader = new ConfigLoader(); - const networkType = NetworkType.MIJIN_TEST; + const networkType = NetworkType.TEST_NET; const securityMode = PrivateKeySecurityMode.ENCRYPT; const oldAccount = Account.generateNewAccount(networkType); const newAccount = Account.generateNewAccount(networkType); @@ -329,7 +329,7 @@ describe('ConfigLoader', () => { it('should generateAccount when old and new are same', () => { const configLoader = new ConfigLoader(); - const networkType = NetworkType.MIJIN_TEST; + const networkType = NetworkType.TEST_NET; const securityMode = PrivateKeySecurityMode.ENCRYPT; const oldAccount = Account.generateNewAccount(networkType); const newAccount = oldAccount; @@ -354,7 +354,7 @@ describe('ConfigLoader', () => { it('should generateAccount when old and new are same, new no private eky', () => { const configLoader = new ConfigLoader(); - const networkType = NetworkType.MIJIN_TEST; + const networkType = NetworkType.TEST_NET; const securityMode = PrivateKeySecurityMode.ENCRYPT; const oldAccount = Account.generateNewAccount(networkType); const newAccount = oldAccount; @@ -379,7 +379,7 @@ describe('ConfigLoader', () => { it('should generateAccount when old and new are same, old no private eky', () => { const configLoader = new ConfigLoader(); - const networkType = NetworkType.MIJIN_TEST; + const networkType = NetworkType.TEST_NET; const securityMode = PrivateKeySecurityMode.ENCRYPT; const oldAccount = Account.generateNewAccount(networkType); const newAccount = oldAccount; @@ -403,7 +403,7 @@ describe('ConfigLoader', () => { it('should generateAccount when old and new are same, old private key', () => { const configLoader = new ConfigLoader(); - const networkType = NetworkType.MIJIN_TEST; + const networkType = NetworkType.TEST_NET; const securityMode = PrivateKeySecurityMode.ENCRYPT; const oldAccount = Account.generateNewAccount(networkType); const newAccount = oldAccount; @@ -426,7 +426,7 @@ describe('ConfigLoader', () => { it('should generateAccount when old and new are different, no private key new', () => { const configLoader = new ConfigLoader(); - const networkType = NetworkType.MIJIN_TEST; + const networkType = NetworkType.TEST_NET; const securityMode = PrivateKeySecurityMode.ENCRYPT; const oldAccount = Account.generateNewAccount(networkType); const newAccount = Account.generateNewAccount(networkType); @@ -450,7 +450,7 @@ describe('ConfigLoader', () => { it('should generateAccount when old and new are different. No new account', () => { const configLoader = new ConfigLoader(); - const networkType = NetworkType.MIJIN_TEST; + const networkType = NetworkType.TEST_NET; const securityMode = PrivateKeySecurityMode.ENCRYPT; const oldAccount = Account.generateNewAccount(networkType); const account = configLoader.generateAccount( @@ -474,7 +474,7 @@ describe('ConfigLoader', () => { it('should generateAccount when old and new are different. No new account. Old without private', () => { const configLoader = new ConfigLoader(); - const networkType = NetworkType.MIJIN_TEST; + const networkType = NetworkType.TEST_NET; const securityMode = PrivateKeySecurityMode.ENCRYPT; const oldAccount = Account.generateNewAccount(networkType); const account = configLoader.generateAccount( @@ -496,7 +496,7 @@ describe('ConfigLoader', () => { it('should generateAccount brand new', () => { const configLoader = new ConfigLoader(); - const networkType = NetworkType.MIJIN_TEST; + const networkType = NetworkType.TEST_NET; const securityMode = PrivateKeySecurityMode.ENCRYPT; const account = configLoader.generateAccount(networkType, securityMode, KeyName.Main, undefined, undefined, undefined); expect(account.address).not.undefined; @@ -506,7 +506,7 @@ describe('ConfigLoader', () => { it('should generateAccount brand new on remote', () => { const configLoader = new ConfigLoader(); - const networkType = NetworkType.MIJIN_TEST; + const networkType = NetworkType.TEST_NET; const securityMode = PrivateKeySecurityMode.PROMPT_MAIN_TRANSPORT; const account = configLoader.generateAccount(networkType, securityMode, KeyName.Remote, undefined, undefined, undefined); expect(account.address).not.undefined; @@ -516,7 +516,7 @@ describe('ConfigLoader', () => { it('should generateAccount brand new on voting', () => { const configLoader = new ConfigLoader(); - const networkType = NetworkType.MIJIN_TEST; + const networkType = NetworkType.TEST_NET; const securityMode = PrivateKeySecurityMode.PROMPT_MAIN; const account = configLoader.generateAccount(networkType, securityMode, KeyName.Voting, undefined, undefined, undefined); expect(account.address).not.undefined; @@ -526,21 +526,21 @@ describe('ConfigLoader', () => { it('should generateAccount raise error new', () => { const configLoader = new ConfigLoader(); - const networkType = NetworkType.MIJIN_TEST; + const networkType = NetworkType.TEST_NET; const securityMode = PrivateKeySecurityMode.PROMPT_MAIN; expect(() => configLoader.generateAccount(networkType, securityMode, KeyName.Main, undefined, undefined, undefined)).throw; }); it('should generateAccount raise error new', () => { const configLoader = new ConfigLoader(); - const networkType = NetworkType.MIJIN_TEST; + const networkType = NetworkType.TEST_NET; const securityMode = PrivateKeySecurityMode.PROMPT_MAIN_TRANSPORT; expect(() => configLoader.generateAccount(networkType, securityMode, KeyName.Transport, undefined, undefined, undefined)).throw; }); it('should generateAccount raise error new', () => { const configLoader = new ConfigLoader(); - const networkType = NetworkType.MIJIN_TEST; + const networkType = NetworkType.TEST_NET; const securityMode = PrivateKeySecurityMode.PROMPT_ALL; expect(() => configLoader.generateAccount(networkType, securityMode, KeyName.Remote, undefined, undefined, undefined)).throw; }); diff --git a/test/service/ConfigService.test.ts b/test/service/ConfigService.test.ts index 2bbdd2e25..45771e18e 100644 --- a/test/service/ConfigService.test.ts +++ b/test/service/ConfigService.test.ts @@ -101,64 +101,4 @@ describe('ConfigService', () => { assertRepeatedService(4, configResult.presetData.gateways); assertRepeatedService(4, configResult.presetData.databases); }); - - it('ConfigService mainnet supernode assembly after upgrade', async () => { - const configResultInitial = await new ConfigService('.', { - ...ConfigService.defaultParams, - reset: true, - target: 'target/tests/ConfigService.mainnet.supernode', - preset: Preset.mainnet, - customPreset: 'test/unit-test-profiles/supernode.yml', - assembly: 'dual', - }).run(); - const configResultUpgrade = await new ConfigService('.', { - ...ConfigService.defaultParams, - upgrade: true, - target: 'target/tests/ConfigService.mainnet.supernode', - preset: Preset.mainnet, - assembly: 'dual', - }).run(); - expect(CryptoUtils.removePrivateKeys(configResultUpgrade.presetData)).deep.eq( - CryptoUtils.removePrivateKeys(configResultInitial.presetData), - ); - const configResultUpgradeSecond = await new ConfigService('.', { - ...ConfigService.defaultParams, - upgrade: true, - target: 'target/tests/ConfigService.mainnet.supernode', - }).run(); - - expect(CryptoUtils.removePrivateKeys(configResultUpgradeSecond.presetData)).deep.eq( - CryptoUtils.removePrivateKeys(configResultInitial.presetData), - ); - }); - - it('ConfigService testnet supernode assembly after upgrade', async () => { - const configResultInitial = await new ConfigService('.', { - ...ConfigService.defaultParams, - reset: true, - target: 'target/tests/ConfigService.testnet.supernode', - preset: Preset.testnet, - customPreset: 'test/unit-test-profiles/supernode.yml', - assembly: 'dual', - }).run(); - const configResultUpgrade = await new ConfigService('.', { - ...ConfigService.defaultParams, - upgrade: true, - target: 'target/tests/ConfigService.testnet.supernode', - preset: Preset.testnet, - assembly: 'dual', - }).run(); - expect(CryptoUtils.removePrivateKeys(configResultUpgrade.presetData)).deep.eq( - CryptoUtils.removePrivateKeys(configResultInitial.presetData), - ); - const configResultUpgradeSecond = await new ConfigService('.', { - ...ConfigService.defaultParams, - upgrade: true, - target: 'target/tests/ConfigService.testnet.supernode', - }).run(); - - expect(CryptoUtils.removePrivateKeys(configResultUpgradeSecond.presetData)).deep.eq( - CryptoUtils.removePrivateKeys(configResultInitial.presetData), - ); - }); }); diff --git a/test/service/ExperimentalCertificateService.test.ts b/test/service/ExperimentalCertificateService.test.ts deleted file mode 100644 index 4f5863ef8..000000000 --- a/test/service/ExperimentalCertificateService.test.ts +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2020 NEM - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { expect } from '@oclif/test'; -import 'mocha'; -import * as sshpk from 'sshpk'; -import { Account, Convert, NetworkType } from 'symbol-sdk'; - -const anySshpk = sshpk as any; -describe('sshpk', () => { - it('sshpk certificate generated', async () => { - const hex = 'CA82E7ADAF7AB729A5462A1BD5AA78632390634904A64EB1BB22295E2E1A1BDD'; - - const keyText = `-----BEGIN PRIVATE KEY----- -MC4CAQAwBQYDK2VwBCIEIMqC562vercppUYqG9WqeGMjkGNJBKZOsbsiKV4uGhvd ------END PRIVATE KEY----- -`; - - const key = anySshpk.parsePrivateKey(keyText); - const privateKey = Convert.uint8ToHex(key.part.k.data); - const publicKey = Convert.uint8ToHex(key.toPublic().part.A.data); - expect(hex).eq(privateKey); - console.log(key.toPublic().toString('pem')); - expect(publicKey).eq(Account.createFromPrivateKey(privateKey, NetworkType.MIJIN_TEST).publicKey); - // - // const object = createSelfSignedCertificate({ subject: 'adsf' } as any, key, { lifetime: 7300 * 86400 }); - // console.log(object); - }); -}); - -describe('ForgeCertificateService', () => { - it('certificate generated', async () => { - // const der = readFileSync('ca.der', { encoding: 'binary' }); - // const asn1 = forge.asn1.fromDer(der); - // const publicKey = forge.pki.publicKeyFromAsn1(asn1); - // const pem = forge.pki.publicKeyToPem(publicKey); - // console.log(pem); - - const key = `-----BEGIN PRIVATE KEY----- -MC4CAQAwBQYDK2VwBCIEIMqC562vercppUYqG9WqeGMjkGNJBKZOsbsiKV4uGhvd ------END PRIVATE KEY----- -`; - - // const privateKey = forge.pki.privateKeyFromPem(key); - // const message = 'abc'; - // const buffer = forge.util.createBuffer(message, 'utf8'); - // const binaryString = buffer.getBytes(); - // - // console.log(binaryString); - - // const privateKey = 'CA82E7ADAF7AB729A5462A1BD5AA78632390634904A64EB1BB22295E2E1A1BDD'; - // const derFile = 'ca.der'; - // BootstrapUtils.createDerFile(privateKey, derFile); - // await BootstrapUtils.exec('cat ca.der | openssl pkey -inform DER -outform PEM -out ca.key.pem'); - // - // const forgePrivateKey = forge.pki.decryptRsaPrivateKey(await BootstrapUtils.readTextFile('ca.key.pem')); - - // const der = readFileSync(derFile, { encoding: 'binary' }); - // const asn1 = forge.asn1.fromDer(der); - // const privateKeyDer = forge.pki.privateKeyToAsn1(asn1 as forge.pki.PrivateKey); - - // const privateKeyObject = forge.pki.decryptRsaPrivateKey(derFile); - // const ed25519 = forge.pki.ed25519; - // const keypair = ed25519.generateKeyPair(); - // console.log(keypair.privateKey); - // `keypair.publicKey` is a node.js Buffer or Uint8Array - // `keypair.privateKey` is a node.js Buffer or Uint8Array - }); -}); diff --git a/test/service/LinkService.test.ts b/test/service/LinkService.test.ts index 1f2834dac..9ba241137 100644 --- a/test/service/LinkService.test.ts +++ b/test/service/LinkService.test.ts @@ -140,9 +140,7 @@ describe('LinkService', () => { preset: Preset.testnet, offline: true, customPreset: './test/unit-test-profiles/voting_preset.yml', - customPresetObject: { - nodeUseRemoteAccount: true, - }, + customPresetObject: { lastKnownNetworkEpoch: 235, nodeUseRemoteAccount: true }, assembly: 'dual', }; const { addresses, presetData } = await new BootstrapService().config(params); @@ -230,9 +228,7 @@ describe('LinkService', () => { reset: true, preset: Preset.testnet, customPreset: './test/unit-test-profiles/voting_preset.yml', - customPresetObject: { - nodeUseRemoteAccount: true, - }, + customPresetObject: { lastKnownNetworkEpoch: 235, nodeUseRemoteAccount: true }, assembly: 'dual', }; const { addresses, presetData } = await new BootstrapService().config(params); @@ -268,6 +264,7 @@ describe('LinkService', () => { target: target, password, upgrade: true, + offline: true, preset: Preset.testnet, customPreset: './test/unit-test-profiles/voting_preset.yml', customPresetObject: { @@ -309,10 +306,7 @@ describe('LinkService', () => { reset: true, preset: Preset.testnet, customPreset: './test/unit-test-profiles/voting_preset.yml', - customPresetObject: { - autoUpdateVotingKeys: true, - nodeUseRemoteAccount: true, - }, + customPresetObject: { lastKnownNetworkEpoch: 235, autoUpdateVotingKeys: true, nodeUseRemoteAccount: true }, assembly: 'dual', }; const { addresses, presetData } = await new BootstrapService().config(params); @@ -377,7 +371,6 @@ describe('LinkService', () => { assertTransaction(transactions[1], TransactionType.VRF_KEY_LINK, LinkAction.Link, nodeAccount.vrf!.publicKey); expect(lastKnownNetworkEpoch).gt(originalLasKnownNetworkEpoch + presetData.votingKeyDesiredLifetime); - console.log(lastKnownNetworkEpoch); assertVotingTransaction( transactions[2], LinkAction.Link, @@ -404,6 +397,7 @@ describe('LinkService', () => { preset: Preset.testnet, customPreset: './test/unit-test-profiles/voting_preset.yml', customPresetObject: { + lastKnownNetworkEpoch: 235, autoUpdateVotingKeys: true, nodeUseRemoteAccount: true, }, @@ -472,7 +466,6 @@ describe('LinkService', () => { assertTransaction(transactions[0], TransactionType.ACCOUNT_KEY_LINK, LinkAction.Link, nodeAccount.remote!.publicKey); assertTransaction(transactions[1], TransactionType.VRF_KEY_LINK, LinkAction.Link, nodeAccount.vrf!.publicKey); expect(lastKnownNetworkEpoch).lt(originalLasKnownNetworkEpoch + presetData.votingKeyDesiredLifetime); - console.log(lastKnownNetworkEpoch); assertVotingTransaction( transactions[2], LinkAction.Link, @@ -501,9 +494,7 @@ describe('LinkService', () => { reset: false, preset: Preset.testnet, customPreset: './test/unit-test-profiles/voting_preset.yml', - customPresetObject: { - nodeUseRemoteAccount: true, - }, + customPresetObject: { lastKnownNetworkEpoch: 235, nodeUseRemoteAccount: true }, assembly: 'dual', }; const { addresses, presetData } = await new BootstrapService().config(params); @@ -567,9 +558,7 @@ describe('LinkService', () => { reset: false, preset: Preset.testnet, customPreset: './test/unit-test-profiles/voting_preset.yml', - customPresetObject: { - nodeUseRemoteAccount: true, - }, + customPresetObject: { lastKnownNetworkEpoch: 235, nodeUseRemoteAccount: true }, assembly: 'dual', }; const { addresses, presetData } = await new BootstrapService().config(params); @@ -644,9 +633,7 @@ describe('LinkService', () => { reset: false, preset: Preset.testnet, customPreset: './test/unit-test-profiles/voting_preset.yml', - customPresetObject: { - nodeUseRemoteAccount: true, - }, + customPresetObject: { lastKnownNetworkEpoch: 235, nodeUseRemoteAccount: true }, assembly: 'dual', }; const { addresses, presetData } = await new BootstrapService().config(params); @@ -726,6 +713,7 @@ describe('LinkService', () => { }); it('LinkService create transactions when dual + voting and already linked not removed', async () => { + const lastKnownNetworkEpoch = 235; const params = { ...ConfigService.defaultParams, ...LinkService.defaultParams, @@ -733,17 +721,16 @@ describe('LinkService', () => { offline: true, target: 'target/tests/testnet-dual-voting', password, - reset: false, + reset: true, preset: Preset.testnet, customPreset: './test/unit-test-profiles/voting_preset.yml', - customPresetObject: { - nodeUseRemoteAccount: true, - }, + customPresetObject: { lastKnownNetworkEpoch: lastKnownNetworkEpoch, nodeUseRemoteAccount: true }, assembly: 'dual', removeOldLinked: false, }; const alreadyLinkedAccountInfo: AccountInfo = (AccountHttp as any)['toAccountInfo'](alreadyLinkedAccountInfoDto); const { addresses, presetData } = await new BootstrapService().config(params); + expect(presetData.lastKnownNetworkEpoch).eq(lastKnownNetworkEpoch); const maxFee = UInt64.fromUint(10); const nodeAccount = addresses.nodes![0]; const transactionFactoryParams: LinkServiceTransactionFactoryParams = { @@ -766,10 +753,9 @@ describe('LinkService', () => { target: 'target/tests/testnet-dual', password, reset: true, + offline: true, preset: Preset.testnet, - customPresetObject: { - nodeUseRemoteAccount: true, - }, + customPresetObject: { lastKnownNetworkEpoch: 235, nodeUseRemoteAccount: true }, assembly: 'dual', }; const { addresses, presetData } = await new BootstrapService().config(params); @@ -798,10 +784,9 @@ describe('LinkService', () => { target: 'target/tests/testnet-dual', password, reset: true, + offline: true, preset: Preset.testnet, - customPresetObject: { - nodeUseRemoteAccount: true, - }, + customPresetObject: { lastKnownNetworkEpoch: 235, nodeUseRemoteAccount: true }, assembly: 'dual', }; const { addresses, presetData } = await new BootstrapService().config(params); @@ -842,10 +827,9 @@ describe('LinkService', () => { target: 'target/tests/testnet-dual', password, reset: true, + offline: true, preset: Preset.testnet, - customPresetObject: { - nodeUseRemoteAccount: true, - }, + customPresetObject: { lastKnownNetworkEpoch: 235, nodeUseRemoteAccount: true }, assembly: 'dual', removeOldLinked: false, }; @@ -874,9 +858,7 @@ describe('LinkService', () => { password, reset: false, preset: Preset.testnet, - customPresetObject: { - nodeUseRemoteAccount: false, - }, + customPresetObject: { lastKnownNetworkEpoch: 235, nodeUseRemoteAccount: false }, assembly: 'dual', }; @@ -906,9 +888,7 @@ describe('LinkService', () => { password, reset: false, preset: Preset.testnet, - customPresetObject: { - nodeUseRemoteAccount: true, - }, + customPresetObject: { lastKnownNetworkEpoch: 235, nodeUseRemoteAccount: true }, assembly: 'api', }; const { addresses, presetData } = await new BootstrapService().config(params); @@ -938,9 +918,7 @@ describe('LinkService', () => { reset: true, preset: Preset.testnet, customPreset: './test/unit-test-profiles/voting_preset.yml', - customPresetObject: { - nodeUseRemoteAccount: true, - }, + customPresetObject: { lastKnownNetworkEpoch: 235, nodeUseRemoteAccount: true }, assembly: 'api', }; const { addresses, presetData } = await new BootstrapService().config(params); @@ -952,6 +930,7 @@ describe('LinkService', () => { deadline: Deadline.create(1), nodeAccount: nodeAccount, maxFee: maxFee, + latestFinalizedBlockEpoch: 235, mainAccountInfo: notLinkedAccountInfo, }; diff --git a/test/service/ModifyMultisigService.test.ts b/test/service/ModifyMultisigService.test.ts new file mode 100644 index 000000000..4d7099186 --- /dev/null +++ b/test/service/ModifyMultisigService.test.ts @@ -0,0 +1,216 @@ +import { expect } from 'chai'; +import { restore, stub } from 'sinon'; +import { Account, Deadline, MultisigAccountModificationTransaction, NetworkType, TransactionType, UInt64 } from 'symbol-sdk'; +import { ConfigPreset } from '../../src/model'; +import { TransactionFactoryParams } from '../../src/service'; +import { ModifyMultisigParams, ModifyMultisigService } from '../../src/service/ModifyMultisigService'; +import { TransactionUtils } from '../../src/service/TransactionUtils'; +import { StdUtils } from '../utils/StdUtils'; + +describe('ModifyMultisigService', () => { + let modifyMultisigService: ModifyMultisigService; + + afterEach(restore); + + const url = 'http://localhost:3000'; + const target = 'target/tests/testnet-dual'; + const useKnownRestGateways = false; + const networkType = NetworkType.TEST_NET; + const maxFee = UInt64.fromUint(2_000_000); + const mainAccount = Account.createFromPrivateKey('CA82E7ADAF7AB729A5462A1BD5AA78632390634904A64EB1BB22295E2E1A1BDD', networkType); + const presetData = ({ networkType, useKnownRestGateways } as unknown) as ConfigPreset; + const deadline = Deadline.create(1_616_694_977); + + const cosigner1 = Account.createFromPrivateKey('41C0163B6A057A4E7B6264AC5BB36C44E0245F8552242BF6A163617C4D616ED3', networkType); + const cosigner2 = Account.createFromPrivateKey('2FBDC1419F22BC049F6E869B144778277C5930D8D07D55E99ADD2282399FDCF5', networkType); + + const commonStub = async ( + addressAdditions?: string, + addressDeletions?: string, + minApprovalDelta?: number, + minRemovalDelta?: number, + multisigAccount?: any, + ): Promise => { + const params: ModifyMultisigParams = { + target, + url, + useKnownRestGateways, + addressAdditions, + addressDeletions, + minApprovalDelta, + minRemovalDelta, + }; + modifyMultisigService = new ModifyMultisigService(params); + stub(TransactionUtils, 'getRepositoryFactory'); + stub(TransactionUtils, 'getMultisigAccount').returns(Promise.resolve(multisigAccount)); + const transactionFactoryParams = { + presetData, + deadline, + maxFee, + mainAccount: mainAccount.publicAccount, + } as TransactionFactoryParams; + const transactions = await modifyMultisigService.createTransactions(transactionFactoryParams); + return transactions[0] as MultisigAccountModificationTransaction; + }; + + it('Converts regular account to multisig, adding single cosignatory', async () => { + StdUtils.in(['\n']); // for addressDeletions + + const tx = await commonStub(cosigner1.address.plain(), undefined, 1, 1, undefined); + + expect(tx.type).to.be.eq(TransactionType.MULTISIG_ACCOUNT_MODIFICATION); + expect(tx.addressAdditions.length).to.be.eq(1); + expect(tx.addressDeletions.length).to.be.eq(0); + expect(tx.minRemovalDelta).to.be.eq(1); + expect(tx.minApprovalDelta).to.be.eq(1); + }); + + it('Converts regular account to multisig, adding multiple cosignatories', async () => { + StdUtils.in(['\n']); // for addressDeletions + + const tx = await commonStub([cosigner1, cosigner2].map((c) => c.address.plain()).join(','), undefined, 1, 1, undefined); + + expect(tx.type).to.be.eq(TransactionType.MULTISIG_ACCOUNT_MODIFICATION); + expect(tx.addressAdditions.length).to.be.eq(2); + expect(tx.addressDeletions.length).to.be.eq(0); + expect(tx.minRemovalDelta).to.be.eq(1); + expect(tx.minApprovalDelta).to.be.eq(1); + }); + + it('Adds another cosignatory to the current multisig account', async () => { + StdUtils.in(['\n']); // for addressDeletions + + const tx = await commonStub(cosigner2.address.plain(), undefined, 1, 1, { + minApproval: 1, + minRemoval: 1, + cosignatoryAddresses: [cosigner1.address], + }); + + expect(tx.type).to.be.eq(TransactionType.MULTISIG_ACCOUNT_MODIFICATION); + expect(tx.addressAdditions.length).to.be.eq(1); + expect(tx.minRemovalDelta).to.be.eq(1); + expect(tx.minApprovalDelta).to.be.eq(1); + }); + + it('Removes a cosignatory from the current multisig account', async () => { + StdUtils.in(['\n']); // for addressAdditions + + const tx = await commonStub(undefined, cosigner1.address.plain(), -1, -1, { + minApproval: 1, + minRemoval: 1, + cosignatoryAddresses: [cosigner1.address], + }); + + expect(tx.type).to.be.eq(TransactionType.MULTISIG_ACCOUNT_MODIFICATION); + expect(tx.addressDeletions.length).to.be.eq(1); + expect(tx.addressAdditions.length).to.be.eq(0); + expect(tx.minRemovalDelta).to.be.eq(-1); + expect(tx.minApprovalDelta).to.be.eq(-1); + }); + + it('Modifies minApproval and minRemoval of the current multisig account with prompt for the address additions/deletions', async () => { + StdUtils.in(['\n', '\n']); // for addressDeletions, addressAdditions + + const tx = await commonStub(undefined, undefined, -1, -1, { + minApproval: 2, + minRemoval: 2, + cosignatoryAddresses: [cosigner1.address], + }); + + expect(tx.type).to.be.eq(TransactionType.MULTISIG_ACCOUNT_MODIFICATION); + expect(tx.addressAdditions.length).to.be.eq(0); + expect(tx.addressDeletions.length).to.be.eq(0); + expect(tx.minRemovalDelta).to.be.eq(-1); + expect(tx.minApprovalDelta).to.be.eq(-1); + }); + + it('Modifies minApproval and minRemoval of the current multisig account with no prompts', async () => { + const tx = await commonStub('', '', -1, -1, { + minApproval: 2, + minRemoval: 2, + cosignatoryAddresses: [cosigner1.address], + }); + + expect(tx.type).to.be.eq(TransactionType.MULTISIG_ACCOUNT_MODIFICATION); + expect(tx.addressAdditions.length).to.be.eq(0); + expect(tx.addressDeletions.length).to.be.eq(0); + expect(tx.minRemovalDelta).to.be.eq(-1); + expect(tx.minApprovalDelta).to.be.eq(-1); + }); + + it('Throws error when new minApproval is larger than the total number of cosignatories ', async () => { + StdUtils.in(['\n']); // for addressDeletions + + try { + await commonStub(cosigner2.address.plain(), undefined, 1, 1, { + minApproval: 3, + minRemoval: 1, + cosignatoryAddresses: [cosigner1.address], + }); + } catch (err) { + expect(err.message).to.be.eq( + 'There are 2 more required cosignatories than available cosignatories for min. approval. Please add cosignatories or reduce the min. approval delta.', + ); + } + }); + + it('Throws error when new minRemoval is larger than the total number of cosignatories ', async () => { + StdUtils.in(['\n']); // for addressDeletions + + try { + await commonStub(cosigner2.address.plain(), undefined, 1, 1, { + minApproval: 1, + minRemoval: 3, + cosignatoryAddresses: [cosigner1.address], + }); + } catch (err) { + expect(err.message).to.be.eq( + 'There are 2 more required cosignatories than available cosignatories for min removal. Please add cosignatories or reduce the min. removal delta.', + ); + } + }); + + it('Throws error when new minApproval is 0 when there are cosignatories in the account', async () => { + StdUtils.in(['\n', '\n']); // for addressDeletions, addressAdditions + + try { + await commonStub(undefined, undefined, -1, -1, { + minApproval: 1, + minRemoval: 1, + cosignatoryAddresses: [cosigner1.address], + }); + } catch (err) { + expect(err.message).to.be.eq( + 'Minimum approval and/or minimum removal cannot be set to 0 while there are 1 cosignatories in your list.', + ); + } + }); + + it('Throws error while cosignatory to be added already a cosignatory.', async () => { + StdUtils.in(['\n']); // for addressDeletions, addressAdditions + + try { + await commonStub(cosigner1.address.plain(), undefined, -1, -1, { + minApproval: 1, + minRemoval: 1, + cosignatoryAddresses: [cosigner1.address], + }); + } catch (err) { + expect(err.message.startsWith('Cannot add cosignatory!')).to.be.true; + } + }); + + it('Throws error while cosignatory to be removed is not an actual cosignatory.', async () => { + StdUtils.in(['\n', '\n']); // for addressDeletions, addressAdditions + + try { + await commonStub(undefined, cosigner2.address.plain(), -1, -1, { + minApproval: 1, + minRemoval: 1, + cosignatoryAddresses: [cosigner1.address], + }); + } catch (err) { + expect(err.message.startsWith('Cannot remove cosignatory!')).to.be.true; + } + }); +}); diff --git a/test/service/NetworkPresetUpgrade.test.ts b/test/service/NetworkPresetUpgrade.test.ts index 77a246a85..878e9b3ab 100644 --- a/test/service/NetworkPresetUpgrade.test.ts +++ b/test/service/NetworkPresetUpgrade.test.ts @@ -14,21 +14,26 @@ * limitations under the License. */ import { it } from 'mocha'; +import { join } from 'path'; import { ConfigPreset } from '../../src/model'; -import { BootstrapUtils, Preset, RemoteNodeService } from '../../src/service'; +import { BootstrapUtils, ConfigLoader, Preset, RemoteNodeService } from '../../src/service'; describe('NetworkPresetUpgrade', () => { const patchNetworkPreset = async (preset: Preset): Promise => { const root = './'; - const presetLocation = `${root}/presets/${preset}/network.yml`; - const networkPreset: ConfigPreset = BootstrapUtils.loadYaml(presetLocation, false); - - const epoch = await new RemoteNodeService().getBestFinalizationEpoch(networkPreset.knownRestGateways); + const networkPresetLocation = `${root}/presets/${preset}/network.yml`; + const sharedPresetLocation = join(root, 'presets', 'shared.yml'); + const sharedPreset = BootstrapUtils.loadYaml(sharedPresetLocation, false); + const networkPreset = BootstrapUtils.loadYaml(networkPresetLocation, false); + const configPreset: ConfigPreset = new ConfigLoader().mergePresets(sharedPreset, networkPreset); + const remoteNodeService = new RemoteNodeService(configPreset, false); + const urls = await remoteNodeService.getRestUrls(); + const epoch = await remoteNodeService.getBestFinalizationEpoch(urls); if (!epoch) { throw new Error('Epoch could not be resolved!!'); } networkPreset.lastKnownNetworkEpoch = epoch; - await BootstrapUtils.writeYaml(presetLocation, networkPreset, undefined); + await BootstrapUtils.writeYaml(networkPresetLocation, networkPreset, undefined); }; it('should patch testnet lastKnownNetworkEpoch', () => { return patchNetworkPreset(Preset.testnet); diff --git a/test/service/RemoteNodeService.test.ts b/test/service/RemoteNodeService.test.ts new file mode 100644 index 000000000..3cdac5560 --- /dev/null +++ b/test/service/RemoteNodeService.test.ts @@ -0,0 +1,556 @@ +/* + * Copyright 2020 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { expect } from 'chai'; +import 'mocha'; +import { it } from 'mocha'; +import { join } from 'path'; +import { restore, stub } from 'sinon'; +import { NodeApi } from 'symbol-statistics-service-typescript-fetch-client'; +import { ConfigPreset } from '../../src'; +import { BootstrapUtils, ConfigLoader, Preset, RemoteNodeService } from '../../src/service'; + +const list = [ + { + peerStatus: { + isAvailable: true, + lastStatusCheck: 1635710986117, + }, + apiStatus: { + restGatewayUrl: 'https://dual-001.testnet.symbol.dev:3001', + isAvailable: true, + lastStatusCheck: 1635710986145, + nodeStatus: { + apiNode: 'up', + db: 'up', + }, + isHttpsEnabled: true, + nodePublicKey: 'A2160AB911943082C88109DD8B65A0082EF547CA7C28F001F857112F7ADD9B3D', + chainHeight: 517611, + finalization: { + height: 517596, + epoch: 720, + point: 43, + hash: 'FD462D4133EEEC56471AAE18A6A2A3065DF69394A849D51F20286E189C46E4F5', + }, + restVersion: '2.3.8-alpha', + }, + _id: '617ef846196f2900128bb55c', + version: 16777728, + publicKey: 'E3FC28889BDE31406465167F1D9D6A16DCA1FF67A3BABFA5E5A8596478848F78', + networkGenerationHashSeed: '3B5E1FA6445653C971A50687E75E6D09FB30481055E3990C84B25E9222DC1155', + roles: 3, + port: 7900, + networkIdentifier: 152, + host: 'dual-001.testnet.symbol.dev', + friendlyName: 'dual-001', + hostDetail: { + host: 'dual-001.testnet.symbol.dev', + coordinates: { + latitude: 39.0438, + longitude: -77.4874, + }, + location: 'Ashburn, VA, United States', + ip: '3.86.56.197', + organization: 'AWS EC2 (us-east-1)', + as: 'AS14618 Amazon.com, Inc.', + continent: 'North America', + country: 'United States', + region: 'VA', + city: 'Ashburn', + district: '', + zip: '20149', + }, + __v: 0, + }, + { + peerStatus: { + isAvailable: true, + lastStatusCheck: 1635710986215, + }, + apiStatus: { + restGatewayUrl: 'https://sym-test-06.opening-line.jp:3001', + isAvailable: true, + lastStatusCheck: 1635710986858, + nodeStatus: { + apiNode: 'up', + db: 'up', + }, + isHttpsEnabled: true, + nodePublicKey: '50F34D96117E020BBB48C81C719A020C40729BF3D48483751D6CA8198FFB52C9', + chainHeight: 517611, + finalization: { + height: 517596, + epoch: 720, + point: 43, + hash: 'FD462D4133EEEC56471AAE18A6A2A3065DF69394A849D51F20286E189C46E4F5', + }, + restVersion: '2.3.6', + }, + _id: '617ef846196f2900128bb55d', + version: 16777728, + publicKey: '4675E1626A35EF8B9537486D93BB6B488960712A653CB62D27404D35E92F53A9', + networkGenerationHashSeed: '3B5E1FA6445653C971A50687E75E6D09FB30481055E3990C84B25E9222DC1155', + roles: 3, + port: 7900, + networkIdentifier: 152, + host: 'sym-test-06.opening-line.jp', + friendlyName: 'sym-test-06.opening-line.jp', + hostDetail: { + host: 'sym-test-06.opening-line.jp', + coordinates: { + latitude: 54.7091, + longitude: 25.2971, + }, + location: 'Vilnius, VL, Lithuania', + ip: '80.209.226.245', + organization: 'RACKRAY', + as: 'AS212531 Interneto vizija', + continent: 'Europe', + country: 'Lithuania', + region: 'VL', + city: 'Vilnius', + district: '', + zip: '08234', + }, + __v: 0, + }, + { + peerStatus: { + isAvailable: true, + lastStatusCheck: 1635710986325, + }, + _id: '617ef846196f2900128bb55e', + version: 16777728, + publicKey: '2489946E49B03D9BE040E3FD42FEBC705D001A746BD25399E2796D615B35B732', + networkGenerationHashSeed: '3B5E1FA6445653C971A50687E75E6D09FB30481055E3990C84B25E9222DC1155', + roles: 5, + port: 7900, + networkIdentifier: 152, + host: 'peer-601.testnet.symbol.dev', + friendlyName: 'peer-601', + hostDetail: { + host: 'peer-601.testnet.symbol.dev', + coordinates: { + latitude: 1.28009, + longitude: 103.851, + }, + location: 'Singapore, , Singapore', + ip: '54.179.53.6', + organization: 'AWS EC2 (ap-southeast-1)', + as: 'AS16509 Amazon.com, Inc.', + continent: 'Asia', + country: 'Singapore', + region: '', + city: 'Singapore', + district: '', + zip: '', + }, + __v: 0, + }, + { + peerStatus: { + isAvailable: true, + lastStatusCheck: 1635710986299, + }, + apiStatus: { + restGatewayUrl: 'http://AMATERASU.symbol-node.com:3000', + isAvailable: true, + lastStatusCheck: 1635710987216, + nodeStatus: { + apiNode: 'up', + db: 'up', + }, + isHttpsEnabled: false, + nodePublicKey: 'B46268513DDCC2A74241E11F2A38F2FCC6CB655E7CBBD95DA6B32266B5CA88ED', + chainHeight: 517611, + finalization: { + height: 517596, + epoch: 720, + point: 43, + hash: 'FD462D4133EEEC56471AAE18A6A2A3065DF69394A849D51F20286E189C46E4F5', + }, + restVersion: '2.3.6', + }, + _id: '617ef846196f2900128bb55f', + version: 16777728, + publicKey: 'DB14A11E28CA1EF8BC45657BA3FF0879946A57D8F7370C585819365521C6449C', + networkGenerationHashSeed: '3B5E1FA6445653C971A50687E75E6D09FB30481055E3990C84B25E9222DC1155', + roles: 3, + port: 7900, + networkIdentifier: 152, + host: 'AMATERASU.symbol-node.com', + friendlyName: 'AMATERASU.symbol-node.com(TEST)', + hostDetail: { + host: 'AMATERASU.symbol-node.com', + coordinates: { + latitude: 34.6866, + longitude: 135.8548, + }, + location: 'Nara, 29, Japan', + ip: '58.70.54.55', + organization: 'OPTAGE Inc.', + as: 'AS17511 OPTAGE Inc.', + continent: 'Asia', + country: 'Japan', + region: '29', + city: 'Nara', + district: '', + zip: '630-8211', + }, + __v: 0, + }, + { + peerStatus: { + isAvailable: true, + lastStatusCheck: 1635710986193, + }, + apiStatus: { + restGatewayUrl: 'https://iroha-symbolnode.com:3001', + isAvailable: true, + lastStatusCheck: 1635710986698, + nodeStatus: { + apiNode: 'up', + db: 'up', + }, + isHttpsEnabled: true, + nodePublicKey: '01438DDE96FD4816726F8B80CC012DC85FED6CDA45F9B932887A3512593CFA51', + chainHeight: 517611, + finalization: { + height: 517596, + epoch: 720, + point: 43, + hash: 'FD462D4133EEEC56471AAE18A6A2A3065DF69394A849D51F20286E189C46E4F5', + }, + restVersion: '2.3.6', + }, + _id: '617ef846196f2900128bb560', + version: 16777728, + publicKey: '26BEC23EF633936BAB5E501F03E0C374036F5FF20AC068972839357851411496', + networkGenerationHashSeed: '3B5E1FA6445653C971A50687E75E6D09FB30481055E3990C84B25E9222DC1155', + roles: 3, + port: 7900, + networkIdentifier: 152, + host: 'iroha-symbolnode.com', + friendlyName: '168nihoheto_VDS_S', + hostDetail: { + host: 'iroha-symbolnode.com', + coordinates: { + latitude: 47.6034, + longitude: -122.3414, + }, + location: 'Seattle, WA, United States', + ip: '66.94.122.36', + organization: 'Contabo Inc', + as: 'AS40021 Contabo Inc.', + continent: 'North America', + country: 'United States', + region: 'WA', + city: 'Seattle', + district: '', + zip: '98111', + }, + __v: 0, + }, + { + peerStatus: { + isAvailable: true, + lastStatusCheck: 1635710986174, + }, + apiStatus: { + restGatewayUrl: 'https://dual-101.testnet.symbol.dev:3001', + isAvailable: true, + lastStatusCheck: 1635710986567, + nodeStatus: { + apiNode: 'up', + db: 'up', + }, + isHttpsEnabled: true, + nodePublicKey: 'F81F749613EF3BC10BB9670A6FAF49BFA95079898E2034255B8256FBA3FD105D', + chainHeight: 517611, + finalization: { + height: 517596, + epoch: 720, + point: 43, + hash: 'FD462D4133EEEC56471AAE18A6A2A3065DF69394A849D51F20286E189C46E4F5', + }, + restVersion: '2.3.8-alpha', + }, + _id: '617ef846196f2900128bb561', + version: 16777728, + publicKey: 'C4348215B4C417D3E4B52ACAA3D370D29DE3A5F482CAED3C9F1BE257DD2B4079', + networkGenerationHashSeed: '3B5E1FA6445653C971A50687E75E6D09FB30481055E3990C84B25E9222DC1155', + roles: 3, + port: 7900, + networkIdentifier: 152, + host: 'dual-101.testnet.symbol.dev', + friendlyName: 'dual-101', + hostDetail: { + host: 'dual-101.testnet.symbol.dev', + coordinates: { + latitude: 37.3394, + longitude: -121.895, + }, + location: 'San Jose, CA, United States', + ip: '54.151.52.226', + organization: 'AWS EC2 (us-west-1)', + as: 'AS16509 Amazon.com, Inc.', + continent: 'North America', + country: 'United States', + region: 'CA', + city: 'San Jose', + district: '', + zip: '95141', + }, + __v: 0, + }, + { + peerStatus: { + isAvailable: true, + lastStatusCheck: 1635710986181, + }, + _id: '617ef846196f2900128bb565', + version: 16777728, + publicKey: 'DC7A90D0676DB3A2D963768276F606AF76541A59588B23C6C6B48D98E0AC3837', + networkGenerationHashSeed: '3B5E1FA6445653C971A50687E75E6D09FB30481055E3990C84B25E9222DC1155', + roles: 1, + port: 7900, + networkIdentifier: 152, + host: 'peer-301.testnet.symbol.dev', + friendlyName: 'peer-301', + hostDetail: { + host: 'peer-301.testnet.symbol.dev', + coordinates: { + latitude: 53.3498, + longitude: -6.26031, + }, + location: 'Dublin, L, Ireland', + ip: '54.77.189.25', + organization: 'AWS EC2 (eu-west-1)', + as: 'AS16509 Amazon.com, Inc.', + continent: 'Europe', + country: 'Ireland', + region: 'L', + city: 'Dublin', + district: '', + zip: 'D02', + }, + __v: 0, + }, + { + peerStatus: { + isAvailable: true, + lastStatusCheck: 1635710986140, + }, + apiStatus: { + restGatewayUrl: 'https://sym-test-02.opening-line.jp:3001', + isAvailable: true, + lastStatusCheck: 1635710986329, + nodeStatus: { + apiNode: 'up', + db: 'up', + }, + isHttpsEnabled: true, + nodePublicKey: '81448301A61412CE24F679C67136CF56DF43216EEAB3065677AA4ECFD0441B59', + chainHeight: 517611, + finalization: { + height: 517596, + epoch: 720, + point: 43, + hash: 'FD462D4133EEEC56471AAE18A6A2A3065DF69394A849D51F20286E189C46E4F5', + }, + restVersion: '2.3.6', + }, + _id: '617ef846196f2900128bb567', + version: 16777728, + publicKey: '97A7D1E1889803D4A5E3F372530EB555C495B23012807E3E94EF15A2205BC3A6', + networkGenerationHashSeed: '3B5E1FA6445653C971A50687E75E6D09FB30481055E3990C84B25E9222DC1155', + roles: 3, + port: 7900, + networkIdentifier: 152, + host: 'sym-test-02.opening-line.jp', + friendlyName: 'sym-test-02.opening-line.jp', + hostDetail: { + host: 'sym-test-02.opening-line.jp', + coordinates: { + latitude: 38.6327, + longitude: -90.1956, + }, + location: 'St Louis, MO, United States', + ip: '209.145.59.225', + organization: 'Contabo Inc', + as: 'AS40021 Contabo Inc.', + continent: 'North America', + country: 'United States', + region: 'MO', + city: 'St Louis', + district: 'Downtown', + zip: '63101', + }, + __v: 0, + }, +]; +const customPresetObject = { + lastKnownNetworkEpoch: 1, + nodeUseRemoteAccount: true, + nodes: [ + { + mainPrivateKey: 'CA82E7ADAF7AB729A5462A1BD5AA78632390634904A64EB1BB22295E2E1A1BDD', + friendlyName: 'myFriendlyName', + }, + ], + knownRestGateways: ['http://staticRest1:3000', 'https://staticRest2:3001'], + knownPeers: [ + { + publicKey: 'AAAAE7EAEEAE61EF0C50B4D05931F4325F69081B1B074D31E094C4B21E8CFB3D', + endpoint: { host: 'someStaticPeer', port: 7900 }, + metadata: { name: 'someStaticPeer', roles: 'Peer,Api' }, + }, + ], +}; +const preset = Preset.testnet; +const root = './'; +const networkPresetLocation = `${root}/presets/${preset}/network.yml`; +const sharedPresetLocation = join(root, 'presets', 'shared.yml'); +const sharedPreset = BootstrapUtils.loadYaml(sharedPresetLocation, false); +const networkPreset = BootstrapUtils.loadYaml(networkPresetLocation, false); +const presetData: ConfigPreset = new ConfigLoader().mergePresets(sharedPreset, networkPreset, customPresetObject); + +describe('RemoteNodeService', () => { + afterEach(restore); + it('getRestUrls online', async () => { + stub(RemoteNodeService.prototype, 'createNodeApiRestClient').callsFake(() => { + return ({ + getNodes(filter: NodeFilter, limit: number) { + expect(filter).eq(presetData.statisticsServiceRestFilter); + expect(limit).eq(presetData.statisticsServiceRestLimit); + return list; + }, + } as unknown) as NodeApi; + }); + + const service = new RemoteNodeService(presetData, false); + const urls = await service.getRestUrls(); + expect(urls).deep.eq([ + 'http://staticRest1:3000', + 'https://staticRest2:3001', + 'https://dual-001.testnet.symbol.dev:3001', + 'https://sym-test-06.opening-line.jp:3001', + 'http://AMATERASU.symbol-node.com:3000', + 'https://iroha-symbolnode.com:3001', + 'https://dual-101.testnet.symbol.dev:3001', + 'https://sym-test-02.opening-line.jp:3001', + ]); + }); + it('getRestUrls offline', async () => { + stub(RemoteNodeService.prototype, 'createNodeApiRestClient').callsFake(() => { + return ({ + getNodes(filter: NodeFilter, limit: number) { + expect(filter).eq(presetData.statisticsServiceRestFilter); + expect(limit).eq(presetData.statisticsServiceRestLimit); + return list; + }, + } as unknown) as NodeApi; + }); + + const service = new RemoteNodeService(presetData, true); + const urls = await service.getRestUrls(); + expect(urls).deep.eq(['http://staticRest1:3000', 'https://staticRest2:3001']); + }); + it('getPeerInfos online', async () => { + stub(RemoteNodeService.prototype, 'createNodeApiRestClient').callsFake(() => { + return ({ + getNodes(filter: NodeFilter, limit: number) { + expect(presetData.statisticsServicePeerFilter).eq(''); + expect(filter).eq(undefined); + expect(limit).eq(presetData.statisticsServicePeerLimit); + return list; + }, + } as unknown) as NodeApi; + }); + + const service = new RemoteNodeService(presetData, false); + const peerInfos = await service.getPeerInfos(); + expect(peerInfos).deep.eq([ + { + publicKey: 'AAAAE7EAEEAE61EF0C50B4D05931F4325F69081B1B074D31E094C4B21E8CFB3D', + endpoint: { host: 'someStaticPeer', port: 7900 }, + metadata: { name: 'someStaticPeer', roles: 'Peer,Api' }, + }, + { + publicKey: 'E3FC28889BDE31406465167F1D9D6A16DCA1FF67A3BABFA5E5A8596478848F78', + endpoint: { host: 'dual-001.testnet.symbol.dev', port: 7900 }, + metadata: { name: 'dual-001', roles: 'Peer,Api' }, + }, + { + publicKey: '4675E1626A35EF8B9537486D93BB6B488960712A653CB62D27404D35E92F53A9', + endpoint: { host: 'sym-test-06.opening-line.jp', port: 7900 }, + metadata: { name: 'sym-test-06.opening-line.jp', roles: 'Peer,Api' }, + }, + { + publicKey: '2489946E49B03D9BE040E3FD42FEBC705D001A746BD25399E2796D615B35B732', + endpoint: { host: 'peer-601.testnet.symbol.dev', port: 7900 }, + metadata: { name: 'peer-601', roles: 'Peer,Voting' }, + }, + { + publicKey: 'DB14A11E28CA1EF8BC45657BA3FF0879946A57D8F7370C585819365521C6449C', + endpoint: { host: 'AMATERASU.symbol-node.com', port: 7900 }, + metadata: { name: 'AMATERASU.symbol-node.com(TEST)', roles: 'Peer,Api' }, + }, + { + publicKey: '26BEC23EF633936BAB5E501F03E0C374036F5FF20AC068972839357851411496', + endpoint: { host: 'iroha-symbolnode.com', port: 7900 }, + metadata: { name: '168nihoheto_VDS_S', roles: 'Peer,Api' }, + }, + { + publicKey: 'C4348215B4C417D3E4B52ACAA3D370D29DE3A5F482CAED3C9F1BE257DD2B4079', + endpoint: { host: 'dual-101.testnet.symbol.dev', port: 7900 }, + metadata: { name: 'dual-101', roles: 'Peer,Api' }, + }, + { + publicKey: 'DC7A90D0676DB3A2D963768276F606AF76541A59588B23C6C6B48D98E0AC3837', + endpoint: { host: 'peer-301.testnet.symbol.dev', port: 7900 }, + metadata: { name: 'peer-301', roles: 'Peer' }, + }, + { + publicKey: '97A7D1E1889803D4A5E3F372530EB555C495B23012807E3E94EF15A2205BC3A6', + endpoint: { host: 'sym-test-02.opening-line.jp', port: 7900 }, + metadata: { name: 'sym-test-02.opening-line.jp', roles: 'Peer,Api' }, + }, + ]); + }); + it('getPeerInfos offline', async () => { + stub(RemoteNodeService.prototype, 'createNodeApiRestClient').callsFake(() => { + return ({ + getNodes(filter: NodeFilter, limit: number) { + expect(filter).eq(presetData.statisticsServicePeerFilter); + expect(limit).eq(presetData.statisticsServicePeerLimit); + return list; + }, + } as unknown) as NodeApi; + }); + + const service = new RemoteNodeService(presetData, true); + const peerInfos = await service.getPeerInfos(); + expect(peerInfos).deep.eq([ + { + publicKey: 'AAAAE7EAEEAE61EF0C50B4D05931F4325F69081B1B074D31E094C4B21E8CFB3D', + endpoint: { host: 'someStaticPeer', port: 7900 }, + metadata: { name: 'someStaticPeer', roles: 'Peer,Api' }, + }, + ]); + }); +}); diff --git a/test/service/RewardProgramService.test.ts b/test/service/RewardProgramService.test.ts deleted file mode 100644 index 8799e91ac..000000000 --- a/test/service/RewardProgramService.test.ts +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2020 NEM - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { expect } from '@oclif/test'; -import 'mocha'; -import { Deadline, TransactionType, TransferTransaction, UInt64 } from 'symbol-sdk'; -import { BootstrapService, ConfigService, LinkService, Preset } from '../../src/service'; -import { RewardProgram, RewardProgramService, RewardProgramServiceTransactionFactoryParams } from '../../src/service/RewardProgramService'; - -const password = '1234'; -describe('RewardProgramService', () => { - it('getRewardProgram', async () => { - expect(RewardProgramService.getRewardProgram('ecosystem')).eq(RewardProgram.Ecosystem); - expect(RewardProgramService.getRewardProgram('Ecosystem')).eq(RewardProgram.Ecosystem); - expect(RewardProgramService.getRewardProgram('superNODE')).eq(RewardProgram.SuperNode); - expect(RewardProgramService.getRewardProgram('earlyAdoption')).eq(RewardProgram.EarlyAdoption); - try { - RewardProgramService.getRewardProgram('NA'); - expect(1).eq(0); - } catch (e) { - expect(e.message).eq('NA is not a valid Reward program. Please use one of EarlyAdoption, Ecosystem, SuperNode, MonitorOnly'); - } - }); - - it('RewardProgramService create transactions when supernode', async () => { - const params = { - ...ConfigService.defaultParams, - ...LinkService.defaultParams, - target: 'target/tests/testnet-supernode', - password, - reset: false, - preset: Preset.testnet, - customPreset: './test/unit-test-profiles/supernode.yml', - customPresetObject: { - nodeUseRemoteAccount: true, - }, - assembly: 'dual', - }; - const { addresses, presetData } = await new BootstrapService('.').config(params); - const maxFee = UInt64.fromUint(10); - const nodeAccount = addresses.nodes![0]; - const nodePreset = presetData.nodes![0]; - const transactionFactoryParams: RewardProgramServiceTransactionFactoryParams = { - presetData, - deadline: Deadline.create(1), - nodePreset: nodePreset, - nodeAccount: nodeAccount, - maxFee: maxFee, - }; - - const transactions = await new RewardProgramService(params).createTransactions(transactionFactoryParams); - expect(transactions.length).eq(1); - const transaction = transactions[0] as TransferTransaction; - expect(transaction.type).eq(TransactionType.TRANSFER); - expect(transaction.message.payload).eq( - 'enroll https://fboucquez-agent-symbollocal.ngrok.io LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlHU01FWUNBUUF3RXpFUk1BOEdBMVVFQXd3SVFXZGxiblFnUTBFd0tqQUZCZ01yWlhBRElRQmtJVU1VTjJMSQpKMWcraW1TQW0zM3lkNDRVSlhWdjVkZi95Z0N6eGJVbUc2QUFNQVVHQXl0bGNBTkJBTncyWlIvQUtxUzlSblJWCnMzYWtZcXdHMnAzR0RTREQzVlU3VDFOSk9MWkdiU3g3alY2WnovS2ZzMGgvcEsyRmhvb2taL2oxeUxUQzgxdEkKZzR6MWFnWT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUgUkVRVUVTVC0tLS0tCg==', - ); - }); - - it('Supernode create transactions when dual + voting, not supernode', async () => { - const params = { - ...ConfigService.defaultParams, - ...LinkService.defaultParams, - target: 'target/tests/testnet-dual-voting', - password, - reset: false, - preset: Preset.testnet, - customPreset: './test/unit-test-profiles/voting_preset.yml', - customPresetObject: { - nodeUseRemoteAccount: true, - }, - assembly: 'dual', - }; - const { addresses, presetData } = await new BootstrapService('.').config(params); - const maxFee = UInt64.fromUint(10); - const nodeAccount = addresses.nodes![0]; - const nodePreset = presetData.nodes![0]; - const transactionFactoryParams: RewardProgramServiceTransactionFactoryParams = { - presetData, - deadline: Deadline.create(1), - nodePreset: nodePreset, - nodeAccount: nodeAccount, - maxFee: maxFee, - }; - - const transactions = await new RewardProgramService(params).createTransactions(transactionFactoryParams); - expect(transactions.length).eq(0); - }); -}); diff --git a/test/service/VerifyService.test.ts b/test/service/VerifyService.test.ts index 664dfc4de..caca7ea80 100644 --- a/test/service/VerifyService.test.ts +++ b/test/service/VerifyService.test.ts @@ -67,8 +67,8 @@ describe('VerifyService', () => { it('VerifyService verify current installation when too old', async () => { const expectedVersions = { node: '18.0.0', - docker: '19.4.0', - dockerCompose: '1.25.30', + docker: '21.4.0', + dockerCompose: '1.29.5', }; const service = new VerifyService(BootstrapUtils.resolveRootFolder(), expectedVersions); const currentDockerVersion = await service.loadVersionFromCommand('docker --version'); diff --git a/test/service/script.ts b/test/service/script.ts index be25aad7e..65842a92b 100644 --- a/test/service/script.ts +++ b/test/service/script.ts @@ -124,6 +124,7 @@ const example = async () => { return signedTransaction; }; + // eslint-disable-next-line @typescript-eslint/no-unused-vars const sendUnlink = async () => { const transferTransaction = AccountKeyLinkTransaction.create( deadline, diff --git a/test/supernode.yml b/test/supernode.yml deleted file mode 100644 index 1d021f4ff..000000000 --- a/test/supernode.yml +++ /dev/null @@ -1,20 +0,0 @@ -#privateKeySecurityMode: PROMPT_MAIN -nodeUseRemoteAccount: true -logLevel: 'Debug' -#lastKnownNetworkEpoch: 70 -votingKeyDesiredLifetime: 28 # create short voting key files, 28 is the minimun -#votingKeyDesiredFutureLifetime: 300 # create files for at least 60 epochs in the future, this will create voting key file 2 and file 3 -useExperimentalNativeVotingKeyGeneration: true # Use new native ts generation -symbolServerImage: symbolplatform/symbol-server-private:gcc-voting-key-unlink-rollback-f2633f4a4c -symbolRestImage: 'symbolplatform/symbol-rest:2.3.6-alpha' -nodes: - - voting: true - rewardProgram: 'supernode' - host: fboucquez-agent-symbollocal.ngrok.io - agentUrl: https://fboucquez-agent-symbollocal.ngrok.io - restGatewayUrl: http://fboucquez-rest-gateway-symbollocal.ngrok.io - mainPrivateKey: E095162875BB1D98CA5E0941670E01C1B0DBDF86DF7B3BEDA4A93635F8E51A03 - transportPrivateKey: 415F253ABF0FB2DFD39D7F409EFA2E88769873CAEB45617313B98657A1476A15 - remotePrivateKey: 24B485712045FEDA5782ECFF1752F63D41C134371BB46AC68EE6DC9183CF5061 - vrfPrivateKey: D34A231C860EB1B6E3A4F8366C8F0F6C7C2462A40263DCB67124FB76CDD4E368 - agentPrivateKey: AAAA231C860EB1B6E3A4F8366C8F0F6C7C2462A40263DCB67124FB76CDD4E368 diff --git a/test/unit-test-profiles/https-proxy.yml b/test/unit-test-profiles/https-proxy.yml new file mode 100644 index 000000000..2141153ac --- /dev/null +++ b/test/unit-test-profiles/https-proxy.yml @@ -0,0 +1,11 @@ +privateKeySecurityMode: PROMPT_MAIN_TRANSPORT +nodes: + - host: symbol-node-2.rockbear.io + voting: false + friendlyName: symbol-node-2.rockbear.io + mainPrivateKey: 36AB6EE63C77C59351C68285C981E2F7E00E0065FC408C67C550F54D2B265B96 + vrfPrivateKey: D7DCF460F26ABABD01E58A3F8AA02CFE6AC3A0DB16522BDD5F396D274620310A + remotePrivateKey: 08CFC6BD0ABADEBF5C41371353BB79D572122C4858EE1135184237F3BF8DFF5B + transportPrivateKey: A88098E203E3CBA75433361EF7F59B767A82CEB9766F7735F9BD6AE1B204021A +httpsProxies: + - excludeDockerService: false diff --git a/test/unit-test-profiles/native-ssl.yml b/test/unit-test-profiles/native-ssl.yml new file mode 100644 index 000000000..b004bdb24 --- /dev/null +++ b/test/unit-test-profiles/native-ssl.yml @@ -0,0 +1,16 @@ +privateKeySecurityMode: PROMPT_MAIN_TRANSPORT +nodes: + - host: symbol-node-2.rockbear.io + voting: false + friendlyName: symbol-node-2.rockbear.io + mainPrivateKey: 36AB6EE63C77C59351C68285C981E2F7E00E0065FC408C67C550F54D2B265B96 + vrfPrivateKey: D7DCF460F26ABABD01E58A3F8AA02CFE6AC3A0DB16522BDD5F396D274620310A + remotePrivateKey: 08CFC6BD0ABADEBF5C41371353BB79D572122C4858EE1135184237F3BF8DFF5B + transportPrivateKey: A88098E203E3CBA75433361EF7F59B767A82CEB9766F7735F9BD6AE1B204021A +gateways: + - restProtocol: HTTPS + openPort: 3001 + restSSLCertificateBase64: >- + LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNFakNDQVhzQ0FnMzZNQTBHQ1NxR1NJYjNEUUVCQlFVQU1JR2JNUXN3Q1FZRFZRUUdFd0pLVURFT01Bd0cKQTFVRUNCTUZWRzlyZVc4eEVEQU9CZ05WQkFjVEIwTm9kVzh0YTNVeEVUQVBCZ05WQkFvVENFWnlZVzVyTkVSRQpNUmd3RmdZRFZRUUxFdzlYWldKRFpYSjBJRk4xY0hCdmNuUXhHREFXQmdOVkJBTVREMFp5WVc1ck5FUkVJRmRsCllpQkRRVEVqTUNFR0NTcUdTSWIzRFFFSkFSWVVjM1Z3Y0c5eWRFQm1jbUZ1YXpSa1pDNWpiMjB3SGhjTk1USXcKT0RJeU1EVXlOalUwV2hjTk1UY3dPREl4TURVeU5qVTBXakJLTVFzd0NRWURWUVFHRXdKS1VERU9NQXdHQTFVRQpDQXdGVkc5cmVXOHhFVEFQQmdOVkJBb01DRVp5WVc1ck5FUkVNUmd3RmdZRFZRUUREQTkzZDNjdVpYaGhiWEJzClpTNWpiMjB3WERBTkJna3Foa2lHOXcwQkFRRUZBQU5MQURCSUFrRUFtL3hta0htRVFydXJFLzByZS9qZUZSTGwKOFpQakJvcDd1TEhobmlhN2xRRy81ekR0WklVQzNSVnBxRFN3QnV3L05Ud2VHeXVQK284QUc5OEh4cXhUQndJRApBUUFCTUEwR0NTcUdTSWIzRFFFQkJRVUFBNEdCQUJTMlRMdUJlVFBtY2FUYVVXL0xDQjJOWU95OEdNZHpSMW14CjhpQkl1Mkg2L0UydGlZM1JJZXZWMk9XNjFxWTIvWFJRZzdZUHh4M2ZmZVV1Z1g5RjRKL2lQbm51MXpBeHh5QnkKMlZndUt2NFNXalJGb1JrSWZJbEhYMHFWdmlNaFNsTnkyaW9GTHk3SmNQWmIrdjNmdERHeXdVcWNCaVZEb2VhMApIbitHbXhaQQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== + restSSLKeyBase64: >- + LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlCT3dJQkFBSkJBSnY4WnBCNWhFSzdxeFA5SzN2NDNoVVM1ZkdUNHdhS2U3aXg0WjRtdTVVQnYrY3c3V1NGCkF0MFZhYWcwc0Fic1B6VThIaHNyai9xUEFCdmZCOGFzVXdjQ0F3RUFBUUpBRzByM2V6SDM1V0ZHMXRHR2FVT3IKUUE2MWN5YUlJNTNaZGdDUjFJVThieDdBVWV2bWtGdEJmK2FxTVd1c1dWT1dKdkd1MnI1VnBIVkFJbDhuRjZEUwprUUloQU1qRUozelZZYTIvTW80ZXkraVU5SjlWZCtXb3lYRFFENEVFdHdteUcxUHBBaUVBeHVabHZoREliYmNlCjdvNUJ2T2huQ1oyTjdrWWIxWkM1N2czRitjYkp5VzhDSVFDYnNER0hCdG8ycUp5RnhiQU83dVE4WTBVVkhhMEoKQk8vZzkwMFNBY0piY1FJZ1J0RWxqSVNoT0I4cERqcnNRUHhtSTFCTGhuakQxRWhSU3Vid2hEdzVBRlVDSVFDTgpBMjRwRHRkT0h5ZHd0U0I1K3pGcUZMZm1WWnBsUU0vZzVrYjRzbzcwWXc9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo= diff --git a/test/unit-test-profiles/supernode.yml b/test/unit-test-profiles/supernode.yml deleted file mode 100644 index a3a21a147..000000000 --- a/test/unit-test-profiles/supernode.yml +++ /dev/null @@ -1,12 +0,0 @@ -privateKeySecurityMode: PROMPT_MAIN -nodes: - - voting: true - rewardProgram: 'supernode' - host: fboucquez-agent-symbollocal.ngrok.io - agentUrl: https://fboucquez-agent-symbollocal.ngrok.io - restGatewayUrl: http://fboucquez-rest-gateway-symbollocal.ngrok.io - mainPrivateKey: CA82E7ADAF7AB729A5462A1BD5AA78632390634904A64EB1BB22295E2E1A1BDD - transportPrivateKey: 6154154096354BC3DB522174ACD8BFE553893A0991BD5D105599846F17A3383B - remotePrivateKey: EFE3F0EF0AB368B8D7AC194D52A8CCFA2D5050B80B9C76E4D2F4D4BF2CD461C1 - vrfPrivateKey: F3C24C153783B683E40FB2671493B54480370BF4E3AB8027D4BF1293E14EB9B8 - agentPrivateKey: AAAA231C860EB1B6E3A4F8366C8F0F6C7C2462A40263DCB67124FB76CDD4E368 diff --git a/test/utils/StdUtils.ts b/test/utils/StdUtils.ts new file mode 100644 index 000000000..0c0096381 --- /dev/null +++ b/test/utils/StdUtils.ts @@ -0,0 +1,46 @@ +/* + * Copyright 2021 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { stdin } from 'mock-stdin'; + +export const StdUtils = { + keys: Object.freeze({ + up: '\u001b[A', + down: '\u001b[B', + left: '\u001b[D', + right: '\u001b[C', + }), + in: (responses: string[]): void => { + let k = 0; + + const s = stdin(); + function sendAnswer() { + setTimeout(function () { + const text = responses[k]; + if (typeof text !== 'string') { + throw new Error('Should give only text responses ' + JSON.stringify(responses, null, 2)); + } + s.send(text); + k += 1; + if (k < responses.length) { + sendAnswer(); + } + }, 0); + } + + sendAnswer(); + }, +};