├── .editorconfig ├── .github └── stale.yml ├── CODEOWNERS ├── LICENSE ├── Vagrantfile ├── app ├── app-core.sh ├── app-explorer.sh ├── args.sh ├── config-core.sh ├── process-core.sh ├── process-explorer.sh ├── update-core-relay.sh ├── update-core.sh └── var.sh ├── bootstrap ├── app.sh └── lib.sh ├── bridgechain.sh ├── config.sample.json ├── lib ├── alerts.sh ├── args.sh ├── dependencies.sh ├── errors.sh ├── manifest.sh ├── rtfm.sh └── utils.sh ├── manifest.json ├── packages └── js-deployer │ ├── bin │ └── deployer │ ├── lib │ ├── builder │ │ └── genesis-block.js │ ├── schema.js │ └── utils │ │ ├── get-random-number.js │ │ ├── logger.js │ │ ├── update-config.js │ │ └── write-env.js │ ├── package.json │ └── yarn.lock ├── prefixes.json ├── renovate.json ├── setup.sh └── vagrant ├── config.json └── setup.sh /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | indent_style = space 8 | indent_size = 4 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | 14 | [*.yml] 15 | indent_style = space 16 | indent_size = 2 17 | 18 | [deployer] 19 | indent_style = space 20 | indent_size = 2 21 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | _extends: .github 2 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @faustbrian @alexbarnsley @ItsANameToo 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Ark.io, Alex Barnsley , Brian Faust 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | Vagrant.configure("2") do |config| 2 | config.vm.box = "ubuntu/bionic64" 3 | config.vm.box_version = ">= 20190212.1.0" 4 | config.vm.network "private_network", ip: "192.168.33.10" 5 | config.vm.provider "virtualbox" do |vb| 6 | vb.memory = "2048" 7 | vb.cpus = 2 8 | end 9 | config.vm.provision "shell", path: "vagrant/setup.sh", privileged: false 10 | end 11 | -------------------------------------------------------------------------------- /app/app-core.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | app_install_core() 4 | { 5 | parse_core_args "$@" 6 | install_dependencies 7 | app_uninstall_core "$@" 8 | 9 | heading "Installing Core to $BRIDGECHAIN_PATH..." 10 | cd ~ 11 | 12 | local CONFIG_PATH_MAINNET="$HOME/.bridgechain/mainnet/$CHAIN_NAME" 13 | local CONFIG_PATH_DEVNET="$HOME/.bridgechain/devnet/$CHAIN_NAME" 14 | local CONFIG_PATH_TESTNET="$HOME/.bridgechain/testnet/$CHAIN_NAME" 15 | 16 | rm -rf "$HOME/.config/@${CORE_ALIAS}" 17 | rm -rf "$HOME/.config/@${CHAIN_NAME}" 18 | rm -rf "$HOME/.config/${CORE_ALIAS}-core" 19 | 20 | local MAINNET_PREFIX=$(sh -c "jq '.[\"$MAINNET_PREFIX\"]' $__dir/prefixes.json") 21 | if [[ -z "$MAINNET_PREFIX" ]]; then 22 | MAINNET_PREFIX=$(sh -c "jq '.M' $__dir/prefixes.json") 23 | fi 24 | local DEVNET_PREFIX=$(sh -c "jq '.[\"$DEVNET_PREFIX\"]' $__dir/prefixes.json") 25 | if [[ -z "$DEVNET_PREFIX" ]]; then 26 | DEVNET_PREFIX=$(sh -c "jq '.M' $__dir/prefixes.json") 27 | fi 28 | local TESTNET_PREFIX=$(sh -c "jq '.[\"$TESTNET_PREFIX\"]' $__dir/prefixes.json") 29 | if [[ -z "$TESTNET_PREFIX" ]]; then 30 | TESTNET_PREFIX=$(sh -c "jq '.M' $__dir/prefixes.json") 31 | fi 32 | 33 | ## Create local user for psql, remove if already exists 34 | OWNED_DATABASES=$(sudo -u postgres psql -c "\l" | fgrep " | $USER " | awk '{print $1}' | egrep "_(main|dev|test)net$") || true 35 | for OWNED_DATABASE in $OWNED_DATABASES; do 36 | sudo -u postgres dropdb "$OWNED_DATABASE" 37 | done 38 | sudo -u postgres psql -c "DROP OWNED BY $USER; DROP USER $USER" || true 39 | sudo -u postgres psql -c "CREATE USER $USER;" 40 | sudo -u postgres psql -c "ALTER USER $USER WITH SUPERUSER;" 41 | echo "Created local postgres user" 42 | 43 | local DATABASE_NAME_MAINNET="${DATABASE_NAME}_mainnet" 44 | local DATABASE_NAME_DEVNET="${DATABASE_NAME}_devnet" 45 | local DATABASE_NAME_TESTNET="${DATABASE_NAME}_testnet" 46 | 47 | local DB_EXISTS_MAINNET=$(psql -t -c "\l" postgres | fgrep "$DATABASE_NAME_MAINNET" | fgrep "|" | awk '{$1=$1};1' | awk '{print $1}') 48 | local DB_EXISTS_DEVNET=$(psql -t -c "\l" postgres | fgrep "$DATABASE_NAME_DEVNET" | fgrep "|" | awk '{$1=$1};1' | awk '{print $1}') 49 | local DB_EXISTS_TESTNET=$(psql -t -c "\l" postgres | fgrep "$DATABASE_NAME_TESTNET" | fgrep "|" | awk '{$1=$1};1' | awk '{print $1}') 50 | 51 | local DB_EXISTS="$DB_EXISTS_MAINNET $DB_EXISTS_DEVNET $DB_EXISTS_TESTNET" 52 | local DB_EXISTS=$(echo "$DB_EXISTS" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') 53 | 54 | if [ ! -z "$DB_EXISTS" ]; then 55 | local RECREATE_DATABASES="Y" 56 | if [[ "$INTERACTIVE" == "Y" ]]; then 57 | read -p "Database(s) ($DB_EXISTS) already exists. Recreate? [Y/n]: " RECREATE_DATABASES 58 | fi 59 | if [[ "$RECREATE_DATABASES" =~ ^(no|n|N) ]]; then 60 | echo "Skipping database re-creation" 61 | else 62 | if [ ! -z "$DB_EXISTS_MAINNET" ]; then 63 | dropdb "$DATABASE_NAME_MAINNET" 64 | createdb "$DATABASE_NAME_MAINNET" 65 | fi 66 | if [ ! -z "$DB_EXISTS_DEVNET" ]; then 67 | dropdb "$DATABASE_NAME_DEVNET" 68 | createdb "$DATABASE_NAME_DEVNET" 69 | fi 70 | if [ ! -z "$DB_EXISTS_TESTNET" ]; then 71 | dropdb "$DATABASE_NAME_TESTNET" 72 | createdb "$DATABASE_NAME_TESTNET" 73 | fi 74 | echo "Created databases" 75 | fi 76 | else 77 | createdb "$DATABASE_NAME_MAINNET" 78 | createdb "$DATABASE_NAME_DEVNET" 79 | createdb "$DATABASE_NAME_TESTNET" 80 | echo "Created databases" 81 | fi 82 | 83 | local DB_USER="core" 84 | local PQ_USER=$(sudo -u postgres psql -t -c "SELECT usename FROM pg_catalog.pg_user WHERE usename = '$DB_USER'" | awk '{$1=$1};1') 85 | if [[ "$PQ_USER" == "$DB_USER" ]]; then 86 | local RECREATE_USER="N" 87 | if [[ "$INTERACTIVE" == "Y" ]]; then 88 | read -p "User $DB_USER already exists. Recreate? [y/N]: " RECREATE_USER 89 | fi 90 | if [[ "$RECREATE_USER" =~ ^(yes|y|Y) ]]; then 91 | sudo -u postgres psql -c "DROP USER $DB_USER" 92 | sudo -u postgres psql -c "CREATE USER $DB_USER WITH PASSWORD 'password' CREATEDB;" 93 | else 94 | echo "Skipping User Creation for $DB_USER" 95 | fi 96 | else 97 | sudo -u postgres psql -c "CREATE USER $DB_USER WITH PASSWORD 'password' CREATEDB;" 98 | fi 99 | 100 | cd "$ROOT_PATH" 101 | if [ ! -d "$ROOT_PATH/packages/js-deployer/node_modules" ]; then 102 | cd "$ROOT_PATH/packages/js-deployer" 103 | yarn 104 | fi 105 | 106 | rm -rf "$CONFIG_PATH_MAINNET" "$CONFIG_PATH_DEVNET" "$CONFIG_PATH_TESTNET" "$BRIDGECHAIN_PATH" 107 | 108 | git clone https://github.com/ArkEcosystem/core.git --branch 2.6.57 --single-branch "$BRIDGECHAIN_PATH" 109 | 110 | local DYNAMIC_FEE_ENABLED="false" 111 | if [[ "$FEE_DYNAMIC_ENABLED" == "Y" ]]; then 112 | local DYNAMIC_FEE_ENABLED="true" 113 | fi 114 | 115 | ## Build Mainnet 116 | node "$ROOT_PATH/packages/js-deployer/bin/deployer" --configPath "$CONFIG_PATH_MAINNET" \ 117 | --corePath "$BRIDGECHAIN_PATH" \ 118 | --overwriteConfig \ 119 | --network "mainnet" \ 120 | --name "$CHAIN_NAME" \ 121 | --p2pPort "$P2P_PORT" \ 122 | --apiPort "$API_PORT" \ 123 | --webhookPort "$WEBHOOK_PORT" \ 124 | --jsonRpcPort "$JSON_RPC_PORT" \ 125 | --dbHost "$DATABASE_HOST" \ 126 | --dbPort "$DATABASE_PORT" \ 127 | --dbUsername "$DB_USER" \ 128 | --dbPassword "password" \ 129 | --dbDatabase "$DATABASE_NAME_MAINNET" \ 130 | --explorerUrl "$EXPLORER_URL" \ 131 | --forgers "$FORGERS" \ 132 | --feeStaticTransfer "$FEE_STATIC_TRANSFER" \ 133 | --feeStaticVote "$FEE_STATIC_VOTE" \ 134 | --feeStaticSecondSignature "$FEE_STATIC_SECOND_SIGNATURE" \ 135 | --feeStaticDelegateRegistration "$FEE_STATIC_DELEGATE_REGISTRATION" \ 136 | --feeStaticMultiSignature "$FEE_STATIC_MULTISIG_REGISTRATION" \ 137 | --feeStaticIpfs "$FEE_STATIC_IPFS" \ 138 | --feeStaticMultiPayment "$FEE_STATIC_MULTIPAYMENT" \ 139 | --feeStaticDelegateResignation "$FEE_STATIC_DELEGATE_RESIGNATION" \ 140 | --feeDynamicEnabled "$DYNAMIC_FEE_ENABLED" \ 141 | --feeDynamicPoolMinFee "$FEE_DYNAMIC_POOL_MIN_FEE" \ 142 | --feeDynamicBroadcastMinFee "$FEE_DYNAMIC_BROADCAST_MIN_FEE" \ 143 | --feeDynamicBytesTransfer "$FEE_DYNAMIC_BYTES_TRANSFER" \ 144 | --feeDynamicBytesSecondSignature "$FEE_DYNAMIC_BYTES_SECOND_SIGNATURE" \ 145 | --feeDynamicBytesDelegateRegistration "$FEE_DYNAMIC_BYTES_DELEGATE_REGISTRATION" \ 146 | --feeDynamicBytesVote "$FEE_DYNAMIC_BYTES_VOTE" \ 147 | --feeDynamicBytesMultiSignature "$FEE_DYNAMIC_BYTES_MULTISIG_REGISTRATION" \ 148 | --feeDynamicBytesIpfs "$FEE_DYNAMIC_BYTES_IPFS" \ 149 | --feeDynamicBytesMultiPayment "$FEE_DYNAMIC_BYTES_MULTIPAYMENT" \ 150 | --feeDynamicBytesDelegateResignation "$FEE_DYNAMIC_BYTES_DELEGATE_RESIGNATION" \ 151 | --rewardHeight "$REWARD_HEIGHT_START" \ 152 | --rewardPerBlock "$REWARD_PER_BLOCK" \ 153 | --vendorFieldLength "$VENDORFIELD_LENGTH" \ 154 | --blocktime "$BLOCK_TIME" \ 155 | --token "$TOKEN" \ 156 | --symbol "$SYMBOL" \ 157 | --peers "$MAINNET_PEERS" \ 158 | --prefixHash "$MAINNET_PREFIX" \ 159 | --transactionsPerBlock "$TXS_PER_BLOCK" \ 160 | --totalPremine "$TOTAL_PREMINE" 161 | 162 | ## Build Devnet 163 | node "$ROOT_PATH/packages/js-deployer/bin/deployer" --configPath "$CONFIG_PATH_DEVNET" \ 164 | --corePath "$BRIDGECHAIN_PATH" \ 165 | --overwriteConfig \ 166 | --network "devnet" \ 167 | --name "$CHAIN_NAME" \ 168 | --p2pPort "$P2P_PORT" \ 169 | --apiPort "$API_PORT" \ 170 | --webhookPort "$WEBHOOK_PORT" \ 171 | --jsonRpcPort "$JSON_RPC_PORT" \ 172 | --dbHost "$DATABASE_HOST" \ 173 | --dbPort "$DATABASE_PORT" \ 174 | --dbUsername "$DB_USER" \ 175 | --dbPassword "password" \ 176 | --dbDatabase "$DATABASE_NAME_DEVNET" \ 177 | --explorerUrl "$EXPLORER_URL" \ 178 | --forgers "$FORGERS" \ 179 | --feeStaticTransfer "$FEE_STATIC_TRANSFER" \ 180 | --feeStaticVote "$FEE_STATIC_VOTE" \ 181 | --feeStaticSecondSignature "$FEE_STATIC_SECOND_SIGNATURE" \ 182 | --feeStaticDelegateRegistration "$FEE_STATIC_DELEGATE_REGISTRATION" \ 183 | --feeStaticMultiSignature "$FEE_STATIC_MULTISIG_REGISTRATION" \ 184 | --feeStaticIpfs "$FEE_STATIC_IPFS" \ 185 | --feeStaticMultiPayment "$FEE_STATIC_MULTIPAYMENT" \ 186 | --feeStaticDelegateResignation "$FEE_STATIC_DELEGATE_RESIGNATION" \ 187 | --feeDynamicEnabled "$DYNAMIC_FEE_ENABLED" \ 188 | --feeDynamicPoolMinFee "$FEE_DYNAMIC_POOL_MIN_FEE" \ 189 | --feeDynamicBroadcastMinFee "$FEE_DYNAMIC_BROADCAST_MIN_FEE" \ 190 | --feeDynamicBytesTransfer "$FEE_DYNAMIC_BYTES_TRANSFER" \ 191 | --feeDynamicBytesSecondSignature "$FEE_DYNAMIC_BYTES_SECOND_SIGNATURE" \ 192 | --feeDynamicBytesDelegateRegistration "$FEE_DYNAMIC_BYTES_DELEGATE_REGISTRATION" \ 193 | --feeDynamicBytesVote "$FEE_DYNAMIC_BYTES_VOTE" \ 194 | --feeDynamicBytesMultiSignature "$FEE_DYNAMIC_BYTES_MULTISIG_REGISTRATION" \ 195 | --feeDynamicBytesIpfs "$FEE_DYNAMIC_BYTES_IPFS" \ 196 | --feeDynamicBytesMultiPayment "$FEE_DYNAMIC_BYTES_MULTIPAYMENT" \ 197 | --feeDynamicBytesDelegateResignation "$FEE_DYNAMIC_BYTES_DELEGATE_RESIGNATION" \ 198 | --rewardHeight "$REWARD_HEIGHT_START" \ 199 | --rewardPerBlock "$REWARD_PER_BLOCK" \ 200 | --vendorFieldLength "$VENDORFIELD_LENGTH" \ 201 | --blocktime "$BLOCK_TIME" \ 202 | --token "$TOKEN" \ 203 | --symbol "$SYMBOL" \ 204 | --peers "$DEVNET_PEERS" \ 205 | --prefixHash "$DEVNET_PREFIX" \ 206 | --transactionsPerBlock "$TXS_PER_BLOCK" \ 207 | --totalPremine "$TOTAL_PREMINE" 208 | 209 | ## Build Testnet 210 | node "$ROOT_PATH/packages/js-deployer/bin/deployer" --configPath "$CONFIG_PATH_TESTNET" \ 211 | --corePath "$BRIDGECHAIN_PATH" \ 212 | --overwriteConfig \ 213 | --network "testnet" \ 214 | --name "$CHAIN_NAME" \ 215 | --p2pPort "$P2P_PORT" \ 216 | --apiPort "$API_PORT" \ 217 | --webhookPort "$WEBHOOK_PORT" \ 218 | --jsonRpcPort "$JSON_RPC_PORT" \ 219 | --dbHost "$DATABASE_HOST" \ 220 | --dbPort "$DATABASE_PORT" \ 221 | --dbUsername "$DB_USER" \ 222 | --dbPassword "password" \ 223 | --dbDatabase "$DATABASE_NAME_TESTNET" \ 224 | --explorerUrl "$EXPLORER_URL" \ 225 | --forgers "$FORGERS" \ 226 | --feeStaticTransfer "$FEE_STATIC_TRANSFER" \ 227 | --feeStaticVote "$FEE_STATIC_VOTE" \ 228 | --feeStaticSecondSignature "$FEE_STATIC_SECOND_SIGNATURE" \ 229 | --feeStaticDelegateRegistration "$FEE_STATIC_DELEGATE_REGISTRATION" \ 230 | --feeStaticMultiSignature "$FEE_STATIC_MULTISIG_REGISTRATION" \ 231 | --feeStaticIpfs "$FEE_STATIC_IPFS" \ 232 | --feeStaticMultiPayment "$FEE_STATIC_MULTIPAYMENT" \ 233 | --feeStaticDelegateResignation "$FEE_STATIC_DELEGATE_RESIGNATION" \ 234 | --feeDynamicEnabled "$DYNAMIC_FEE_ENABLED" \ 235 | --feeDynamicPoolMinFee "$FEE_DYNAMIC_POOL_MIN_FEE" \ 236 | --feeDynamicBroadcastMinFee "$FEE_DYNAMIC_BROADCAST_MIN_FEE" \ 237 | --feeDynamicBytesTransfer "$FEE_DYNAMIC_BYTES_TRANSFER" \ 238 | --feeDynamicBytesSecondSignature "$FEE_DYNAMIC_BYTES_SECOND_SIGNATURE" \ 239 | --feeDynamicBytesDelegateRegistration "$FEE_DYNAMIC_BYTES_DELEGATE_REGISTRATION" \ 240 | --feeDynamicBytesVote "$FEE_DYNAMIC_BYTES_VOTE" \ 241 | --feeDynamicBytesMultiSignature "$FEE_DYNAMIC_BYTES_MULTISIG_REGISTRATION" \ 242 | --feeDynamicBytesIpfs "$FEE_DYNAMIC_BYTES_IPFS" \ 243 | --feeDynamicBytesMultiPayment "$FEE_DYNAMIC_BYTES_MULTIPAYMENT" \ 244 | --feeDynamicBytesDelegateResignation "$FEE_DYNAMIC_BYTES_DELEGATE_RESIGNATION" \ 245 | --rewardPerBlock "$REWARD_PER_BLOCK" \ 246 | --vendorFieldLength "$VENDORFIELD_LENGTH" \ 247 | --blocktime "$BLOCK_TIME" \ 248 | --token "$TOKEN" \ 249 | --symbol "$SYMBOL" \ 250 | --prefixHash "$TESTNET_PREFIX" \ 251 | --transactionsPerBlock "$TXS_PER_BLOCK" \ 252 | --totalPremine "$TOTAL_PREMINE" 253 | 254 | rm -rf "$BRIDGECHAIN_PATH"/packages/core/bin/config/{mainnet,devnet,testnet}/ 255 | rm -rf "$BRIDGECHAIN_PATH"/packages/crypto/src/networks/{mainnet,devnet,testnet}/ 256 | 257 | cp -R "$CONFIG_PATH_MAINNET/core" "$BRIDGECHAIN_PATH/packages/core/bin/config/mainnet" 258 | cp -R "$CONFIG_PATH_MAINNET/crypto" "$BRIDGECHAIN_PATH/packages/crypto/src/networks/mainnet" 259 | cp -R "$CONFIG_PATH_DEVNET/core" "$BRIDGECHAIN_PATH/packages/core/bin/config/devnet" 260 | cp -R "$CONFIG_PATH_DEVNET/crypto" "$BRIDGECHAIN_PATH/packages/crypto/src/networks/devnet" 261 | cp -R "$CONFIG_PATH_TESTNET/core" "$BRIDGECHAIN_PATH/packages/core/bin/config/testnet" 262 | cp -R "$CONFIG_PATH_TESTNET/crypto" "$BRIDGECHAIN_PATH/packages/crypto/src/networks/testnet" 263 | cp "$CONFIG_PATH_TESTNET/delegates.json" "$BRIDGECHAIN_PATH/packages/core/bin/config/testnet/" 264 | 265 | ## Update core properties 266 | local PACKAGE_JSON_PATH="$BRIDGECHAIN_PATH/packages/core/package.json" 267 | local PACKAGE_JSON=$(cat "$PACKAGE_JSON_PATH" | jq ".name = \"@${CORE_ALIAS}/core\"") 268 | local PACKAGE_JSON=$(echo "$PACKAGE_JSON" | jq ".description = \"Core of the ${CHAIN_NAME} Blockchain\"") 269 | local PACKAGE_JSON=$(echo "$PACKAGE_JSON" | jq ".bin[\"${CORE_ALIAS}\"] = \"./bin/run\"") 270 | local PACKAGE_JSON=$(echo "$PACKAGE_JSON" | jq "del(.bin.ark)") 271 | local PACKAGE_JSON=$(echo "$PACKAGE_JSON" | jq ".scripts[\"${CORE_ALIAS}\"] = \"./bin/run\"") 272 | local PACKAGE_JSON=$(echo "$PACKAGE_JSON" | jq "del(.scripts.ark)") 273 | local PACKAGE_JSON=$(echo "$PACKAGE_JSON" | jq ".oclif.bin = \"${CORE_ALIAS}\"") 274 | echo $PACKAGE_JSON 275 | rm "$PACKAGE_JSON_PATH" 276 | echo "$PACKAGE_JSON" > "$PACKAGE_JSON_PATH" 277 | 278 | if [ ! -z "$LICENSE_NAME" ]; then 279 | local YEAR=$(date +"%-Y") 280 | local LICENSE="Copyright (c) $YEAR $LICENSE_NAME" 281 | if [ ! -z "$LICENSE_EMAIL" ]; then 282 | local LICENSE="$LICENSE <$LICENSE_EMAIL>" 283 | fi 284 | sed -i -E "s/^(Copyright.+Ark Ecosystem.*)$/\1\n$LICENSE/g" "$BRIDGECHAIN_PATH/LICENSE" 285 | fi 286 | 287 | if [[ "$GIT_CORE_COMMIT" == "Y" ]]; then 288 | echo "Committing changes..." 289 | cd "$BRIDGECHAIN_PATH" 290 | if [[ "$GIT_USE_SSH" == "Y" ]]; then 291 | git config url."git@github.com:".insteadOf "https://github.com/" 292 | fi 293 | git config --global user.email "support@ark.io" 294 | git config --global user.name "ARK Deployer" 295 | git checkout -b chore/bridgechain-changes 296 | if [[ "$GIT_CORE_ORIGIN" != "" ]]; then 297 | local ALIAS=$(echo $CORE_ALIAS | tr -cs '[:alnum:]\r\n' '-' | tr '[:upper:]' '[:lower:]') 298 | read -r -d '' COMMANDS << EOM || true 299 | shopt -s expand_aliases 300 | alias ark="$BRIDGECHAIN_PATH_RAW/packages/core/bin/run" 301 | echo 'alias $ALIAS="$BRIDGECHAIN_PATH_RAW/packages/core/bin/run"' >> ~/.bashrc 302 | 303 | rm -rf "$BRIDGECHAIN_PATH_RAW" 304 | git clone "$GIT_CORE_ORIGIN" "$BRIDGECHAIN_PATH_RAW" || FAILED="Y" 305 | if [ "\$FAILED" == "Y" ]; then 306 | echo "Failed to fetch core repo with origin '$GIT_CORE_ORIGIN'" 307 | 308 | exit 1 309 | fi 310 | 311 | cd "$BRIDGECHAIN_PATH_RAW" 312 | HAS_REMOTE=\$(git branch -a | fgrep -o "remotes/origin/chore/bridgechain-changes") 313 | if [ ! -z "\$HAS_REMOTE" ]; then 314 | git checkout chore/bridgechain-changes 315 | fi 316 | 317 | YARN_SETUP="N" 318 | while [ "$YARN_SETUP" == "N" ]; do 319 | YARN_SETUP="Y" 320 | rm -rf "\$HOME/.cache/yarn" 321 | yarn setup || YARN_SETUP="N" 322 | if [[ "$YARN_SETUP" == "N" ]]; then 323 | read -p "Failed to setup core. Retry? [Y/n]: " RETRY_SETUP 324 | fi 325 | if [[ "$RETRY_SETUP" =~ ^(no|n|N) ]]; then 326 | exit 1 327 | fi 328 | done 329 | 330 | rm -rf "\$HOME/.config/@${CORE_ALIAS}" 331 | rm -rf "\$HOME/.config/@${CHAIN_NAME}" 332 | rm -rf "\$HOME/.config/${CORE_ALIAS}-core" 333 | EOM 334 | COMMANDS=$(echo "$COMMANDS" | tr '\n' '\r') 335 | sed -i "s/ARK Core/Core/gi" "$BRIDGECHAIN_PATH/install.sh" 336 | LINE_NO_START=$(($(egrep -hn "^while.+yarn global add @arkecosystem/core.+do" "$BRIDGECHAIN_PATH/install.sh" | cut -f1 -d:)+1)) 337 | LINE_NO_END=$(($LINE_NO_START+4)) 338 | sed -i "${LINE_NO_START},${LINE_NO_END}d" "$BRIDGECHAIN_PATH/install.sh" 339 | 340 | INSTALL_SH=$(sed -E "s#^while.+yarn global add @arkecosystem\/core.+do\$#$COMMANDS#gi" "$BRIDGECHAIN_PATH/install.sh" | tr '\r' '\n') 341 | rm "$BRIDGECHAIN_PATH/install.sh" && echo "$INSTALL_SH" > "$BRIDGECHAIN_PATH/install.sh" 342 | fi 343 | git add . 344 | git commit -m "chore: prepare new network config 🎉" 345 | if [[ "$GIT_CORE_ORIGIN" != "" ]]; then 346 | git remote set-url origin "$GIT_CORE_ORIGIN" 347 | git push --set-upstream origin chore/bridgechain-changes || local CANT_PUSH="Y" 348 | if [[ "$CANT_PUSH" == "Y" ]]; then 349 | error "Could not push Git changes to '$GIT_CORE_ORIGIN'" 350 | fi 351 | fi 352 | fi 353 | 354 | __core_setup 355 | 356 | app_output_passphrases "$@" 357 | 358 | app_install_core_configuration 359 | 360 | success "Bridgechain Installed!" 361 | } 362 | 363 | app_uninstall_core() 364 | { 365 | process_core_stop "$@" 366 | 367 | heading "Uninstalling..." 368 | if [ ! -z "$CHAIN_NAME" ]; then 369 | pm2 delete "$CHAIN_NAME-relay" &>/dev/null || true 370 | pm2 delete "$CHAIN_NAME-forger" &>/dev/null || true 371 | fi 372 | 373 | rm -rf "$BRIDGECHAIN_PATH" 374 | 375 | success "Uninstall OK!" 376 | } 377 | 378 | app_output_passphrases() 379 | { 380 | parse_core_args "$@" 381 | 382 | local CONFIG_PATH_MAINNET="$HOME/.bridgechain/mainnet/$CHAIN_NAME" 383 | local CONFIG_PATH_DEVNET="$HOME/.bridgechain/devnet/$CHAIN_NAME" 384 | local CONFIG_PATH_TESTNET="$HOME/.bridgechain/testnet/$CHAIN_NAME" 385 | 386 | echo "------------------------------------" 387 | echo "Passphrase Details" 388 | echo "------------------------------------" 389 | if [ -d "$CONFIG_PATH_MAINNET" ]; then 390 | local PASSPHRASE=$(sh -c "jq '.passphrase' $CONFIG_PATH_MAINNET/genesisWallet.json") 391 | local ADDRESS=$(sh -c "jq '.address' $CONFIG_PATH_MAINNET/genesisWallet.json") 392 | 393 | echo "Your MAINNET Genesis Details are:" 394 | echo " Passphrase: $PASSPHRASE" 395 | echo " Address: $ADDRESS" 396 | echo "" 397 | echo "You can find the genesis wallet passphrase in '$CONFIG_PATH_MAINNET/genesisWallet.json'" 398 | echo "You can find the delegates.json passphrase file at '$CONFIG_PATH_MAINNET/delegates.json'" 399 | else 400 | echo "Could not find your MAINNET config" 401 | fi 402 | echo "------------------------------------" 403 | 404 | if [ -d "$CONFIG_PATH_DEVNET" ]; then 405 | local PASSPHRASE=$(sh -c "jq '.passphrase' $CONFIG_PATH_DEVNET/genesisWallet.json") 406 | local ADDRESS=$(sh -c "jq '.address' $CONFIG_PATH_DEVNET/genesisWallet.json") 407 | 408 | echo "Your DEVNET Genesis Details are:" 409 | echo " Passphrase: $PASSPHRASE" 410 | echo " Address: $ADDRESS" 411 | echo "" 412 | echo "You can find the genesis wallet passphrase in '$CONFIG_PATH_DEVNET/genesisWallet.json'" 413 | echo "You can find the delegates.json passphrase file at '$CONFIG_PATH_DEVNET/delegates.json'" 414 | else 415 | echo "Could not find your DEVNET config" 416 | fi 417 | echo "------------------------------------" 418 | 419 | if [ -d "$CONFIG_PATH_TESTNET" ]; then 420 | local PASSPHRASE=$(sh -c "jq '.passphrase' $CONFIG_PATH_TESTNET/genesisWallet.json") 421 | local ADDRESS=$(sh -c "jq '.address' $CONFIG_PATH_TESTNET/genesisWallet.json") 422 | 423 | echo "Your TESTNET Genesis Details are:" 424 | echo " Passphrase: $PASSPHRASE" 425 | echo " Address: $ADDRESS" 426 | echo "" 427 | echo "You can find the genesis wallet passphrase in '$CONFIG_PATH_TESTNET/genesisWallet.json'" 428 | echo "You can find the delegates.json passphrase file at '$CONFIG_PATH_TESTNET/delegates.json'" 429 | echo "or '$BRIDGECHAIN_PATH/packages/core/bin/config/testnet/delegates.json'" 430 | else 431 | echo "Could not find your TESTNET config" 432 | fi 433 | echo "------------------------------------" 434 | } 435 | 436 | __core_setup() 437 | { 438 | echo "Setting up Core..." 439 | 440 | __yarn_setup 441 | 442 | cd "$BRIDGECHAIN_PATH/packages/core/" 443 | ./bin/run config:cli --token "$CORE_ALIAS" 444 | } 445 | 446 | __yarn_setup() 447 | { 448 | if [[ "$1" != "1" ]]; then 449 | cd "$BRIDGECHAIN_PATH" 450 | else 451 | error "Yarn setup failed. Trying again..." 452 | rm -rf "$HOME/.cache/yarn" 453 | fi 454 | yarn setup || __yarn_setup 1 455 | } 456 | -------------------------------------------------------------------------------- /app/app-explorer.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | app_install_explorer() 4 | { 5 | parse_explorer_args "$@" 6 | install_dependencies 7 | app_uninstall_explorer "$@" 8 | 9 | heading "Installing Explorer to '$EXPLORER_PATH'..." 10 | 11 | rm -rf "$EXPLORER_PATH" 12 | git clone https://github.com/ArkEcosystem/ark-explorer.git -b master "$EXPLORER_PATH" && cd "$EXPLORER_PATH" 13 | yarn 14 | yarn add connect-history-api-fallback express 15 | 16 | for NETWORK_FILE in $(ls "$EXPLORER_PATH/networks/"); do 17 | local NETWORK_PATH="$EXPLORER_PATH/networks/$NETWORK_FILE" 18 | local NETWORK_TYPE=$(echo "$NETWORK_FILE" | sed s/\.json$//g | sed 's/./\U&/') 19 | local NETWORK_LOWER=$(echo "$NETWORK_TYPE" | awk '{print tolower($0)}') 20 | local CONFIG=$(cat "$NETWORK_PATH" | jq ".title = \"$CHAIN_NAME $NETWORK_TYPE Explorer\"") 21 | local CONFIG=$(echo "$CONFIG" | jq ".server = \"http://$CORE_IP:$API_PORT/api/v2\"") 22 | local CONFIG=$(echo "$CONFIG" | jq ".activeDelegates = \"$FORGERS\"") 23 | local CONFIG=$(echo "$CONFIG" | jq ".rewardOffset = \"$REWARD_HEIGHT_START\"") 24 | local CONFIG=$(echo "$CONFIG" | jq ".currencies = []") 25 | local CONFIG=$(echo "$CONFIG" | jq ".knownWallets = {}") 26 | local CONFIG=$(echo "$CONFIG" | jq ".defaults.currency = null") 27 | local CONFIG=$(echo "$CONFIG" | jq ".defaults.token = \"$TOKEN\"") 28 | local CONFIG=$(echo "$CONFIG" | jq ".defaults.symbol = \"$SYMBOL\"") 29 | local CONFIG=$(echo "$CONFIG" | jq ".defaults.priceChart = false") 30 | rm "$NETWORK_PATH" 31 | echo "$CONFIG" > "$NETWORK_PATH" 32 | done 33 | 34 | cat > "$EXPLORER_PATH/start-explorer.sh" <<- EOF 35 | NETWORK="\$1" 36 | if [ -z "\$NETWORK" ]; then 37 | NETWORK="testnet" 38 | fi 39 | HOST="$EXPLORER_IP" PORT="$EXPLORER_PORT" yarn build:"\$NETWORK" 40 | EXPLORER_HOST="$EXPLORER_IP" EXPLORER_PORT="$EXPLORER_PORT" pm2 start $EXPLORER_PATH/express-server.js --name explorer 41 | EOF 42 | 43 | chmod u+x "$EXPLORER_PATH/start-explorer.sh" 44 | 45 | if [ ! -z "$LICENSE_NAME" ]; then 46 | local YEAR=$(date +"%-Y") 47 | local LICENSE="Copyright (c) $YEAR $LICENSE_NAME" 48 | if [ ! -z "$LICENSE_EMAIL" ]; then 49 | local LICENSE="$LICENSE <$LICENSE_EMAIL>" 50 | fi 51 | sed -i -E "s/^(Copyright.+Ark Ecosystem.*)$/\1\n$LICENSE/g" "$EXPLORER_PATH/LICENSE" 52 | fi 53 | 54 | if [[ "$GIT_EXPLORER_COMMIT" == "Y" ]]; then 55 | echo "Committing changes..." 56 | cd "$EXPLORER_PATH" 57 | if [[ "$GIT_USE_SSH" == "Y" ]]; then 58 | git config url."git@github.com:".insteadOf "https://github.com/" 59 | fi 60 | git config --global user.email "support@ark.io" 61 | git config --global user.name "ARK Deployer" 62 | git checkout -b chore/bridgechain-changes 63 | git add . 64 | git commit -m "chore: prepare new network config 🎉" 65 | if [[ "$GIT_EXPLORER_ORIGIN" != "" ]]; then 66 | git remote set-url origin "$GIT_EXPLORER_ORIGIN" 67 | git push --set-upstream origin chore/bridgechain-changes || local CANT_PUSH="Y" 68 | if [[ "$CANT_PUSH" == "Y" ]]; then 69 | echo "Could not push Git changes to '$GIT_EXPLORER_ORIGIN'" 70 | fi 71 | fi 72 | fi 73 | 74 | success "Explorer Installed!" 75 | } 76 | 77 | app_uninstall_explorer() 78 | { 79 | heading "Uninstalling Explorer..." 80 | parse_explorer_args "$@" 81 | process_explorer_stop 82 | rm -rf "$EXPLORER_PATH" 83 | pm2 del explorer &>/dev/null || true 84 | success "Uninstall OK!" 85 | } 86 | -------------------------------------------------------------------------------- /app/args.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | parse_json_config() 4 | { 5 | if [[ "$CONFIG_PROCESSED" == "Y" ]]; then 6 | return 7 | fi 8 | 9 | if [[ -f "$CONFIG" ]]; then 10 | KEYS=$(jq -r '. | keys[]' "$CONFIG") 11 | for KEY in $(jq -r '. | keys[]' "$CONFIG"); do 12 | case $KEY in 13 | "coreIp") ## Used when accessing Explorer 14 | CORE_IP=$(jq -r '.coreIp' "$CONFIG") 15 | if [ "$CORE_IP" == "127.0.0.1" ]; then 16 | CORE_IP=$(get_ip) 17 | fi 18 | ;; 19 | "p2pPort") 20 | P2P_PORT=$(jq -r '.p2pPort' "$CONFIG") 21 | ;; 22 | "apiPort") 23 | API_PORT=$(jq -r '.apiPort' "$CONFIG") 24 | ;; 25 | "webhookPort") 26 | WEBHOOK_PORT=$(jq -r '.webhookPort' "$CONFIG") 27 | ;; 28 | "jsonRpcPort") 29 | JSON_RPC_PORT=$(jq -r '.jsonRpcPort' "$CONFIG") 30 | ;; 31 | "explorerIp") 32 | EXPLORER_IP=$(jq -r '.explorerIp // empty' "$CONFIG") 33 | ;; 34 | "explorerPort") 35 | EXPLORER_PORT=$(jq -r '.explorerPort // empty' "$CONFIG") 36 | ;; 37 | "chainName") 38 | local CHANGE_DATABASE="N" 39 | if [[ "$DATABASE_NAME" == "core_$CHAIN_NAME" ]]; then 40 | CHANGE_DATABASE="Y" 41 | fi 42 | CHAIN_NAME=$(jq -r '.chainName' "$CONFIG" | tr -cs '[:alnum:]\r\n' '-') 43 | if [ "$CHANGE_DATABASE" == "Y" ]; then 44 | DATABASE_NAME="core_$CHAIN_NAME" 45 | fi 46 | ;; 47 | "token") 48 | TOKEN=$(jq -r '.token' "$CONFIG") 49 | ;; 50 | "cliAlias") 51 | CLI_ALIAS=$(jq -r '.cliAlias' "$CONFIG") 52 | ;; 53 | "databaseHost") 54 | DATABASE_HOST=$(jq -r '.databaseHost' "$CONFIG") 55 | ;; 56 | "databasePort") 57 | DATABASE_PORT=$(jq -r '.databasePort' "$CONFIG") 58 | ;; 59 | "databaseName") 60 | DATABASE_NAME=$(jq -r '.databaseName' "$CONFIG") 61 | ;; 62 | "symbol") 63 | SYMBOL=$(jq -r '.symbol' "$CONFIG") 64 | ;; 65 | "mainnetPeers") 66 | local MAINNET_PEERS_RAW=$(jq -r '.mainnetPeers // empty' "$CONFIG") 67 | if [ ! -z "$MAINNET_PEERS_RAW" ]; then 68 | MAINNET_PEERS=$(jq -r '.mainnetPeers // empty | join(",")' "$CONFIG") 69 | fi 70 | ;; 71 | "devnetPeers") 72 | local DEVNET_PEERS_RAW=$(jq -r '.devnetPeers // empty' "$CONFIG") 73 | if [ ! -z "$DEVNET_PEERS_RAW" ]; then 74 | DEVNET_PEERS=$(jq -r '.devnetPeers // empty | join(",")' "$CONFIG") 75 | fi 76 | ;; 77 | "mainnetPrefix") 78 | MAINNET_PREFIX=$(jq -r '.mainnetPrefix' "$CONFIG") 79 | ;; 80 | "devnetPrefix") 81 | DEVNET_PREFIX=$(jq -r '.devnetPrefix' "$CONFIG") 82 | ;; 83 | "testnetPrefix") 84 | TESTNET_PREFIX=$(jq -r '.testnetPrefix' "$CONFIG") 85 | ;; 86 | "fees") 87 | local STATIC_FEES=$(jq -r '.fees.static // empty' "$CONFIG") 88 | if [ ! -z "$STATIC_FEES" ]; then 89 | local STATIC_TRANSFER=$(jq -r '.fees.static.transfer // empty' "$CONFIG") 90 | if [ ! -z "$STATIC_TRANSFER" ]; then 91 | FEE_STATIC_TRANSFER="$STATIC_TRANSFER" 92 | fi 93 | local STATIC_VOTE=$(jq -r '.fees.static.vote // empty' "$CONFIG") 94 | if [ ! -z "$STATIC_VOTE" ]; then 95 | FEE_STATIC_VOTE="$STATIC_VOTE" 96 | fi 97 | local STATIC_SECOND_SIGNATURE=$(jq -r '.fees.static.secondSignature // empty' "$CONFIG") 98 | if [ ! -z "$STATIC_SECOND_SIGNATURE" ]; then 99 | FEE_STATIC_SECOND_SIGNATURE="$STATIC_SECOND_SIGNATURE" 100 | fi 101 | local STATIC_DELEGATE_REGISTRATION=$(jq -r '.fees.static.delegateRegistration // empty' "$CONFIG") 102 | if [ ! -z "$STATIC_DELEGATE_REGISTRATION" ]; then 103 | FEE_STATIC_DELEGATE_REGISTRATION="$STATIC_DELEGATE_REGISTRATION" 104 | fi 105 | local STATIC_MULTISIG_REGISTRATION=$(jq -r '.fees.static.multiSignature // empty' "$CONFIG") 106 | if [ ! -z "$STATIC_MULTISIG_REGISTRATION" ]; then 107 | FEE_STATIC_MULTISIG_REGISTRATION="$STATIC_MULTISIG_REGISTRATION" 108 | fi 109 | local STATIC_IPFS=$(jq -r '.fees.static.ipfs // empty' "$CONFIG") 110 | if [ ! -z "$STATIC_IPFS" ]; then 111 | FEE_STATIC_IPFS="$STATIC_IPFS" 112 | fi 113 | local STATIC_MULTIPAYMENT=$(jq -r '.fees.static.multipayment // empty' "$CONFIG") 114 | if [ ! -z "$STATIC_MULTIPAYMENT" ]; then 115 | FEE_STATIC_MULTIPAYMENT="$STATIC_MULTIPAYMENT" 116 | fi 117 | local STATIC_DELEGATE_RESIGNATION=$(jq -r '.fees.static.delegateResignation // empty' "$CONFIG") 118 | if [ ! -z "$STATIC_DELEGATE_RESIGNATION" ]; then 119 | FEE_STATIC_DELEGATE_RESIGNATION="$STATIC_DELEGATE_RESIGNATION" 120 | fi 121 | fi 122 | 123 | local DYNAMIC_FEES=$(jq -r '.fees.dynamic // empty' "$CONFIG") 124 | if [ ! -z "$DYNAMIC_FEES" ]; then 125 | local IS_ENABLED=$(jq -r '.fees.dynamic.enabled' "$CONFIG") 126 | if [[ "$IS_ENABLED" == "true" ]]; then 127 | FEE_DYNAMIC_ENABLED="Y" 128 | fi 129 | local POOL_MIN_FEE=$(jq -r '.fees.dynamic.minFeePool // empty' "$CONFIG") 130 | if [ ! -z "$POOL_MIN_FEE" ]; then 131 | FEE_DYNAMIC_POOL_MIN_FEE="$POOL_MIN_FEE" 132 | fi 133 | local BROADCAST_MIN_FEE=$(jq -r '.fees.dynamic.minFeeBroadcast // empty' "$CONFIG") 134 | if [ ! -z "$BROADCAST_MIN_FEE" ]; then 135 | FEE_DYNAMIC_BROADCAST_MIN_FEE="$BROADCAST_MIN_FEE" 136 | fi 137 | local BYTES_TRANSFER=$(jq -r '.fees.dynamic.addonBytes.transfer // empty' "$CONFIG") 138 | if [ ! -z "$BYTES_TRANSFER" ]; then 139 | FEE_DYNAMIC_BYTES_TRANSFER="$BYTES_TRANSFER" 140 | fi 141 | local BYTES_SECOND_SIGNATURE=$(jq -r '.fees.dynamic.addonBytes.secondSignature // empty' "$CONFIG") 142 | if [ ! -z "$BYTES_SECOND_SIGNATURE" ]; then 143 | FEE_DYNAMIC_BYTES_SECOND_SIGNATURE="$BYTES_SECOND_SIGNATURE" 144 | fi 145 | local BYTES_DELEGATE_REGISTRATION=$(jq -r '.fees.dynamic.addonBytes.delegateRegistration // empty' "$CONFIG") 146 | if [ ! -z "$BYTES_DELEGATE_REGISTRATION" ]; then 147 | FEE_DYNAMIC_BYTES_DELEGATE_REGISTRATION="$BYTES_DELEGATE_REGISTRATION" 148 | fi 149 | local BYTES_VOTE=$(jq -r '.fees.dynamic.addonBytes.vote // empty' "$CONFIG") 150 | if [ ! -z "$BYTES_VOTE" ]; then 151 | FEE_DYNAMIC_BYTES_VOTE="$BYTES_VOTE" 152 | fi 153 | local BYTES_MULTISIG_REGISTRATION=$(jq -r '.fees.dynamic.addonBytes.multiSignature // empty' "$CONFIG") 154 | if [ ! -z "$BYTES_MULTISIG_REGISTRATION" ]; then 155 | FEE_DYNAMIC_BYTES_MULTISIG_REGISTRATION="$BYTES_MULTISIG_REGISTRATION" 156 | fi 157 | local BYTES_IPFS=$(jq -r '.fees.dynamic.addonBytes.ipfs // empty' "$CONFIG") 158 | if [ ! -z "$BYTES_IPFS" ]; then 159 | FEE_DYNAMIC_BYTES_IPFS="$BYTES_IPFS" 160 | fi 161 | local BYTES_MULTIPAYMENT=$(jq -r '.fees.dynamic.addonBytes.multiPayment // empty' "$CONFIG") 162 | if [ ! -z "$BYTES_MULTIPAYMENT" ]; then 163 | FEE_DYNAMIC_BYTES_MULTIPAYMENT="$BYTES_MULTIPAYMENT" 164 | fi 165 | local BYTES_DELEGATE_RESIGNATION=$(jq -r '.fees.dynamic.addonBytes.delegateResignation // empty' "$CONFIG") 166 | if [ ! -z "$BYTES_DELEGATE_RESIGNATION" ]; then 167 | FEE_DYNAMIC_BYTES_DELEGATE_RESIGNATION="$BYTES_DELEGATE_RESIGNATION" 168 | fi 169 | fi 170 | ;; 171 | "forgers") 172 | FORGERS=$(jq -r '.forgers' "$CONFIG") 173 | ;; 174 | "blocktime") 175 | BLOCK_TIME=$(jq -r '.blocktime' "$CONFIG") 176 | ;; 177 | "transactionsPerBlock") 178 | TXS_PER_BLOCK=$(jq -r '.transactionsPerBlock' "$CONFIG") 179 | ;; 180 | "totalPremine") 181 | TOTAL_PREMINE=$(jq -r '.totalPremine' "$CONFIG") 182 | ;; 183 | "rewardHeightStart") 184 | REWARD_HEIGHT_START=$(jq -r '.rewardHeightStart' "$CONFIG") 185 | ;; 186 | "rewardPerBlock") 187 | REWARD_PER_BLOCK=$(jq -r '.rewardPerBlock' "$CONFIG") 188 | ;; 189 | "vendorFieldLength") 190 | VENDORFIELD_LENGTH=$(jq -r '.vendorFieldLength' "$CONFIG") 191 | ;; 192 | "bridgechainPath") 193 | BRIDGECHAIN_PATH_RAW=$(jq -r '.bridgechainPath' "$CONFIG") 194 | BRIDGECHAIN_PATH=$(eval echo "$BRIDGECHAIN_PATH_RAW") 195 | ;; 196 | "explorerPath") 197 | EXPLORER_PATH_RAW=$(jq -r '.explorerPath' "$CONFIG") 198 | EXPLORER_PATH=$(eval echo "$EXPLORER_PATH_RAW") 199 | ;; 200 | "gitCoreCommit") 201 | local VALUE=$(jq -r '.gitCoreCommit' "$CONFIG") 202 | if [[ "$VALUE" == "true" ]]; then 203 | GIT_CORE_COMMIT="Y" 204 | fi 205 | ;; 206 | "gitCoreOrigin") 207 | GIT_CORE_ORIGIN=$(jq -r '.gitCoreOrigin // empty' "$CONFIG") 208 | ;; 209 | "gitExplorerCommit") 210 | local VALUE=$(jq -r '.gitExplorerCommit' "$CONFIG") 211 | if [[ "$VALUE" == "true" ]]; then 212 | GIT_EXPLORER_COMMIT="Y" 213 | fi 214 | ;; 215 | "gitExplorerOrigin") 216 | GIT_EXPLORER_ORIGIN=$(jq -r '.gitExplorerOrigin // empty' "$CONFIG") 217 | ;; 218 | "gitUseSsh") 219 | local USE_SSH=$(jq -r '.gitUseSsh' "$CONFIG") 220 | if [[ "$USE_SSH" == "true" ]]; then 221 | GIT_USE_SSH="Y" 222 | fi 223 | ;; 224 | "licenseName") 225 | LICENSE_NAME=$(jq -r '.licenseName // empty' "$CONFIG") 226 | ;; 227 | "licenseEmail") 228 | LICENSE_EMAIL=$(jq -r '.licenseEmail // empty' "$CONFIG") 229 | ;; 230 | esac 231 | done 232 | fi 233 | 234 | post_args_process 235 | 236 | CONFIG_PROCESSED="Y" 237 | } 238 | 239 | post_args_process() 240 | { 241 | if [ "$CLI_ALIAS" == "TOKEN" ]; then 242 | CORE_ALIAS="$TOKEN" 243 | else 244 | CORE_ALIAS="$CHAIN_NAME" 245 | fi 246 | 247 | CORE_ALIAS=$(echo $CORE_ALIAS | tr -cs '[:alnum:]\r\n' '-' | tr '[:upper:]' '[:lower:]') 248 | 249 | LOCAL_EXPLORER_IP="$EXPLORER_IP" 250 | LOCAL_EXPLORER_PORT=$(echo "$EXPLORER_PORT" | sed 's/[^0-9]//g') 251 | if [ -z "$LOCAL_EXPLORER_IP" ]; then 252 | LOCAL_EXPLORER_IP="0.0.0.0" 253 | fi 254 | if [ -z "$LOCAL_EXPLORER_PORT" ]; then 255 | LOCAL_EXPLORER_PORT="4200" 256 | fi 257 | EXPLORER_URL="http://$LOCAL_EXPLORER_IP:$LOCAL_EXPLORER_PORT" 258 | } 259 | 260 | parse_generic_args() 261 | { 262 | ARGS="$@" 263 | HAS_JSON_CONFIG="N" 264 | 265 | while [[ $# -ne 0 ]] ; do 266 | case $1 in 267 | "--config") 268 | CONFIG="$2" 269 | HAS_JSON_CONFIG="Y" 270 | ;; 271 | esac 272 | shift 273 | done 274 | 275 | if [ "$HAS_JSON_CONFIG" == "Y" ]; then 276 | parse_json_config 277 | elif [[ -d "$XDG_CONFIG_HOME/deployer" && -f "$XDG_CONFIG_HOME/deployer/.env" ]]; then 278 | export $(grep -v '^#' "$XDG_CONFIG_HOME/deployer/.env" | xargs) 279 | fi 280 | 281 | set -- $ARGS 282 | while [[ $# -ne 0 ]] ; do 283 | case $1 in 284 | "--name") 285 | local CHANGE_DATABASE="N" 286 | if [[ "$DATABASE_NAME" == "core_$CHAIN_NAME" ]]; then 287 | CHANGE_DATABASE="Y" 288 | fi 289 | CHAIN_NAME=$(echo $2 | tr -cs '[:alnum:]\r\n' '-') 290 | if [ "$CHANGE_DATABASE" == "Y" ]; then 291 | DATABASE_NAME="core_$CHAIN_NAME" 292 | fi 293 | ;; 294 | "--explorer-ip") 295 | EXPLORER_IP="$2" 296 | ;; 297 | "--explorer-port") 298 | EXPLORER_PORT="$2" 299 | ;; 300 | "--token") 301 | TOKEN="$2" 302 | ;; 303 | "--cli-alias") 304 | CLI_ALIAS="$2" 305 | ;; 306 | "--forgers") 307 | FORGERS="$2" 308 | ;; 309 | "--autoinstall-deps") 310 | INSTALL_DEPS="Y" 311 | ;; 312 | "--skip-deps") 313 | SKIP_DEPS="Y" 314 | ;; 315 | "--non-interactive") 316 | INTERACTIVE="N" 317 | ;; 318 | "--git-commit") 319 | if [[ $METHOD == "install-core" ]]; then 320 | GIT_CORE_COMMIT="Y" 321 | elif [[ $METHOD == "install-explorer" ]]; then 322 | GIT_EXPLORER_COMMIT="Y" 323 | fi 324 | ;; 325 | "--git-origin") 326 | if [[ $METHOD == "install-core" ]]; then 327 | GIT_CORE_ORIGIN="$2" 328 | elif [[ $METHOD == "install-explorer" ]]; then 329 | GIT_EXPLORER_ORIGIN="$2" 330 | fi 331 | ;; 332 | "--git-use-ssh") 333 | GIT_USE_SSH="Y" 334 | ;; 335 | "--license-name") 336 | LICENSE_NAME="$2" 337 | ;; 338 | "--license-email") 339 | LICENSE_EMAIL="$2" 340 | ;; 341 | ## Starting options 342 | "--network") 343 | NETWORK="$2" 344 | ;; 345 | esac 346 | shift 347 | done 348 | 349 | post_args_process 350 | 351 | ARGS_PROCESSED="Y" 352 | } 353 | 354 | parse_explorer_args() 355 | { 356 | if [[ "$ARGS_PROCESSED" == "Y" ]]; then 357 | return 0 358 | fi 359 | 360 | parse_generic_args "$@" 361 | 362 | while [[ $# -ne 0 ]] ; do 363 | case $1 in 364 | "--path") 365 | EXPLORER_PATH_RAW="$2" 366 | EXPLORER_PATH=$(eval echo "$EXPLORER_PATH_RAW") 367 | ;; 368 | "--core-ip") 369 | CORE_IP="$2" 370 | if [ "$CORE_IP" == "127.0.0.1" ]; then 371 | CORE_IP=$(get_ip) 372 | fi 373 | ;; 374 | "--core-port") 375 | API_PORT="$2" 376 | ;; 377 | esac 378 | shift 379 | done 380 | 381 | write_args_env 382 | } 383 | 384 | parse_core_args() 385 | { 386 | if [[ "$ARGS_PROCESSED" == "Y" ]]; then 387 | return 0 388 | fi 389 | 390 | parse_generic_args "$@" 391 | 392 | while [[ $# -ne 0 ]] ; do 393 | case "$1" in 394 | "--path") 395 | BRIDGECHAIN_PATH_RAW="$2" 396 | BRIDGECHAIN_PATH=$(eval echo "$BRIDGECHAIN_PATH_RAW") 397 | ;; 398 | "--database") 399 | DATABASE_NAME="$2" 400 | ;; 401 | "--p2p-port") 402 | P2P_PORT="$2" 403 | ;; 404 | "--api-port") 405 | API_PORT="$2" 406 | ;; 407 | "--webhook-port") 408 | WEBHOOK_PORT="$2" 409 | ;; 410 | "--json-rpc-port") 411 | JSON_RPC_PORT="$2" 412 | ;; 413 | "--symbol") 414 | SYMBOL="$2" 415 | ;; 416 | "--mainnet-peers") 417 | MAINNET_PEERS="$2" 418 | ;; 419 | "--devnet-peers") 420 | DEVNET_PEERS="$2" 421 | ;; 422 | "--mainnet-prefix") 423 | MAINNET_PREFIX="$2" 424 | ;; 425 | "--devnet-prefix") 426 | DEVNET_PREFIX="$2" 427 | ;; 428 | "--testnet-prefix") 429 | TESTNET_PREFIX="$2" 430 | ;; 431 | "--blocktime") 432 | BLOCK_TIME="$2" 433 | ;; 434 | "--transactions-per-block") 435 | TXS_PER_BLOCK="$2" 436 | ;; 437 | "--reward-height-start") 438 | REWARD_HEIGHT_START="$2" 439 | ;; 440 | "--reward-per-block") 441 | REWARD_PER_BLOCK="$2" 442 | ;; 443 | "--vendorfield-length") 444 | VENDORFIELD_LENGTH="$2" 445 | ;; 446 | "--total-premine") 447 | TOTAL_PREMINE="$2" 448 | ;; 449 | "--force-network-start") 450 | FORCE_NETWORK_START="Y" 451 | ;; 452 | "--no-autoforger") 453 | AUTO_FORGER="N" 454 | ;; 455 | ## Static Fees 456 | "--fee-static-transfer") 457 | FEE_STATIC_TRANSFER="$2" 458 | ;; 459 | "--fee-static-vote") 460 | FEE_STATIC_VOTE="$2" 461 | ;; 462 | "--fee-static-second-signature") 463 | FEE_STATIC_SECOND_SIGNATURE="$2" 464 | ;; 465 | "--fee-static-delegate-registration") 466 | FEE_STATIC_DELEGATE_REGISTRATION="$2" 467 | ;; 468 | "--fee-static-multisig-registration") 469 | FEE_STATIC_MULTISIG_REGISTRATION="$2" 470 | ;; 471 | "--fee-static-ipfs") 472 | FEE_STATIC_IPFS="$2" 473 | ;; 474 | "--fee-static-multipayment") 475 | FEE_STATIC_MULTIPAYMENT="$2" 476 | ;; 477 | "--fee-static-delegate-resignation") 478 | FEE_STATIC_DELEGATE_RESIGNATION="$2" 479 | ;; 480 | 481 | ## Dynamic Fees 482 | "--fee-dynamic-enabled") 483 | FEE_DYNAMIC_ENABLED="Y" 484 | ;; 485 | "--fee-dynamic-pool-min-fee") 486 | FEE_DYNAMIC_POOL_MIN_FEE="$2" 487 | ;; 488 | "--fee-dynamic-broadcast-min-fee") 489 | FEE_DYNAMIC_BROADCAST_MIN_FEE="$2" 490 | ;; 491 | "--fee-dynamic-bytes-transfer") 492 | FEE_DYNAMIC_BYTES_TRANSFER="$2" 493 | ;; 494 | "--fee-dynamic-bytes-second-signature") 495 | FEE_DYNAMIC_BYTES_SECOND_SIGNATURE="$2" 496 | ;; 497 | "--fee-dynamic-bytes-delegate-registration") 498 | FEE_DYNAMIC_BYTES_DELEGATE_REGISTRATION="$2" 499 | ;; 500 | "--fee-dynamic-bytes-vote") 501 | FEE_DYNAMIC_BYTES_VOTE="$2" 502 | ;; 503 | "--fee-dynamic-bytes-multisig-registration") 504 | FEE_DYNAMIC_BYTES_MULTISIG_REGISTRATION="$2" 505 | ;; 506 | "--fee-dynamic-bytes-ipfs") 507 | FEE_DYNAMIC_BYTES_IPFS="$2" 508 | ;; 509 | "--fee-dynamic-bytes-multipayment") 510 | FEE_DYNAMIC_BYTES_MULTIPAYMENT="$2" 511 | ;; 512 | "--fee-dynamic-bytes-delegate-resignation") 513 | FEE_DYNAMIC_BYTES_DELEGATE_RESIGNATION="$2" 514 | ;; 515 | esac 516 | shift 517 | done 518 | 519 | write_args_env 520 | } 521 | 522 | write_args_env() 523 | { 524 | if [ ! -d "$XDG_CONFIG_HOME/deployer" ]; then 525 | mkdir -p "$XDG_CONFIG_HOME/deployer" 526 | fi 527 | 528 | rm -f "$XDG_CONFIG_HOME/deployer/.env" 529 | cat > "$XDG_CONFIG_HOME/deployer/.env" <<- EOF 530 | BRIDGECHAIN_PATH="$BRIDGECHAIN_PATH" 531 | EXPLORER_PATH="$EXPLORER_PATH" 532 | CHAIN_NAME="$CHAIN_NAME" 533 | TOKEN="$TOKEN" 534 | CORE_ALIAS="$CORE_ALIAS" 535 | CLI_ALIAS="$CLI_ALIAS" 536 | DATABASE_HOST="$DATABASE_HOST" 537 | DATABASE_PORT="$DATABASE_PORT" 538 | DATABASE_NAME="$DATABASE_NAME" 539 | CORE_IP="$CORE_IP" 540 | P2P_PORT="$P2P_PORT" 541 | API_PORT="$API_PORT" 542 | WEBHOOK_PORT="$WEBHOOK_PORT" 543 | JSON_RPC_PORT="$JSON_RPC_PORT" 544 | EXPLORER_IP="$EXPLORER_IP" 545 | EXPLORER_PORT="$EXPLORER_PORT" 546 | EXPLORER_URL="$EXPLORER_URL" 547 | SYMBOL="$SYMBOL" 548 | MAINNET_PEERS="$MAINNET_PEERS" 549 | DEVNET_PEERS="$DEVNET_PEERS" 550 | MAINNET_PREFIX="$MAINNET_PREFIX" 551 | DEVNET_PREFIX="$DEVNET_PREFIX" 552 | TESTNET_PREFIX="$TESTNET_PREFIX" 553 | INSTALL_DEPS="$INSTALL_DEPS" 554 | SKIP_DEPS="$SKIP_DEPS" 555 | INTERACTIVE="$INTERACTIVE" 556 | FEE_STATIC_TRANSFER="$FEE_STATIC_TRANSFER" 557 | FEE_STATIC_VOTE="$FEE_STATIC_VOTE" 558 | FEE_STATIC_SECOND_SIGNATURE="$FEE_STATIC_SECOND_SIGNATURE" 559 | FEE_STATIC_DELEGATE_REGISTRATION="$FEE_STATIC_DELEGATE_REGISTRATION" 560 | FEE_STATIC_MULTISIG_REGISTRATION="$FEE_STATIC_MULTISIG_REGISTRATION" 561 | FEE_STATIC_IPFS="$FEE_STATIC_IPFS" 562 | FEE_STATIC_MULTIPAYMENT="$FEE_STATIC_MULTIPAYMENT" 563 | FEE_STATIC_DELEGATE_RESIGNATION="$FEE_STATIC_DELEGATE_RESIGNATION" 564 | FEE_DYNAMIC_ENABLED="$FEE_DYNAMIC_ENABLED" 565 | FEE_DYNAMIC_POOL_MIN_FEE="$FEE_DYNAMIC_POOL_MIN_FEE" 566 | FEE_DYNAMIC_BROADCAST_MIN_FEE="$FEE_DYNAMIC_BROADCAST_MIN_FEE" 567 | FEE_DYNAMIC_BYTES_TRANSFER="$FEE_DYNAMIC_BYTES_TRANSFER" 568 | FEE_DYNAMIC_BYTES_SECOND_SIGNATURE="$FEE_DYNAMIC_BYTES_SECOND_SIGNATURE" 569 | FEE_DYNAMIC_BYTES_DELEGATE_REGISTRATION="$FEE_DYNAMIC_BYTES_DELEGATE_REGISTRATION" 570 | FEE_DYNAMIC_BYTES_VOTE="$FEE_DYNAMIC_BYTES_VOTE" 571 | FEE_DYNAMIC_BYTES_MULTISIG_REGISTRATION="$FEE_DYNAMIC_BYTES_MULTISIG_REGISTRATION" 572 | FEE_DYNAMIC_BYTES_IPFS="$FEE_DYNAMIC_BYTES_IPFS" 573 | FEE_DYNAMIC_BYTES_MULTIPAYMENT="$FEE_DYNAMIC_BYTES_MULTIPAYMENT" 574 | FEE_DYNAMIC_BYTES_DELEGATE_RESIGNATION="$FEE_DYNAMIC_BYTES_DELEGATE_RESIGNATION" 575 | FORGERS="$FORGERS" 576 | BLOCK_TIME="$BLOCK_TIME" 577 | TXS_PER_BLOCK="$TXS_PER_BLOCK" 578 | TOTAL_PREMINE="$TOTAL_PREMINE" 579 | REWARD_HEIGHT_START="$REWARD_HEIGHT_START" 580 | REWARD_PER_BLOCK="$REWARD_PER_BLOCK" 581 | VENDORFIELD_LENGTH="$VENDORFIELD_LENGTH" 582 | ARGS_PROCESSED="$ARGS_PROCESSED" 583 | CONFIG_PROCESSED="$CONFIG_PROCESSED" 584 | AUTO_FORGER="$AUTO_FORGER" 585 | FORCE_NETWORK_START="$FORCE_NETWORK_START" 586 | NETWORK="$NETWORK" 587 | GIT_CORE_COMMIT="$GIT_CORE_COMMIT" 588 | GIT_CORE_ORIGIN="$GIT_CORE_ORIGIN" 589 | GIT_EXPLORER_COMMIT="$GIT_EXPLORER_COMMIT" 590 | GIT_EXPLORER_ORIGIN="$GIT_EXPLORER_ORIGIN" 591 | GIT_USE_SSH="$GIT_USE_SSH" 592 | LICENSE_NAME="$LICENSE_NAME" 593 | LICENSE_EMAIL="$LICENSE_EMAIL" 594 | EOF 595 | } 596 | -------------------------------------------------------------------------------- /app/config-core.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | app_install_core_configuration() 4 | { 5 | parse_core_args "$@" 6 | 7 | if [ ! -d "$BRIDGECHAIN_PATH/packages/core" ]; then 8 | error "Bridgechain path could not be found. Use '--path' to specify the location it was installed." 9 | 10 | return 11 | fi 12 | 13 | cd "$BRIDGECHAIN_PATH/packages/core" 14 | 15 | local CONFIG_PATH_MAINNET="$(cd ~ && pwd)/.bridgechain/mainnet/$CHAIN_NAME" 16 | local CONFIG_PATH_DEVNET="$(cd ~ && pwd)/.bridgechain/devnet/$CHAIN_NAME" 17 | local CONFIG_PATH_TESTNET="$(cd ~ && pwd)/.bridgechain/testnet/$CHAIN_NAME" 18 | local CONFIG_PATH_CORE="$XDG_CONFIG_HOME/${CORE_ALIAS}-core" 19 | 20 | # Alias 21 | local ALIAS_PATH="" 22 | if [ -f "$HOME/.bash_aliases" ]; then 23 | local ALIAS_PATH="$HOME/.bash_aliases" 24 | elif [ -f "$HOME/.bashrc" ]; then 25 | local ALIAS_PATH="$HOME/.bashrc" 26 | fi 27 | 28 | if [[ ! -z "$ALIAS_PATH" && -z $(fgrep "alias $CORE_ALIAS=" "$ALIAS_PATH") ]]; then 29 | echo "alias $CORE_ALIAS=\"$BRIDGECHAIN_PATH/packages/core/bin/run\"" >> "$ALIAS_PATH" 30 | echo "The command to interact with your bridgechain is '$CORE_ALIAS'" 31 | fi 32 | 33 | # Production 34 | if [[ -d "$CONFIG_PATH_MAINNET" && ! -d "${CONFIG_PATH_CORE}/mainnet" ]]; then 35 | heading "Installing [mainnet] configuration to ${CONFIG_PATH_CORE}/mainnet..." 36 | 37 | ./bin/run config:publish --network "mainnet" &>/dev/null || true 38 | 39 | if [[ ! -f "${CONFIG_PATH_CORE}/mainnet/delegates.json" ]]; then 40 | cp "$CONFIG_PATH_MAINNET/delegates.json" "${CONFIG_PATH_CORE}/mainnet/delegates.json" 41 | fi 42 | 43 | success "[mainnet] configuration Installed!" 44 | fi 45 | 46 | # Development 47 | if [[ -d "$CONFIG_PATH_DEVNET" && ! -d "${CONFIG_PATH_CORE}/devnet" ]]; then 48 | heading "Installing [devnet] configuration to ${CONFIG_PATH_CORE}/devnet..." 49 | 50 | ./bin/run config:publish --network "devnet" &>/dev/null || true 51 | 52 | if [[ ! -f "${CONFIG_PATH_CORE}/devnet/delegates.json" ]]; then 53 | cp "$CONFIG_PATH_DEVNET/delegates.json" "${CONFIG_PATH_CORE}/devnet/delegates.json" 54 | fi 55 | 56 | success "[devnet] configuration Installed!" 57 | fi 58 | 59 | # Test 60 | if [[ -d "$CONFIG_PATH_TESTNET" && ! -d "${CONFIG_PATH_CORE}/testnet" ]]; then 61 | heading "Installing [testnet] configuration to ${CONFIG_PATH_CORE}/testnet..." 62 | 63 | ./bin/run config:publish --network "testnet" &>/dev/null || true 64 | 65 | if [[ ! -f "${CONFIG_PATH_CORE}/testnet/delegates.json" ]]; then 66 | cp "$CONFIG_PATH_TESTNET/delegates.json" "${CONFIG_PATH_CORE}/testnet/delegates.json" 67 | fi 68 | 69 | success "[testnet] configuration Installed!" 70 | fi 71 | } 72 | -------------------------------------------------------------------------------- /app/process-core.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | process_core_start() 4 | { 5 | process_core_stop "$@" 6 | 7 | heading "Starting..." 8 | parse_core_args "$@" 9 | 10 | if [ ! -d "$BRIDGECHAIN_PATH/packages/core" ]; then 11 | error "Bridgechain path could not be found. Use '--path' to specify the location it was installed." 12 | 13 | return 14 | fi 15 | 16 | app_install_core_configuration 17 | 18 | cd "$BRIDGECHAIN_PATH/packages/core" 19 | local NETWORK=$(echo "$NETWORK" | awk '{print tolower($0)}') 20 | 21 | if [ -z "$NETWORK" ]; then 22 | abort 1 "Network must be specified" 23 | elif [ ! -d "$XDG_CONFIG_HOME/${CORE_ALIAS}-core/$NETWORK" ]; then 24 | echo "$XDG_CONFIG_HOME/${CORE_ALIAS}-core/$NETWORK" 25 | abort 1 "Network '$NETWORK' does not exist" 26 | fi 27 | 28 | if [[ "$AUTO_FORGER" == "Y" ]]; then 29 | local LAST_HEIGHT=$(__core_check_last_height "$CONFIG_PATH") 30 | if [[ "$LAST_HEIGHT" > "0" ]]; then 31 | __core_start 32 | else 33 | ./bin/run relay:start --network="$NETWORK" --networkStart --ignoreMinimumNetworkReach --env=test 34 | if [ $(sh -c "jq '.secrets | length' $XDG_CONFIG_HOME/${CORE_ALIAS}-core/$NETWORK/delegates.json") <> "0" ]; then 35 | ./bin/run forger:start --network="$NETWORK" --env=test 36 | else 37 | warning "No forging delegates found in 'delegates.json' config" 38 | fi 39 | fi 40 | else 41 | __core_start 42 | fi 43 | success "Start OK!" 44 | 45 | local WATCH_LOGS="N" 46 | if [[ "$INTERACTIVE" == "Y" ]]; then 47 | read -p "Watch Logs? [y/N]: " WATCH_LOGS 48 | fi 49 | if [[ "$WATCH_LOGS" =~ ^(yes|y|Y) ]]; then 50 | process_core_logs 51 | fi 52 | } 53 | 54 | __core_start() { 55 | if [[ "$FORCE_NETWORK_START" == "Y" ]]; then 56 | ./bin/run relay:start --network="$NETWORK" --networkStart --ignoreMinimumNetworkReach 57 | else 58 | ./bin/run relay:start --network="$NETWORK" --ignoreMinimumNetworkReach 59 | fi 60 | 61 | if [ $(sh -c "jq '.secrets | length' $XDG_CONFIG_HOME/${CORE_ALIAS}-core/$NETWORK/delegates.json") <> "0" ]; then 62 | ./bin/run forger:start --network="$NETWORK" 63 | else 64 | warning "No forging delegates found in 'delegates.json' config" 65 | fi 66 | } 67 | 68 | __core_check_last_height() { 69 | local CONFIG_PATH="$1" 70 | local DATABASE_NAME=$(cat "$XDG_CONFIG_HOME/${CORE_ALIAS}-core/$NETWORK/.env" | fgrep 'CORE_DB_DATABASE=' | awk -F'=' '{print $2}') 71 | psql -qtAX -d "$DATABASE_NAME" -c "SELECT height FROM blocks ORDER BY height DESC LIMIT 1" 2>/dev/null || echo 0 72 | } 73 | 74 | process_core_stop() 75 | { 76 | heading "Stopping..." 77 | parse_core_args "$@" 78 | 79 | local NETWORK=$(echo "$NETWORK" | awk '{print tolower($0)}') 80 | if [[ -d "$BRIDGECHAIN_PATH/packages/core" && ! -z "$NETWORK" ]]; then 81 | cd "$BRIDGECHAIN_PATH/packages/core" 82 | 83 | if [ ! -d "$XDG_CONFIG_HOME/${CORE_ALIAS}-core/$NETWORK" ]; then 84 | error "Network '$NETWORK' does not exist" 85 | 86 | return 87 | fi 88 | 89 | ./bin/run relay:stop --network="$NETWORK" &>/dev/null || true 90 | ./bin/run forger:stop --network="$NETWORK" &>/dev/null || true 91 | else 92 | for PROCESS in $(pm2 list | fgrep "online" | egrep -v "explorer|────|^│ App nam" | awk '{print $2}'); do 93 | pm2 stop "$PROCESS" &>/dev/null || true 94 | done 95 | fi 96 | 97 | success "Stop OK!" 98 | } 99 | 100 | process_core_restart() 101 | { 102 | heading "Restarting..." 103 | process_core_stop "$@" 104 | process_core_start "$@" 105 | success "Restart OK!" 106 | } 107 | 108 | process_core_logs() 109 | { 110 | pm2 logs 111 | } 112 | -------------------------------------------------------------------------------- /app/process-explorer.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | process_explorer_start() 4 | { 5 | process_explorer_stop 6 | 7 | heading "Starting Explorer..." 8 | 9 | parse_explorer_args "$@" 10 | 11 | if [ -z "$NETWORK" ]; then 12 | abort 1 "Network must be specified" 13 | elif [ ! -f "$EXPLORER_PATH/networks/$NETWORK.json" ]; then 14 | abort 1 "Network '$NETWORK' does not exist" 15 | fi 16 | 17 | cd $EXPLORER_PATH 18 | ./start-explorer.sh "$NETWORK" 19 | 20 | success "Start OK!" 21 | } 22 | 23 | process_explorer_stop() 24 | { 25 | heading "Stopping..." 26 | pm2 stop explorer &>/dev/null || true 27 | success "Stop OK!" 28 | } 29 | 30 | process_explorer_restart() 31 | { 32 | heading "Restarting..." 33 | process_explorer_stop "$@" 34 | process_explorer_start "$@" 35 | success "Restart OK!" 36 | } 37 | -------------------------------------------------------------------------------- /app/update-core-relay.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | TARGET_BRANCH="REPLACE_WITH_TARGET_BRANCH" 4 | TARGET_VERSION="REPLACE_WITH_TARGET_VERSION" 5 | BRIDGECHAIN_BIN=$(jq -r '.oclif.bin' "./packages/core/package.json") 6 | 7 | update_bridgechain() 8 | { 9 | run_checks 10 | 11 | info "Stopping core..." 12 | pm2 stop all 13 | 14 | info "Updating files..." 15 | merge_core_update || error_setting_target_branch 16 | 17 | info "Building Core..." 18 | YARN_SETUP="N" 19 | while [ "$YARN_SETUP" == "N" ]; do 20 | YARN_SETUP="Y" 21 | yarn setup || YARN_SETUP="N" 22 | if [[ "$YARN_SETUP" == "N" ]]; then 23 | read -p "Failed to setup updated core. Retry? [Y/n]: " RETRY_SETUP 24 | fi 25 | if [[ "$RETRY_SETUP" =~ ^(no|n|N) ]]; then 26 | exit 1 27 | fi 28 | done 29 | 30 | reset_plugins_js 31 | 32 | success "Done." 33 | } 34 | 35 | red=$(tput setaf 1) 36 | green=$(tput setaf 2) 37 | yellow=$(tput setaf 3) 38 | lila=$(tput setaf 4) 39 | pink=$(tput setaf 5) 40 | blue=$(tput setaf 6) 41 | bold=$(tput bold) 42 | reset=$(tput sgr0) 43 | timestamp=$(date +%Y-%m-%d_%H-%M-%S) 44 | 45 | heading() 46 | { 47 | echo "${lila}==>${reset}${bold} $1${reset}" 48 | } 49 | 50 | success() 51 | { 52 | echo "${green}==>${reset}${bold} $1${reset}" 53 | } 54 | 55 | info() 56 | { 57 | echo "${blue}==>${reset}${bold} $1${reset}" 58 | } 59 | 60 | warning() 61 | { 62 | echo "${yellow}==>${reset}${bold} $1${reset}" 63 | } 64 | 65 | error() 66 | { 67 | echo "${red}==>${reset}${bold} $1${reset}" 68 | } 69 | 70 | check_for_core_directory() 71 | { 72 | test -f "./packages/core/package.json" || FAILED="Y" 73 | if [ "$FAILED" == "Y" ]; then 74 | error "You must run this script from inside of the Core directory." 75 | exit 1 76 | fi 77 | } 78 | 79 | check_for_dirty_directory() 80 | { 81 | if output=$(git status --untracked-files=no --porcelain) && [ -n "$output" ]; then 82 | git status 83 | warning "Please commit changes in this repository before continuing. If you'd like to discard them, run ${reset}${bold}${pink}git reset --hard${reset}" 84 | exit 1 85 | fi 86 | } 87 | 88 | merge_core_update() 89 | { 90 | git reset --hard 91 | git branch --set-upstream-to=origin/"$TARGET_BRANCH" "$TARGET_BRANCH" 92 | git pull origin "$TARGET_BRANCH" 93 | } 94 | 95 | check_for_target_branch() 96 | { 97 | git fetch 98 | local HAS_REMOTE=$(git branch -a | fgrep -o "remotes/origin/$TARGET_BRANCH") 99 | if [ -n "$HAS_REMOTE" ]; then 100 | git checkout "$TARGET_BRANCH" 101 | else 102 | error "The target branch $TARGET_BRANCH doesn't exist. Please verify your TARGET_BRANCH and remote." 103 | exit 1 104 | fi 105 | } 106 | 107 | error_setting_target_branch() 108 | { 109 | error "Something went wrong. Make sure that the branch $TARGET_BRANCH exists in the remote repository, and try again." 110 | exit 1 111 | } 112 | 113 | run_checks() 114 | { 115 | check_for_core_directory 116 | check_for_dirty_directory 117 | check_for_target_branch 118 | } 119 | 120 | reset_plugins_js() 121 | { 122 | local CONFIG_PATH="./packages/core/bin/config" 123 | local PUBLISHED_CONFIG_PATH="$HOME/.config/REPLACE_WITH_CHAIN_NAME-core" 124 | 125 | if [[ -f "$PUBLISHED_CONFIG_PATH/mainnet/plugins.js" ]]; then 126 | mv "$PUBLISHED_CONFIG_PATH/mainnet/plugins.js" "$PUBLISHED_CONFIG_PATH/mainnet/plugins_2.3_$timestamp.js" 127 | cp "$CONFIG_PATH/mainnet/plugins.js" "$PUBLISHED_CONFIG_PATH/mainnet/plugins.js" 128 | fi 129 | 130 | if [[ -f "$PUBLISHED_CONFIG_PATH/devnet/plugins.js" ]]; then 131 | mv "$PUBLISHED_CONFIG_PATH/devnet/plugins.js" "$PUBLISHED_CONFIG_PATH/devnet/plugins_2.3_$timestamp.js" 132 | cp "$CONFIG_PATH/devnet/plugins.js" "$PUBLISHED_CONFIG_PATH/devnet/plugins.js" 133 | fi 134 | 135 | if [[ -f "$PUBLISHED_CONFIG_PATH/testnet/plugins.js" ]]; then 136 | mv "$PUBLISHED_CONFIG_PATH/testnet/plugins.js" "$PUBLISHED_CONFIG_PATH/testnet/plugins_2.3_$timestamp.js" 137 | cp "$CONFIG_PATH/testnet/plugins.js" "$PUBLISHED_CONFIG_PATH/testnet/plugins.js" 138 | fi 139 | } 140 | 141 | read -p "This script will update Core to $TARGET_VERSION. Would you like to continue? [y/N]: " choice 142 | if [[ "$choice" =~ ^(yes|y|Y) ]]; then 143 | update_bridgechain 144 | fi 145 | -------------------------------------------------------------------------------- /app/update-core.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | update_core_handle() 4 | { 5 | update_core_resolve_vars 6 | 7 | if [ "$CHAIN_VERSION" == "$TARGET_VERSION" ]; then 8 | info "This chain is already up to date." 9 | else 10 | heading "Bridgechain version: $CHAIN_VERSION" 11 | read -p "Would you like to update Core to version $TARGET_VERSION? [y/N]: " choice 12 | 13 | if [[ "$choice" =~ ^(yes|y|Y) ]]; then 14 | 15 | process_core_stop 16 | 17 | update_core_add_upstream_remote 18 | 19 | update_core_merge_from_upstream 20 | 21 | update_core_resolve_conflicts 22 | 23 | heading "Applying migration updates..." 24 | 25 | update_core_change_block_reward_from_number_to_string 26 | 27 | update_core_update_package_json 28 | 29 | update_core_make_update_relay_script 30 | 31 | update_core_commit_changes 32 | 33 | heading "Done" 34 | 35 | heading "Building Core..." 36 | 37 | yarn setup 38 | 39 | update_core_reset_plugins_js 40 | 41 | update_core_prompt_to_push_changes 42 | 43 | success "Finished." 44 | 45 | fi 46 | fi 47 | } 48 | 49 | update_core_resolve_vars() 50 | { 51 | TARGET_VERSION="2.6.57" 52 | BRIDGECHAIN_BIN=$(jq -r '.oclif.bin' "$BRIDGECHAIN_PATH/packages/core/package.json") 53 | CHAIN_VERSION=$(jq -r '.version' "$BRIDGECHAIN_PATH/packages/core/package.json") 54 | NETWORKS_PATH="$BRIDGECHAIN_PATH/packages/crypto/src/networks" 55 | TIMESTAMP=$(date +%Y-%m-%d_%H-%M-%S) 56 | } 57 | 58 | update_core_add_upstream_remote() 59 | { 60 | heading "Fetching from upstream..." 61 | cd "$BRIDGECHAIN_PATH" 62 | git remote add upstream https://github.com/ArkEcosystem/core.git > /dev/null 2>&1 || true 63 | git fetch && git fetch --tags upstream 64 | } 65 | 66 | update_core_merge_from_upstream() 67 | { 68 | heading "Merging from upstream..." 69 | git config --global user.email "support@ark.io" 70 | git config --global user.name "ARK Deployer" 71 | git checkout -b update/"$TARGET_VERSION" || git checkout -b update/"${TARGET_VERSION}_${TIMESTAMP}" 72 | git merge "$TARGET_VERSION" || true 73 | info "Done" 74 | } 75 | 76 | update_core_resolve_conflicts() 77 | { 78 | heading "Resolving merge conflicts..." 79 | git checkout --ours "$NETWORKS_PATH/devnet/genesisBlock.json" 80 | git checkout --ours "$NETWORKS_PATH/devnet/milestones.json" 81 | git checkout --ours "$NETWORKS_PATH/mainnet/exceptions.json" 82 | git checkout --ours "$NETWORKS_PATH/mainnet/genesisBlock.json" 83 | git checkout --ours "$NETWORKS_PATH/mainnet/milestones.json" 84 | git checkout --ours "$NETWORKS_PATH/testnet/genesisBlock.json" 85 | git checkout --ours "$NETWORKS_PATH/testnet/milestones.json" 86 | git checkout --theirs packages/core/bin/config/mainnet/plugins.js 87 | git checkout --theirs packages/core/bin/config/devnet/plugins.js 88 | git checkout --theirs packages/core/bin/config/testnet/plugins.js 89 | git checkout --ours install.sh 90 | info "Done" 91 | } 92 | 93 | update_core_change_block_reward_from_number_to_string() 94 | { 95 | jq '.reward = "0"' "$NETWORKS_PATH/mainnet/genesisBlock.json" \ 96 | > "$NETWORKS_PATH/mainnet/genesisBlock.json.tmp" \ 97 | && mv "$NETWORKS_PATH/mainnet/genesisBlock.json.tmp" \ 98 | "$NETWORKS_PATH/mainnet/genesisBlock.json" 99 | 100 | jq '.reward = "0"' "$NETWORKS_PATH/devnet/genesisBlock.json" \ 101 | > "$NETWORKS_PATH/devnet/genesisBlock.json.tmp" \ 102 | && mv "$NETWORKS_PATH/devnet/genesisBlock.json.tmp" \ 103 | "$NETWORKS_PATH/devnet/genesisBlock.json" 104 | 105 | jq '.reward = "0"' "$NETWORKS_PATH/testnet/genesisBlock.json" \ 106 | > "$NETWORKS_PATH/testnet/genesisBlock.json.tmp" \ 107 | && mv "$NETWORKS_PATH/testnet/genesisBlock.json.tmp" \ 108 | "$NETWORKS_PATH/testnet/genesisBlock.json" 109 | } 110 | 111 | update_core_update_package_json() 112 | { 113 | git checkout --ours packages/core/package.json && cat packages/core/package.json \ 114 | >| packages/core/package.json.old && git checkout --theirs packages/core/package.json 115 | 116 | package_temp="packages/core/package.json.old" 117 | 118 | jq --arg var "$(jq -r '.name' "$package_temp")" '.name = $var' packages/core/package.json \ 119 | >| packages/core/package.json.tmp && mv packages/core/package.json.tmp packages/core/package.json 120 | 121 | jq --argjson var "$(jq -r '.bin' "$package_temp")" '.bin = $var' packages/core/package.json \ 122 | >| packages/core/package.json.tmp && mv packages/core/package.json.tmp packages/core/package.json 123 | 124 | jq --argjson var "$(jq -r '.bin' "$package_temp")" '.scripts += $var' packages/core/package.json \ 125 | >| packages/core/package.json.tmp && mv packages/core/package.json.tmp packages/core/package.json 126 | 127 | jq --arg var "$(jq -r '.description' "$package_temp")" '.description = $var' packages/core/package.json \ 128 | >| packages/core/package.json.tmp && mv packages/core/package.json.tmp packages/core/package.json 129 | 130 | jq --arg var "$BRIDGECHAIN_BIN" '.oclif.bin = $var' packages/core/package.json \ 131 | >| packages/core/package.json.tmp && mv packages/core/package.json.tmp packages/core/package.json 132 | 133 | rm "$package_temp" 134 | } 135 | 136 | update_core_make_update_relay_script() 137 | { 138 | local current_branch=$(git rev-parse --abbrev-ref HEAD) 139 | local update_script_path="$BRIDGECHAIN_PATH/upgrade/$TARGET_VERSION/update.sh" 140 | 141 | mkdir -p "$BRIDGECHAIN_PATH/upgrade/$TARGET_VERSION/" 142 | cp "$ROOT_PATH/app/update-core-relay.sh" "$update_script_path" 143 | 144 | sed -i "s@REPLACE_WITH_TARGET_BRANCH@$current_branch@g" "$update_script_path" 145 | sed -i "s@REPLACE_WITH_TARGET_VERSION@$TARGET_VERSION@g" "$update_script_path" 146 | sed -i "s@REPLACE_WITH_CHAIN_NAME@$CHAIN_NAME@g" "$update_script_path" 147 | 148 | git add "$BRIDGECHAIN_PATH/upgrade/$TARGET_VERSION/update.sh" 149 | } 150 | 151 | update_core_commit_changes() 152 | { 153 | git add install.sh 154 | git add packages/core/bin/config/mainnet/plugins.js 155 | git add packages/core/bin/config/testnet/plugins.js 156 | git add packages/core/bin/config/devnet/plugins.js 157 | git add packages/core/package.json 158 | git add packages/crypto/src/networks/devnet/genesisBlock.json 159 | git add packages/crypto/src/networks/devnet/milestones.json 160 | git add packages/crypto/src/networks/mainnet/exceptions.json 161 | git add packages/crypto/src/networks/mainnet/genesisBlock.json 162 | git add packages/crypto/src/networks/mainnet/milestones.json 163 | git add packages/crypto/src/networks/testnet/genesisBlock.json 164 | git add packages/crypto/src/networks/testnet/milestones.json 165 | 166 | git commit --no-verify -m "chore: upgrade to core v$TARGET_VERSION" 167 | } 168 | 169 | update_core_reset_plugins_js() 170 | { 171 | local CONFIG_PATH="$BRIDGECHAIN_PATH/packages/core/bin/config" 172 | local PUBLISHED_CONFIG_PATH="$HOME/.config/$CHAIN_NAME-core" 173 | 174 | if [[ -f "$PUBLISHED_CONFIG_PATH/mainnet/plugins.js" ]]; then 175 | mv "$PUBLISHED_CONFIG_PATH/mainnet/plugins.js" "$PUBLISHED_CONFIG_PATH/mainnet/plugins_2.3_$TIMESTAMP.js" 176 | cp "$CONFIG_PATH/mainnet/plugins.js" "$PUBLISHED_CONFIG_PATH/mainnet/plugins.js" 177 | fi 178 | 179 | if [[ -f "$PUBLISHED_CONFIG_PATH/devnet/plugins.js" ]]; then 180 | mv "$PUBLISHED_CONFIG_PATH/devnet/plugins.js" "$PUBLISHED_CONFIG_PATH/devnet/plugins_2.3_$TIMESTAMP.js" 181 | cp "$CONFIG_PATH/devnet/plugins.js" "$PUBLISHED_CONFIG_PATH/devnet/plugins.js" 182 | fi 183 | 184 | if [[ -f "$PUBLISHED_CONFIG_PATH/testnet/plugins.js" ]]; then 185 | mv "$PUBLISHED_CONFIG_PATH/testnet/plugins.js" "$PUBLISHED_CONFIG_PATH/testnet/plugins_2.3_$TIMESTAMP.js" 186 | cp "$CONFIG_PATH/testnet/plugins.js" "$PUBLISHED_CONFIG_PATH/testnet/plugins.js" 187 | fi 188 | } 189 | 190 | update_core_prompt_to_push_changes() 191 | { 192 | read -p "Your bridgechain has been updated! Wou like to push it to your git repository? [y/N]: " choice 193 | 194 | if [[ "$choice" =~ ^(yes|y|Y) ]]; then 195 | local current_branch=$(git rev-parse --abbrev-ref HEAD) 196 | git push --no-verify --set-upstream origin "$current_branch" 197 | fi 198 | } 199 | -------------------------------------------------------------------------------- /app/var.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ROOT_PATH=$(cd "$(dirname $(dirname "${BASH_SOURCE[0]}"))" >/dev/null 2>&1 && pwd) 4 | BRIDGECHAIN_PATH="$HOME/core-bridgechain" 5 | BRIDGECHAIN_PATH_RAW="\$HOME/core-bridgechain" 6 | EXPLORER_PATH="$HOME/core-explorer" 7 | EXPLORER_PATH_RAW="\$HOME/core-explorer" 8 | CHAIN_NAME="bridgechain" 9 | TOKEN="MINE" 10 | CORE_ALIAS="mine" 11 | CLI_ALIAS="CHAIN_NAME" # Used to determine whether to use CHAIN_NAME or TOKEN in in the "CORE_ALIAS" var 12 | DATABASE_HOST="localhost" 13 | DATABASE_PORT="5432" 14 | DATABASE_NAME="core_$CHAIN_NAME" 15 | CORE_IP="0.0.0.0" 16 | P2P_PORT="4102" 17 | API_PORT="4103" 18 | WEBHOOK_PORT="4104" 19 | JSON_RPC_PORT="8080" 20 | EXPLORER_IP="127.0.0.1" 21 | EXPLORER_PORT="4200" 22 | EXPLORER_URL="http://$EXPLORER_IP:$EXPLORER_PORT" 23 | SYMBOL="M" 24 | MAINNET_PEERS="" 25 | DEVNET_PEERS="" 26 | MAINNET_PREFIX="M" 27 | DEVNET_PREFIX="D" 28 | TESTNET_PREFIX="T" 29 | INSTALL_DEPS="N" 30 | SKIP_DEPS="N" 31 | INTERACTIVE="Y" 32 | if [[ $METHOD == "install-explorer" ]]; then 33 | CORE_IP="127.0.0.1" 34 | EXPLORER_IP="0.0.0.0" 35 | fi 36 | 37 | ## Constants 38 | ## Fees - Static 39 | FEE_STATIC_TRANSFER=10000000 40 | FEE_STATIC_VOTE=100000000 41 | FEE_STATIC_SECOND_SIGNATURE=500000000 42 | FEE_STATIC_DELEGATE_REGISTRATION=2500000000 43 | FEE_STATIC_MULTISIG_REGISTRATION=500000000 44 | FEE_STATIC_IPFS=500000000 45 | FEE_STATIC_MULTIPAYMENT=10000000 46 | FEE_STATIC_DELEGATE_RESIGNATION=2500000000 47 | 48 | ## Fees - Dynamic 49 | FEE_DYNAMIC_ENABLED="N" 50 | FEE_DYNAMIC_POOL_MIN_FEE=3000 51 | FEE_DYNAMIC_BROADCAST_MIN_FEE=3000 52 | FEE_DYNAMIC_BYTES_TRANSFER=100 53 | FEE_DYNAMIC_BYTES_SECOND_SIGNATURE=250 54 | FEE_DYNAMIC_BYTES_DELEGATE_REGISTRATION=400000 55 | FEE_DYNAMIC_BYTES_VOTE=100 56 | FEE_DYNAMIC_BYTES_MULTISIG_REGISTRATION=500 57 | FEE_DYNAMIC_BYTES_IPFS=250 58 | FEE_DYNAMIC_BYTES_MULTIPAYMENT=500 59 | FEE_DYNAMIC_BYTES_DELEGATE_RESIGNATION=400000 60 | 61 | ## Forging Delegates 62 | FORGERS=51 63 | 64 | ## Block time (seconds) 65 | BLOCK_TIME=8 66 | 67 | ## Max Transactions per Block 68 | TXS_PER_BLOCK=150 69 | 70 | ## Total Premined Tokens 71 | TOTAL_PREMINE=2100000000000000 72 | 73 | ## Rewards 74 | ## Start Block Height 75 | REWARD_HEIGHT_START=75600 76 | ## ARK reward per Block 77 | REWARD_PER_BLOCK=200000000 78 | 79 | ## VendorField/SmartBridge Length 80 | VENDORFIELD_LENGTH=255 81 | 82 | ## Flag to indicate if args has been processed 83 | ARGS_PROCESSED="N" 84 | 85 | ## Flag to indicate if JSON config has been processed 86 | CONFIG_PROCESSED="N" 87 | 88 | ## Start core options 89 | AUTO_FORGER="Y" 90 | FORCE_NETWORK_START="N" 91 | NETWORK="" 92 | 93 | ## Git 94 | GIT_CORE_COMMIT="N" 95 | GIT_CORE_ORIGIN="" 96 | GIT_EXPLORER_COMMIT="N" 97 | GIT_EXPLORER_ORIGIN="" 98 | GIT_USE_SSH="N" 99 | 100 | ## License 101 | LICENSE_NAME="" 102 | LICENSE_EMAIL="" 103 | -------------------------------------------------------------------------------- /bootstrap/app.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${__dir}/app/var.sh" 4 | source "${__dir}/app/args.sh" 5 | source "${__dir}/app/config-core.sh" 6 | source "${__dir}/app/app-core.sh" 7 | source "${__dir}/app/app-explorer.sh" 8 | source "${__dir}/app/process-core.sh" 9 | source "${__dir}/app/process-explorer.sh" 10 | source "${__dir}/app/update-core.sh" 11 | 12 | if [ -z "$XDG_CONFIG_HOME" ]; then 13 | export XDG_CONFIG_HOME="$HOME/.config" 14 | fi 15 | -------------------------------------------------------------------------------- /bootstrap/lib.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${__dir}/lib/utils.sh" 4 | source "${__dir}/lib/alerts.sh" 5 | source "${__dir}/lib/errors.sh" 6 | 7 | if [[ "$BASH_VERSINFO" < 4 ]]; then 8 | abort 1 'You need at least bash-4.0 to run this script.' 9 | fi 10 | 11 | if [ "$(id -u)" = "0" ]; then 12 | abort 1 'This script should NOT be started using sudo or as the root user!' 13 | fi 14 | 15 | if [[ -z "${HOME}" ]]; then 16 | abort 1 "\$HOME is not defined. Please set it first." 17 | fi 18 | 19 | source "${__dir}/lib/rtfm.sh" 20 | source "${__dir}/lib/dependencies.sh" 21 | source "${__dir}/lib/manifest.sh" 22 | source "${__dir}/lib/args.sh" 23 | -------------------------------------------------------------------------------- /bridgechain.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | [[ "${DEBUG}" == 'true' ]] && set -o xtrace 4 | set -o errexit 5 | set -o pipefail 6 | set -o noclobber 7 | 8 | shopt -s extglob 9 | 10 | readonly __dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 11 | readonly __file="${__dir}/$(basename "${BASH_SOURCE[0]}")" 12 | readonly __base="$(basename ${__file} .sh)" 13 | readonly __root="$(cd "$(dirname "${__dir}")" && pwd)" 14 | readonly __manifest="${__dir}/manifest.json" 15 | 16 | readonly -a DEPENDENCIES_PROGRAMS=('postgresql postgresql-contrib build-essential libcairo2-dev pkg-config libtool autoconf automake python git curl jq libpq-dev ntp') 17 | readonly -a DEPENDENCIES_NODEJS=('pm2 grunt-cli node-sass lerna') 18 | 19 | source "${__dir}/bootstrap/lib.sh" 20 | source "${__dir}/bootstrap/app.sh" 21 | 22 | main() 23 | { 24 | parse_args "$@" 25 | 26 | app_install_core_configuration 27 | 28 | trap cleanup SIGINT SIGTERM SIGKILL 29 | } 30 | 31 | [[ "$0" == "$BASH_SOURCE" ]] && main "$@" 32 | -------------------------------------------------------------------------------- /config.sample.json: -------------------------------------------------------------------------------- 1 | { 2 | "coreIp": "localhost", 3 | "p2pPort": 4102, 4 | "apiPort": 4103, 5 | "webhookPort": 4104, 6 | "jsonRpcPort": 8080, 7 | "explorerIp": "0.0.0.0", 8 | "explorerPort": 4200, 9 | "chainName": "bridgechain", 10 | "token": "MINE", 11 | "databaseHost": "localhost", 12 | "databasePort": "5432", 13 | "databaseName": "core_bridgechain", 14 | "symbol": "M", 15 | "mainnetPeers": ["127.0.0.1", "127.0.0.2", "127.0.0.3"], 16 | "devnetPeers": ["127.0.0.4", "127.0.0.5", "127.0.0.6"], 17 | "mainnetPrefix": "M", 18 | "devnetPrefix": "D", 19 | "testnetPrefix": "T", 20 | "fees": { 21 | "static": { 22 | "transfer": 10000000, 23 | "vote": 100000000, 24 | "secondSignature": 500000000, 25 | "delegateRegistration": 2500000000, 26 | "multiSignature": 500000000, 27 | "ipfs": 500000000, 28 | "multiPayment": 10000000, 29 | "delegateResignation": 2500000000 30 | }, 31 | "dynamic": { 32 | "enabled": false, 33 | "minFeePool": 3000, 34 | "minFeeBroadcast": 3000, 35 | "addonBytes": { 36 | "transfer": 100, 37 | "secondSignature": 250, 38 | "delegateRegistration": 400000, 39 | "vote": 100, 40 | "multiSignature": 500, 41 | "ipfs": 250, 42 | "multiPayment": 500, 43 | "delegateResignation": 400000 44 | } 45 | } 46 | }, 47 | "forgers": 51, 48 | "blocktime": 8, 49 | "transactionsPerBlock": 50, 50 | "totalPremine": 2100000000000000, 51 | "rewardHeightStart": 75600, 52 | "rewardPerBlock": 200000000, 53 | "vendorFieldLength": 255, 54 | "bridgechainPath": "$HOME/core-bridgechain", 55 | "explorerPath": "$HOME/core-explorer", 56 | "gitCoreCommit": true, 57 | "gitCoreOrigin": null, 58 | "gitExplorerCommit": true, 59 | "gitExplorerOrigin": null, 60 | "licenseName": "mytest", 61 | "licenseEmail": "mytest@mytest.com" 62 | } 63 | -------------------------------------------------------------------------------- /lib/alerts.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | readonly red=$(tput setaf 1) 4 | readonly green=$(tput setaf 2) 5 | readonly yellow=$(tput setaf 3) 6 | readonly lila=$(tput setaf 4) 7 | readonly pink=$(tput setaf 5) 8 | readonly blue=$(tput setaf 6) 9 | readonly white=$(tput setaf 7) 10 | readonly black=$(tput setaf 8) 11 | 12 | readonly bgRed=$(tput setab 1) 13 | readonly bgGreen=$(tput setab 2) 14 | readonly bgYellow=$(tput setab 3) 15 | readonly bgLila=$(tput setab 4) 16 | readonly bgPink=$(tput setab 5) 17 | readonly bgBlue=$(tput setab 6) 18 | readonly bgWhite=$(tput setab 7) 19 | readonly bgBlack=$(tput setab 8) 20 | 21 | readonly bold=$(tput bold) 22 | readonly reset=$(tput sgr0) 23 | 24 | heading() 25 | { 26 | echo "${lila}==>${reset}${bold} $1${reset}" 27 | } 28 | 29 | success() 30 | { 31 | echo "${green}==>${reset}${bold} $1${reset}" 32 | } 33 | 34 | info() 35 | { 36 | echo "${blue}==>${reset}${bold} $1${reset}" 37 | } 38 | 39 | warning() 40 | { 41 | echo "${yellow}==>${reset}${bold} $1${reset}" 42 | } 43 | 44 | error() 45 | { 46 | echo "${red}==>${reset}${bold} $1${reset}" 47 | } 48 | 49 | heading_solid() 50 | { 51 | echo "${bgBlack}${lila}==>${bold} $1${reset}" 52 | } 53 | 54 | success_solid() 55 | { 56 | echo "${bgBlack}${green}==>${bold} $1${reset}" 57 | } 58 | 59 | info_solid() 60 | { 61 | echo "${bgBlack}${blue}==>${bold} $1${reset}" 62 | } 63 | 64 | warning_solid() 65 | { 66 | echo "${bgBlack}${yellow}==>${bold} $1${reset}" 67 | } 68 | 69 | error_solid() 70 | { 71 | echo "${bgBlack}${red}==>${bold} $1${reset}" 72 | } 73 | -------------------------------------------------------------------------------- /lib/args.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | parse_args() 4 | { 5 | METHOD="$(cat ${__manifest} | jq -r --arg COMMAND "$1" '.commands[] | select(.command == $COMMAND) | .method')" 6 | 7 | if [[ -z "$METHOD" ]]; then 8 | METHOD="$(cat ${__manifest} | jq -r --arg COMMAND "$1" '.commands[] | select(.abbreviation == $COMMAND) | .method')" 9 | fi 10 | 11 | if [[ -z "$METHOD" ]]; then 12 | help_me 13 | fi 14 | 15 | $METHOD "${@:2}" 16 | } 17 | -------------------------------------------------------------------------------- /lib/dependencies.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | case "$(uname -s)" in 4 | Linux*) machine=Linux;; 5 | Darwin*) machine=Mac;; 6 | CYGWIN*) machine=Cygwin;; 7 | MINGW*) machine=MinGw;; 8 | *) machine="UNKNOWN:${unameOut}" 9 | esac 10 | 11 | install_dependencies() 12 | { 13 | if [[ "$SKIP_DEPS" != "Y" ]]; then 14 | heading "Checking Dependencies..." 15 | check_program_dependencies 16 | check_nodejs_dependencies 17 | 18 | export PATH="/home/vagrant/bin:/home/vagrant/.local/bin:/home/vagrant/.yarn/bin:$PATH" 19 | fi 20 | } 21 | 22 | apt_package_installed() 23 | { 24 | local package="$1" 25 | local install_status 26 | 27 | install_status=$(dpkg --list "$package" 2>&1 | tail -n 1 | head -c 3) || true 28 | # interpretation of the 3 characters of install status 29 | # https://linuxprograms.wordpress.com/2010/05/11/status-dpkg-list/ 30 | if [[ "$install_status" == "ii " ]]; then 31 | return 0 32 | else 33 | return 1 34 | fi 35 | } 36 | 37 | check_program_dependencies() 38 | { 39 | local -a DEPENDENCIES="${DEPENDENCIES_PROGRAMS[@]}" 40 | 41 | TO_INSTALL="" 42 | for DEPENDENCY in ${DEPENDENCIES[@]}; do 43 | if ! apt_package_installed "$DEPENDENCY" ; then 44 | TO_INSTALL="$TO_INSTALL$DEPENDENCY " 45 | fi 46 | done 47 | 48 | if [[ ! -z "$TO_INSTALL" ]]; then 49 | if [[ "$INSTALL_DEPS" != "Y" ]]; then 50 | read -p "Dependencies [ ${TO_INSTALL}] are not installed. Do you want to install them? [y/N]: " choice 51 | fi 52 | 53 | if [[ "$choice" =~ ^(yes|y|Y) || "$INSTALL_DEPS" == "Y" ]]; then 54 | success "Installing Program Dependencies..." 55 | if [[ "$machine" == "Linux" ]]; then 56 | sudo sh -c "sudo apt-get install ${TO_INSTALL} -y" 57 | elif [[ "$machine" == "Mac" ]]; then 58 | sh -c "brew install ${TO_INSTALL} -y" 59 | else 60 | abort 1 'Unsupported platform.' 61 | fi 62 | success 'Program Dependencies Installed!' 63 | else 64 | abort 1 "Please ensure that [ ${TO_INSTALL}] dependencies are installed and try again." 65 | fi 66 | fi 67 | } 68 | 69 | check_nodejs_dependencies() 70 | { 71 | local -a DEPENDENCIES="${DEPENDENCIES_NODEJS[@]}" 72 | 73 | TO_INSTALL="" 74 | YARN_LIST=$(yarn global list) 75 | for DEPENDENCY in ${DEPENDENCIES[@]}; do 76 | INSTALLED_1=$(echo "$YARN_LIST" | egrep "^\s+-\s($DEPENDENCY)$" | awk '{print $2}') || true 77 | INSTALLED_2=$(echo "$YARN_LIST" | egrep "$DEPENDENCY.+has binaries:$" | awk '{print $2}' | egrep -o "\"$DEPENDENCY@") || true 78 | if [[ "$INSTALLED_1" != "$DEPENDENCY" && "$INSTALLED_2" != "\"$DEPENDENCY@" ]]; then 79 | TO_INSTALL="$TO_INSTALL$DEPENDENCY " 80 | fi 81 | done 82 | 83 | if [[ ! -z "$TO_INSTALL" ]]; then 84 | if [[ "$INSTALL_DEPS" != "Y" ]]; then 85 | read -p "[ ${TO_INSTALL}] are not installed. Do you want to install them? [y/N]: " choice 86 | fi 87 | 88 | if [[ "$choice" =~ ^(yes|y|Y) || "$INSTALL_DEPS" == "Y" ]]; then 89 | success "Installing NodeJS Dependencies..." 90 | sh -c "yarn global add ${TO_INSTALL}" 91 | success 'NodeJS Dependencies Installed!' 92 | else 93 | abort 1 "Please ensure that [ ${TO_INSTALL}] dependencies are installed and try again." 94 | fi 95 | fi 96 | } 97 | 98 | check_file_dependencies() 99 | { 100 | local -a DEPENDENCIES="${1}" 101 | 102 | for DEPENDENCY in ${DEPENDENCIES[@]}; do 103 | if [[ ! -f "${DEPENDENCY}" ]]; then 104 | abort 1 "Please ensure that [${DEPENDENCY}] exists and try again." 105 | fi 106 | done 107 | } 108 | 109 | check_process_dependencies() 110 | { 111 | local -a DEPENDENCIES="${1}" 112 | 113 | for DEPENDENCY in ${DEPENDENCIES[@]}; do 114 | if [[ ! $(pgrep -x "${DEPENDENCY}") ]]; then 115 | read -p "[${DEPENDENCY}] is not running. Do you want to start it? [y/N] :" choice 116 | 117 | if [[ "$choice" =~ ^(yes|y|Y) ]]; then 118 | success "Starting ${DEPENDENCY}..." 119 | sudo service "${DEPENDENCY}" start 120 | success 'Start OK!' 121 | else 122 | abort 1 "Please ensure that [${DEPENDENCY}] is running and try again." 123 | fi 124 | fi 125 | done 126 | } 127 | -------------------------------------------------------------------------------- /lib/errors.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | abort() 4 | { 5 | error "Yikes! ${2}" 6 | exit "${1}" 7 | } 8 | 9 | abort_info() 10 | { 11 | info "Huh! ${1}" 12 | exit 0 13 | } 14 | 15 | abort_success() 16 | { 17 | success "Yay! ${1}" 18 | exit 0 19 | } 20 | 21 | abort_warning() 22 | { 23 | warning "Argh! ${1}" 24 | exit 1 25 | } 26 | 27 | exception() 28 | { 29 | abort 1 "${1}" 30 | } 31 | 32 | exception_missing_argument() 33 | { 34 | abort 2 "Argument [${1}] is missing." 35 | } 36 | 37 | exception_command_not_found() 38 | { 39 | abort 127 "Command [${1}] not found." 40 | } 41 | 42 | exception_invalid_argument() 43 | { 44 | abort 128 "Argument [${1}] is invalid." 45 | } 46 | -------------------------------------------------------------------------------- /lib/manifest.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | manifest_details() 4 | { 5 | cat "${__manifest}" | jq -r '.details.'$1'' 6 | } 7 | 8 | manifest_command_value() 9 | { 10 | cat "${__manifest}" | jq -r '.commands['$1'].'$2'' 11 | } 12 | 13 | manifest_commands_length() 14 | { 15 | cat "${__manifest}" | jq -r '.commands|length' 16 | } 17 | -------------------------------------------------------------------------------- /lib/rtfm.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | help_me() 4 | { 5 | printf "%s# ---------------------------------------------------------------------------" 6 | printf "%s\n#" 7 | printf "%s\n# $(manifest_details title)" 8 | printf "%s\n# Version: $(manifest_details version)" 9 | printf "%s\n#" 10 | printf "%s\n# Usage:" 11 | printf "%s\n# $(manifest_details syntax)" 12 | printf "%s\n#" 13 | printf "%s\n" 14 | 15 | local MAX_COL=0 16 | local COUNT_ARGS=$(manifest_commands_length) 17 | 18 | for (( i = 0; i < COUNT_ARGS; i++ )) do 19 | ARG_LEN=$(manifest_command_value $i abbreviation)+$(manifest_command_value $i command) 20 | 21 | ((${#ARG_LEN} > MAX_COL)) && MAX_COL=${#ARG_LEN} 22 | 23 | (($i == COUNT_ARGS-1 )) && ((MAX_COL+=6)) 24 | done 25 | 26 | for (( i = 0; i < COUNT_ARGS; i++ )) do 27 | local abbreviation="$(manifest_command_value $i abbreviation)" 28 | 29 | if [[ "$abbreviation" == "null" ]]; then 30 | printf "%-${MAX_COL}s %s\n" "# $(manifest_command_value $i command)" "$(manifest_command_value $i description)" 31 | else 32 | printf "%-${MAX_COL}s %s\n" "# ${abbreviation}, $(manifest_command_value $i command)" "$(manifest_command_value $i description)" 33 | fi 34 | done 35 | 36 | printf "%s#\n" 37 | printf "%s# ---------------------------------------------------------------------------\n" 38 | } 39 | -------------------------------------------------------------------------------- /lib/utils.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | get_ip() 4 | { 5 | # Specific to AWS EC2 instances. It uses AWS's Instance Metadata service to retrive the external IP. It falls back to using ifconfig on non EC2 machines. 6 | # More info: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html 7 | if AWS_IP=$(curl -f -s --connect-timeout 5 http://169.254.169.254/latest/meta-data/public-ipv4); then 8 | echo "$AWS_IP" 9 | elif IP=$(sudo ifconfig | fgrep "inet " | egrep -v "inet (addr:)?(127|192)\." | egrep -o "inet (addr:)?([0-9]+\.?){4}" | egrep -o "([0-9]+\.?){4}" | head -n 1); then 10 | echo "$IP" 11 | else 12 | get_local_ip 13 | fi 14 | } 15 | 16 | get_local_ip() 17 | { 18 | IP=$(sudo ifconfig | fgrep "inet " | egrep -v "inet (addr:)?(127)\." | egrep -o "inet (addr:)?([0-9]+\.?){4}" | egrep -o "([0-9]+\.?){4}" | head -n 1) 19 | 20 | if [ ! -z "$IP" ]; then 21 | echo "$IP" 22 | else 23 | echo "127.0.0.1" 24 | fi 25 | } 26 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "details": { 3 | "title": "ARK Bridgechain Deployment script.", 4 | "syntax": "bridgechain.sh [argument] [-option]", 5 | "author": "Alex Barnsley & Brian Faust ", 6 | "version": "2.0.0" 7 | }, 8 | "commands": [{ 9 | "command": "start-core", 10 | "description": "Start the Core", 11 | "method": "process_core_start" 12 | }, { 13 | "command": "stop-core", 14 | "description": "Stop the Core", 15 | "method": "process_core_stop" 16 | }, { 17 | "command": "restart-core", 18 | "description": "Restart the Core", 19 | "method": "process_core_restart" 20 | }, { 21 | "command": "logs-core", 22 | "description": "Show the Core logs", 23 | "method": "process_core_logs" 24 | }, { 25 | "command": "start-explorer", 26 | "description": "Start the Explorer", 27 | "method": "process_explorer_start" 28 | }, { 29 | "command": "stop-explorer", 30 | "description": "Stop the Explorer", 31 | "method": "process_explorer_stop" 32 | }, { 33 | "command": "restart-explorer", 34 | "description": "Restart the Explorer", 35 | "method": "process_explorer_restart" 36 | }, { 37 | "command": "install-core", 38 | "description": "Install the Core", 39 | "method": "app_install_core" 40 | }, { 41 | "command": "uninstall-core", 42 | "description": "Uninstall the Core", 43 | "method": "app_uninstall_core" 44 | }, { 45 | "command": "update-core", 46 | "description": "Update Core to the latest version", 47 | "method": "update_core_handle" 48 | }, { 49 | "command": "install-explorer", 50 | "description": "Install the Explorer", 51 | "method": "app_install_explorer" 52 | }, { 53 | "command": "uninstall-explorer", 54 | "description": "Uninstall the Explorer", 55 | "method": "app_uninstall_explorer" 56 | }, { 57 | "command": "passphrases", 58 | "description": "Output Core passphrases", 59 | "method": "app_output_passphrases" 60 | }, { 61 | "command": "get-ip", 62 | "description": "Get machine IP", 63 | "method": "get_ip" 64 | }, { 65 | "abbreviation": "-h", 66 | "command": "help", 67 | "description": "Output usage information", 68 | "method": "help_me" 69 | }] 70 | } 71 | -------------------------------------------------------------------------------- /packages/js-deployer/bin/deployer: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | "use strict"; 4 | 5 | const commander = require("commander"); 6 | const Joi = require("joi"); 7 | const fs = require("fs-extra"); 8 | const os = require("os"); 9 | const path = require("path"); 10 | const GenesisBlockBuilder = require("../lib/builder/genesis-block"); 11 | const getRandomNumber = require("../lib/utils/get-random-number"); 12 | const logger = require("../lib/utils/logger"); 13 | const updateConfig = require("../lib/utils/update-config"); 14 | 15 | commander 16 | .version(require("../package.json").version) 17 | .option("--network ", "Network to initially copy", "mainnet") 18 | .option("--name ", "Name", "Bridgechain") 19 | .option("--coreIp ", "IP for core", "0.0.0.0") 20 | .option("--p2pPort ", "P2P API Port", 4102) 21 | .option("--apiPort ", "Public P2P Port", 4103) 22 | .option("--webhookPort ", "Webhook Port", 4104) 23 | .option("--jsonRpcPort ", "JSON RPC Port", 8080) 24 | .option("--dbHost ", "Database host", "localhost") 25 | .option("--dbPort ", "Database port", 5432) 26 | .option("--dbUsername ", "Database username", "core") 27 | .option("--dbPassword ", "Database password", "password") 28 | .option( 29 | "--dbDatabase ", 30 | "Database name", 31 | `core_${commander.name.toLowerCase()}` 32 | ) 33 | .option( 34 | "--explorerUrl ", 35 | "URL to link to explorer", 36 | "http://localhost:4200" 37 | ) 38 | .option("--forgers ", "How many forgers for the network [51]", 51) 39 | .option( 40 | "--epoch ", 41 | "Set Epoch based on time the chain was created", 42 | new Date().toISOString() 43 | ) 44 | .option( 45 | "--rewardHeight ", 46 | "Block Height when Forgers receive Rewards [1]", 47 | 1 48 | ) 49 | .option( 50 | "--rewardPerBlock ", 51 | "How many Rewarded Tokens per Forged Block [200000000 (2)]", 52 | 200000000 53 | ) 54 | .option( 55 | "--vendorFieldLength ", 56 | "Maximum length allowed for VendorField [255]", 57 | 255 58 | ) 59 | .option("--blocktime ", "Time per block (seconds) [8]", 8) 60 | .option("--token ", "Token Name [CHAIN]", "CHAIN") 61 | .option("--symbol ", "Symbol for Token [C]", "C") 62 | .option("--peers ", "Comma separated list of peer IPs") 63 | .option("--prefixHash ", "Address Prefix Hash [28]", 28) 64 | .option( 65 | "--transactionsPerBlock ", 66 | "Max Transaction count per Block [50]", 67 | 50 68 | ) 69 | .option( 70 | "--wifPrefix ", 71 | "Prefix for generating a WIF [rand(1, 255)]", 72 | getRandomNumber(1, 255) 73 | ) 74 | .option( 75 | "--totalPremine ", 76 | "Tokens added to genesis wallet [2100000000000000 (21 million)]", 77 | "2100000000000000" 78 | ) 79 | .option( 80 | "--overwriteConfig", 81 | "Overwrite current deployer config files [off]", 82 | false 83 | ) 84 | .option("--configPath ", "Deployer config path destination") 85 | .option( 86 | "--corePath ", 87 | "Core path location [~/core-bridgechain]", 88 | `${path.resolve(os.homedir(), "core-bridgechain")}` 89 | ) 90 | // Static Fees 91 | .option( 92 | "--feeStaticTransfer ", 93 | "Fee for sending Transaction", 94 | 10000000 95 | ) 96 | .option("--feeStaticVote ", "Fee for Vote Transaction", 100000000) 97 | .option( 98 | "--feeStaticSecondSignature ", 99 | "Fee for Second Passphrase Transaction", 100 | 500000000 101 | ) 102 | .option( 103 | "--feeStaticDelegateRegistration ", 104 | "Fee for Register Delegate Transaction", 105 | 2500000000 106 | ) 107 | .option( 108 | "--feeStaticMultiSignature ", 109 | "Fee for Multisignature Transaction", 110 | 500000000 111 | ) 112 | .option("--feeStaticIpfs ", "Fee for IPFS Transaction", 500000000) 113 | .option( 114 | "--feeStaticMultiPayment ", 115 | "Fee for MultiPayment Transaction", 116 | 10000000 117 | ) 118 | .option( 119 | "--feeStaticDelegateResignation ", 120 | "Fee for Delegate Resignation Transaction", 121 | 2500000000 122 | ) 123 | // Dynamic Fees 124 | .option("--feeDynamicEnabled ", "Dynamic Fees enabled", false) 125 | .option( 126 | "--feeDynamicPoolMinFee ", 127 | "Minimum fee for pool to accept transaction", 128 | 3000 129 | ) 130 | .option( 131 | "--feeDynamicBroadcastMinFee ", 132 | "Minimum fee to broadcast transaction", 133 | 3000 134 | ) 135 | .option( 136 | "--feeDynamicBytesTransfer ", 137 | "Fee Bytes for Transfer transaction", 138 | 100 139 | ) 140 | .option( 141 | "--feeDynamicBytesSecondSignature ", 142 | "Fee Bytes for Second Signature transaction", 143 | 250 144 | ) 145 | .option( 146 | "--feeDynamicBytesDelegateRegistration ", 147 | "Fee Bytes for Delegate Registration transaction", 148 | 400000 149 | ) 150 | .option( 151 | "--feeDynamicBytesVote ", 152 | "Fee Bytes for Vote transaction", 153 | 100 154 | ) 155 | .option( 156 | "--feeDynamicBytesMultiSignature ", 157 | "Fee Bytes for Multi-Signature transaction", 158 | 500 159 | ) 160 | .option( 161 | "--feeDynamicBytesIpfs ", 162 | "Fee Bytes for IPFS transaction", 163 | 250 164 | ) 165 | .option( 166 | "--feeDynamicBytesMultiPayment ", 167 | "Fee Bytes for Multi-Payment transaction", 168 | 500 169 | ) 170 | .option( 171 | "--feeDynamicBytesDelegateResignation ", 172 | "Fee Bytes for Delegate Resignation transaction", 173 | 400000 174 | ) 175 | .parse(process.argv); 176 | 177 | // Validate Schema 178 | const { error, value } = Joi.validate(commander, require("../lib/schema.js"), { 179 | allowUnknown: true, 180 | convert: true 181 | }); 182 | 183 | if (error) { 184 | error.details.forEach(detail => logger.error(detail.message)); 185 | process.exit(1); 186 | } 187 | 188 | // Store validated schema 189 | const options = value; 190 | 191 | // Check whether config path already exists 192 | if (fs.existsSync(options.configPath)) { 193 | if (options.overwriteConfig) { 194 | fs.removeSync(options.configPath); 195 | } else { 196 | logger.error( 197 | `Deployer config already exists in '${options.configPath}' - to overwrite, use the '--overwriteConfig' flag` 198 | ); 199 | process.exit(1); 200 | } 201 | } 202 | 203 | // Store original network paths 204 | const oldCoreNetworkPath = path.resolve( 205 | options.corePath, 206 | `packages/core/bin/config/${options.network}` 207 | ); 208 | const oldCryptoNetworkPath = path.resolve( 209 | options.corePath, 210 | `packages/crypto/src/networks/${options.network}` 211 | ); 212 | 213 | // Check network to copy exists 214 | if ( 215 | !fs.existsSync(oldCoreNetworkPath) || 216 | !fs.existsSync(oldCryptoNetworkPath) 217 | ) { 218 | logger.error(`Network '${options.network}' does not exist`); 219 | process.exit(1); 220 | } 221 | 222 | // Create config path 223 | fs.ensureDirSync(options.configPath); 224 | 225 | const coreNetworkPath = path.resolve(options.configPath, "core/"); 226 | const cryptoNetworkPath = path.resolve(options.configPath, "crypto/"); 227 | 228 | // Copy core config 229 | fs.copySync(oldCoreNetworkPath, coreNetworkPath); 230 | 231 | // Copy crypto config 232 | fs.copySync(oldCryptoNetworkPath, cryptoNetworkPath); 233 | 234 | let networkConfig = { 235 | name: options.network, 236 | messagePrefix: `${options.token} message:\n`, 237 | pubKeyHash: options.prefixHash, 238 | wif: options.wifPrefix, 239 | client: { 240 | token: options.token, 241 | symbol: options.symbol, 242 | explorer: options.explorerUrl 243 | } 244 | }; 245 | 246 | let milestones = [ 247 | { 248 | height: 1, 249 | reward: 0, 250 | activeDelegates: options.forgers, 251 | blocktime: options.blocktime, 252 | block: { 253 | version: 0, 254 | maxTransactions: options.transactionsPerBlock, 255 | maxPayload: (2097152 / 50) * options.transactionsPerBlock 256 | }, 257 | epoch: options.epoch, 258 | fees: { 259 | staticFees: { 260 | transfer: options.feeStaticTransfer, 261 | secondSignature: options.feeStaticSecondSignature, 262 | delegateRegistration: options.feeStaticDelegateRegistration, 263 | vote: options.feeStaticVote, 264 | multiSignature: options.feeStaticMultiSignature 265 | } 266 | }, 267 | htlcEnabled: false, 268 | vendorFieldLength: options.vendorFieldLength 269 | }, 270 | { 271 | height: 2, 272 | aip11: true, 273 | fees: { 274 | staticFees: { 275 | ipfs: options.feeStaticIpfs, 276 | multiPayment: options.feeStaticMultiPayment, 277 | delegateResignation: options.feeStaticDelegateResignation 278 | } 279 | } 280 | } 281 | ]; 282 | 283 | // Update milestones config 284 | if (options.rewardHeight <= 1) { 285 | milestones[0].reward = options.rewardPerBlock; 286 | } else if (options.rewardHeight > 1) { 287 | milestones.push({ 288 | height: options.rewardHeight, 289 | reward: options.rewardPerBlock 290 | }); 291 | } 292 | 293 | updateConfig("milestones.json", milestones, cryptoNetworkPath, true); 294 | 295 | let exceptions = { 296 | blocks: [], 297 | blocksTransactions: {}, 298 | transactions: [], 299 | outlookTable: {}, 300 | transactionIdFixTable: {}, 301 | wrongTransactionOrder: {}, 302 | negativeBalances: {} 303 | }; 304 | 305 | // Update exceptions config 306 | updateConfig("exceptions.json", exceptions, cryptoNetworkPath); 307 | 308 | let config = { 309 | exceptions: exceptions, 310 | genesisBlock: {}, 311 | milestones: milestones, 312 | network: networkConfig 313 | }; 314 | // Update network config 315 | networkConfig = updateConfig("network.json", networkConfig, cryptoNetworkPath); 316 | 317 | const genesis = new GenesisBlockBuilder( 318 | networkConfig, 319 | options, 320 | config 321 | ).generate(); 322 | networkConfig.nethash = genesis.genesisBlock.payloadHash; 323 | 324 | updateConfig("network.json", networkConfig, cryptoNetworkPath); 325 | 326 | // Update peers config 327 | const peerConfig = { 328 | list: [], 329 | sources: [] 330 | }; 331 | if (options.peers) { 332 | for (const ip of options.peers.split(",")) { 333 | peerConfig.list.push({ 334 | ip: ip.trim(), 335 | port: options.p2pPort 336 | }); 337 | } 338 | } else { 339 | peerConfig.list.push({ 340 | ip: options.coreIp === "0.0.0.0" ? "127.0.0.1" : options.coreIp, 341 | port: options.p2pPort 342 | }); 343 | } 344 | updateConfig("peers.json", peerConfig, coreNetworkPath); 345 | 346 | // Update genesis block 347 | updateConfig( 348 | "genesisBlock.json", 349 | genesis.genesisBlock, 350 | cryptoNetworkPath, 351 | true 352 | ); 353 | 354 | // Store genesis wallet config 355 | updateConfig( 356 | "genesisWallet.json", 357 | { 358 | address: genesis.genesisWallet.address, 359 | passphrase: genesis.genesisWallet.passphrase 360 | }, 361 | options.configPath, 362 | true 363 | ); 364 | 365 | // Store delegate passphrase config 366 | updateConfig( 367 | "delegates.json", 368 | { 369 | secrets: genesis.delegatePassphrases 370 | }, 371 | options.configPath, 372 | true 373 | ); 374 | 375 | // Update plugins config 376 | let pluginsConfig = fs 377 | .readFileSync(path.resolve(coreNetworkPath, "plugins.js")) 378 | .toString(); 379 | const pluginsToUpdate = [ 380 | // Remove magistrate plugin 381 | { 382 | from: '"@arkecosystem/core-magistrate-transactions": {},', 383 | to: "" 384 | }, 385 | // Database config 386 | { 387 | from: /process\.env\.CORE_DB_HOST \|\| "(\w+)"/g, 388 | to: `process.env.CORE_DB_HOST || "${options.dbHost}"` 389 | }, 390 | { 391 | from: /process\.env\.CORE_DB_PORT \|\| (\d+)/g, 392 | to: `process.env.CORE_DB_PORT || ${options.dbPort}` 393 | }, 394 | { 395 | from: /process\.env\.CORE_DB_PASSWORD \|\| "(.+)"/g, 396 | to: `process.env.CORE_DB_PASSWORD || "${options.dbPassword}"` 397 | }, 398 | // P2P config 399 | { 400 | from: /process\.env\.CORE_P2P_HOST \|\| "(.+)"/g, 401 | to: `process.env.CORE_P2P_HOST || "${options.coreIp}"` 402 | }, 403 | { 404 | from: /process\.env\.CORE_P2P_PORT \|\| (\d+)/g, 405 | to: `process.env.CORE_P2P_PORT || ${options.p2pPort}` 406 | }, 407 | // API config 408 | { 409 | from: /process\.env\.CORE_API_HOST \|\| "(.+)"/g, 410 | to: `process.env.CORE_API_HOST || "${options.coreIp}"` 411 | }, 412 | { 413 | from: /process\.env\.CORE_API_PORT \|\| (\d+)/g, 414 | to: `process.env.CORE_API_PORT || ${options.apiPort}` 415 | }, 416 | // Webhook config 417 | { 418 | from: /process\.env\.CORE_WEBHOOKS_HOST \|\| "(.+)"/g, 419 | to: `process.env.CORE_WEBHOOKS_HOST || "${options.coreIp}"` 420 | }, 421 | { 422 | from: /process\.env\.CORE_WEBHOOKS_PORT \|\| (\d+)/g, 423 | to: `process.env.CORE_WEBHOOKS_PORT || ${options.webhookPort}` 424 | }, 425 | // JSON RPC config 426 | { 427 | from: /process\.env\.CORE_JSON_RPC_HOST \|\| "(.+)"/g, 428 | to: `process.env.CORE_JSON_RPC_HOST || "${options.coreIp}"` 429 | }, 430 | { 431 | from: /process\.env\.CORE_JSON_RPC_PORT \|\| (\d+)/g, 432 | to: `process.env.CORE_JSON_RPC_PORT || ${options.jsonRpcPort}` 433 | }, 434 | // Dynamic Fees 435 | { 436 | from: /(dynamicFees: {[a-zA-Z0-9: ,\n{}]*enabled: )(true|false+)/g, 437 | to: `$1${options.feeDynamicEnabled}` 438 | }, 439 | { 440 | from: /(dynamicFees: {[a-zA-Z0-9: ,\n{}]*minFeePool: )([0-9]+)/g, 441 | to: `$1${options.feeDynamicPoolMinFee}` 442 | }, 443 | { 444 | from: /(dynamicFees: {[a-zA-Z0-9: ,\n{}]*minFeeBroadcast: )([0-9]+)/g, 445 | to: `$1${options.feeDynamicBroadcastMinFee}` 446 | }, 447 | { 448 | from: /(dynamicFees: {[a-zA-Z0-9: ,\n{}]*addonBytes: {[a-zA-Z0-9: ,\n{}]*transfer: )([0-9]+)/g, 449 | to: `$1${options.feeDynamicBytesTransfer}` 450 | }, 451 | { 452 | from: /(dynamicFees: {[a-zA-Z0-9: ,\n{}]*addonBytes: {[a-zA-Z0-9: ,\n{}]*secondSignature: )([0-9]+)/g, 453 | to: `$1${options.feeDynamicBytesSecondSignature}` 454 | }, 455 | { 456 | from: /(dynamicFees: {[a-zA-Z0-9: ,\n{}]*addonBytes: {[a-zA-Z0-9: ,\n{}]*delegateRegistration: )([0-9]+)/g, 457 | to: `$1${options.feeDynamicBytesDelegateRegistration}` 458 | }, 459 | { 460 | from: /(dynamicFees: {[a-zA-Z0-9: ,\n{}]*addonBytes: {[a-zA-Z0-9: ,\n{}]*vote: )([0-9]+)/g, 461 | to: `$1${options.feeDynamicBytesVote}` 462 | }, 463 | { 464 | from: /(dynamicFees: {[a-zA-Z0-9: ,\n{}]*addonBytes: {[a-zA-Z0-9: ,\n{}]*multiSignature: )([0-9]+)/g, 465 | to: `$1${options.feeDynamicBytesMultiSignature}` 466 | }, 467 | { 468 | from: /(dynamicFees: {[a-zA-Z0-9: ,\n{}]*addonBytes: {[a-zA-Z0-9: ,\n{}]*ipfs: )([0-9]+)/g, 469 | to: `$1${options.feeDynamicBytesIpfs}` 470 | }, 471 | { 472 | from: /(dynamicFees: {[a-zA-Z0-9: ,\n{}]*addonBytes: {[a-zA-Z0-9: ,\n{}]*multiPayment: )([0-9]+)/g, 473 | to: `$1${options.feeDynamicBytesMultiPayment}` 474 | }, 475 | { 476 | from: /(dynamicFees: {[a-zA-Z0-9: ,\n{}]*addonBytes: {[a-zA-Z0-9: ,\n{}]*delegateResignation: )([0-9]+)/g, 477 | to: `$1${options.feeDynamicBytesDelegateResignation}` 478 | }, 479 | // Remove HTLC fees 480 | { 481 | from: /(dynamicFees: {[a-zA-Z0-9: ,\n{}]*addonBytes: {[a-zA-Z0-9: ,\n{}]*,\n)([ ]*)(htlcLock: [0-9]+,\n[ ]*htlcClaim: [0-9]+,\n[ ]*htlcRefund: [0-9]+,\n)/g, 482 | to: "$1" 483 | }, 484 | // Remove business fees 485 | { 486 | from: /(dynamicFees: {[a-zA-Z0-9: ,\n{}]*addonBytes: {[a-zA-Z0-9: ,\n{}]*,\n)([ ]*)(businessRegistration: [0-9]+,\n[ ]*businessUpdate: [0-9]+,\n[ ]*businessResignation: [0-9]+,\n)/g, 487 | to: "$1" 488 | }, 489 | // Remove bridgechain fees 490 | { 491 | from: /(dynamicFees: {[a-zA-Z0-9: ,\n{}]*addonBytes: {[a-zA-Z0-9: ,\n{}]*,\n)([ ]*)(bridgechainRegistration: [0-9]+,\n[ ]*bridgechainUpdate: [0-9]+,\n[ ]*bridgechainResignation: [0-9]+,\n)/g, 492 | to: "$1" 493 | } 494 | ]; 495 | 496 | for (const replacement of pluginsToUpdate) { 497 | pluginsConfig = pluginsConfig.replace(replacement.from, replacement.to); 498 | } 499 | 500 | if (options.network === "testnet") { 501 | pluginsConfig = pluginsConfig.replace( 502 | /(minimumNetworkReach:) [0-9]+/g, 503 | `$1 2` 504 | ); 505 | } 506 | 507 | if (options.network === "mainnet") { 508 | pluginsConfig = pluginsConfig.replace( 509 | /("@arkecosystem\/core-p2p": {)/, 510 | `$1\n minimumNetworkReach: ${Math.ceil(options.forgers / 3)},` 511 | ); 512 | } 513 | 514 | fs.writeFileSync(path.resolve(coreNetworkPath, "plugins.js"), pluginsConfig); 515 | 516 | // Update env config 517 | let envConfig = fs 518 | .readFileSync(path.resolve(coreNetworkPath, ".env")) 519 | .toString(); 520 | const envToUpdate = [ 521 | // Database config 522 | { 523 | from: /^CORE_DB_HOST=.+$/m, 524 | to: `CORE_DB_HOST=${options.dbHost}` 525 | }, 526 | { 527 | from: /^CORE_DB_PORT=.+$/m, 528 | to: `CORE_DB_PORT=${options.dbPort}` 529 | }, 530 | // P2P config 531 | { 532 | from: /^CORE_P2P_HOST=.+$/m, 533 | to: `CORE_P2P_HOST=${options.coreIp}` 534 | }, 535 | { 536 | from: /^CORE_P2P_PORT=.+$/m, 537 | to: `CORE_P2P_PORT=${options.p2pPort}` 538 | }, 539 | // API config 540 | { 541 | from: /^CORE_API_HOST=.+$/m, 542 | to: `CORE_API_HOST=${options.coreIp}` 543 | }, 544 | { 545 | from: /^CORE_API_PORT=.+$/m, 546 | to: `CORE_API_PORT=${options.apiPort}` 547 | }, 548 | // Webhook config 549 | { 550 | from: /^CORE_WEBHOOKS_HOST=.+$/m, 551 | to: `CORE_WEBHOOKS_HOST=${options.coreIp}` 552 | }, 553 | { 554 | from: /^CORE_WEBHOOKS_PORT=.+$/m, 555 | to: `CORE_WEBHOOKS_PORT=${options.webhookPort}` 556 | }, 557 | // JSON RPC config 558 | { 559 | from: /^CORE_JSON_RPC_HOST=.+$/m, 560 | to: `CORE_JSON_RPC_HOST=${options.coreIp}` 561 | }, 562 | { 563 | from: /^CORE_JSON_RPC_PORT=.+$/m, 564 | to: `CORE_JSON_RPC_PORT=${options.jsonRpcPort}` 565 | } 566 | ]; 567 | 568 | if (/^CORE_DB_USERNAME=.+$/m.test(envConfig)) { 569 | envConfig = envConfig.replace( 570 | /^CORE_DB_USERNAME=.+$/m, 571 | `CORE_DB_USERNAME=${options.dbUsername}` 572 | ); 573 | } else { 574 | envConfig = envConfig.replace( 575 | /^(CORE_DB_PORT=.+)$/m, 576 | `$1\nCORE_DB_USERNAME=${options.dbUsername}` 577 | ); 578 | } 579 | 580 | if (/^CORE_DB_DATABASE=.+$/m.test(envConfig)) { 581 | envConfig = envConfig.replace( 582 | /^CORE_DB_DATABASE=.+$/m, 583 | `CORE_DB_DATABASE=${options.dbDatabase}` 584 | ); 585 | } else { 586 | envConfig = envConfig.replace( 587 | /^(CORE_DB_USERNAME=.+)$/m, 588 | `$1\nCORE_DB_DATABASE=${options.dbDatabase}` 589 | ); 590 | } 591 | 592 | for (const replacement of envToUpdate) { 593 | envConfig = envConfig.replace(replacement.from, replacement.to); 594 | } 595 | 596 | fs.writeFileSync(path.resolve(coreNetworkPath, ".env"), envConfig); 597 | -------------------------------------------------------------------------------- /packages/js-deployer/lib/builder/genesis-block.js: -------------------------------------------------------------------------------- 1 | const { 2 | Identities, 3 | Managers, 4 | Transactions, 5 | Utils, 6 | Crypto 7 | } = require("@arkecosystem/crypto"); 8 | const bip39 = require('bip39') 9 | const ByteBuffer = require('bytebuffer') 10 | const { createHash } = require('crypto') 11 | 12 | module.exports = class GenesisBlockBuilder { 13 | /** 14 | * Create a new Genesis Block builder instance. 15 | * @param {Object} options 16 | * @return {void} 17 | */ 18 | constructor(network, options, config) { 19 | this.network = network 20 | this.prefixHash = network.pubKeyHash 21 | this.totalPremine = options.totalPremine 22 | this.forgers = options.forgers 23 | this.config = config 24 | } 25 | 26 | /** 27 | * Generate a Genesis Block. 28 | * @return {Object} 29 | */ 30 | generate() { 31 | Managers.configManager.setConfig(this.config); 32 | Managers.configManager.setHeight(1); 33 | 34 | const genesisWallet = this.__createWallet() 35 | const premineWallet = this.__createWallet() 36 | const delegates = this.__buildDelegates() 37 | const transactions = [ 38 | ...this.__buildDelegateTransactions(delegates), 39 | this.__createTransferTransaction( 40 | premineWallet, 41 | genesisWallet, 42 | Utils.BigNumber.make(this.totalPremine), 43 | ), 44 | ] 45 | const genesisBlock = this.__createGenesisBlock({ 46 | keys: genesisWallet.keys, 47 | transactions, 48 | timestamp: 0, 49 | }) 50 | 51 | return { 52 | genesisWallet, 53 | genesisBlock, 54 | delegatePassphrases: delegates.map(wallet => wallet.passphrase), 55 | } 56 | } 57 | 58 | /** 59 | * Generate a new random wallet. 60 | * @return {Object} 61 | */ 62 | __createWallet() { 63 | const passphrase = bip39.generateMnemonic() 64 | 65 | return { 66 | address: Identities.Address.fromPassphrase(passphrase, this.prefixHash), 67 | passphrase, 68 | keys: Identities.Keys.fromPassphrase(passphrase), 69 | } 70 | } 71 | 72 | /** 73 | * Generate a random wallet and assign it a delegate username. 74 | * @param {String} username 75 | * @return {Object} 76 | */ 77 | __createDelegateWallet(username) { 78 | const wallet = this.__createWallet() 79 | wallet.username = username 80 | 81 | return wallet 82 | } 83 | 84 | /** 85 | * Generate a collection of delegate wallets. 86 | * @return {Object[]} 87 | */ 88 | __buildDelegates() { 89 | const wallets = [] 90 | for (let i = 0; i < this.forgers; i++) { 91 | wallets.push(this.__createDelegateWallet(`genesis_${i + 1}`)) 92 | } 93 | 94 | return wallets 95 | } 96 | 97 | /** 98 | * Generate a collection of delegate registration transactions. 99 | * @param {Object[]} wallets 100 | * @return {Object[]} 101 | */ 102 | __buildDelegateTransactions(wallets) { 103 | return wallets.map(wallet => this.__createDelegateTransaction(wallet)) 104 | } 105 | 106 | /** 107 | * Create transfer transaction. 108 | * @param {Object} senderWallet 109 | * @param {Object} receiverWallet 110 | * @param {Number} amount 111 | * @return {Object} 112 | */ 113 | __createTransferTransaction(senderWallet, receiverWallet, amount) { 114 | const { data } = Transactions.BuilderFactory 115 | .transfer() 116 | .recipientId(receiverWallet.address) 117 | .amount(amount) 118 | .sign(senderWallet.passphrase) 119 | .build() 120 | 121 | return this.__formatGenesisTransaction(data, senderWallet) 122 | } 123 | 124 | /** 125 | * Create delegate registration transaction. 126 | * @param {Object} wallet 127 | * @return {Object} 128 | */ 129 | __createDelegateTransaction(wallet) { 130 | 131 | const { data } = Transactions.BuilderFactory 132 | .delegateRegistration() 133 | .amount(Utils.BigNumber.ZERO) 134 | .usernameAsset(wallet.username) 135 | .sign(wallet.passphrase) 136 | .build() 137 | 138 | return this.__formatGenesisTransaction(data, wallet) 139 | } 140 | 141 | /** 142 | * Reset transaction to be applied in the genesis block. 143 | * @param {Object} transaction 144 | * @param {Object} wallet 145 | * @return {Object} 146 | */ 147 | __formatGenesisTransaction(transaction, wallet) { 148 | Object.assign(transaction, { 149 | fee: Utils.BigNumber.ZERO, 150 | timestamp: 0, 151 | senderId: wallet.address, 152 | }) 153 | 154 | transaction.signature = Transactions.Signer.sign(transaction, wallet.keys) 155 | transaction.id = Transactions.Utils.getId(transaction) 156 | 157 | return transaction 158 | } 159 | 160 | /** 161 | * Create block based on data. 162 | * @param {Object} data 163 | * @return {Object} 164 | */ 165 | __createGenesisBlock(data) { 166 | const transactions = data.transactions.sort((a, b) => { 167 | if (a.type === b.type) { 168 | return a.amount - b.amount 169 | } 170 | 171 | return a.type - b.type 172 | }) 173 | 174 | let payloadLength = 0 175 | let totalFee = Utils.BigNumber.ZERO 176 | let totalAmount = Utils.BigNumber.ZERO 177 | const payloadHash = createHash('sha256') 178 | 179 | transactions.forEach(transaction => { 180 | const bytes = Transactions.Serializer.getBytes(transaction) 181 | payloadLength += bytes.length 182 | totalFee = totalFee.plus(transaction.fee) 183 | if (transaction.amount) { 184 | totalAmount = totalAmount.plus(transaction.amount) 185 | } 186 | payloadHash.update(bytes) 187 | }) 188 | 189 | const block = { 190 | version: 0, 191 | totalAmount, 192 | totalFee, 193 | reward: Utils.BigNumber.ZERO, 194 | payloadHash: payloadHash.digest().toString('hex'), 195 | timestamp: data.timestamp, 196 | numberOfTransactions: transactions.length, 197 | payloadLength, 198 | previousBlock: null, 199 | generatorPublicKey: data.keys.publicKey.toString('hex'), 200 | transactions, 201 | height: 1, 202 | } 203 | 204 | block.id = this.__getBlockId(block) 205 | 206 | try { 207 | block.blockSignature = this.__signBlock(block, data.keys) 208 | } catch (e) { 209 | throw e 210 | } 211 | 212 | return block 213 | } 214 | 215 | /** 216 | * Work out block id for block. 217 | * @param {Object} block 218 | * @return {String} 219 | */ 220 | __getBlockId(block) { 221 | const hash = this.__getHash(block) 222 | const blockBuffer = Buffer.alloc(8) 223 | for (let i = 0; i < 8; i++) { 224 | blockBuffer[i] = hash[7 - i] 225 | } 226 | 227 | return Utils.BigNumber.make(`0x${blockBuffer.toString("hex")}`).toString(); 228 | } 229 | 230 | /** 231 | * Sign block with keys. 232 | * @param {Object} block 233 | * @param {Object]} keys 234 | * @return {String} 235 | */ 236 | __signBlock(block, keys) { 237 | const hash = this.__getHash(block) 238 | return Crypto.Hash.signECDSA(hash, keys) 239 | } 240 | 241 | /** 242 | * Get hash of block. 243 | * @param {Object} block 244 | * @return {String} 245 | */ 246 | __getHash(block) { 247 | return createHash('sha256') 248 | .update(this.__getBytes(block)) 249 | .digest() 250 | } 251 | 252 | /** 253 | * Get block bytes. 254 | * @param {Object} block 255 | * @return {(Buffer|undefined)} 256 | */ 257 | __getBytes(block) { 258 | const size = 4 + 4 + 4 + 8 + 4 + 4 + 8 + 8 + 4 + 4 + 4 + 32 + 32 + 64 259 | 260 | try { 261 | const byteBuffer = new ByteBuffer(size, true) 262 | byteBuffer.writeInt(block.version) 263 | byteBuffer.writeInt(block.timestamp) 264 | byteBuffer.writeInt(block.height) 265 | 266 | if (block.previousBlock) { 267 | const previousBlock = Buffer.from( 268 | new Utils.BigNumber(block.previousBlock).toString(16), 269 | 'hex', 270 | ) 271 | 272 | for (let i = 0; i < 8; i++) { 273 | byteBuffer.writeByte(previousBlock[i]) 274 | } 275 | } else { 276 | for (let i = 0; i < 8; i++) { 277 | byteBuffer.writeByte(0) 278 | } 279 | } 280 | 281 | byteBuffer.writeInt(block.numberOfTransactions) 282 | byteBuffer.writeLong(block.totalAmount.toFixed()) 283 | byteBuffer.writeLong(block.totalFee.toFixed()) 284 | byteBuffer.writeLong(block.reward.toFixed()) 285 | 286 | byteBuffer.writeInt(block.payloadLength) 287 | 288 | const payloadHashBuffer = Buffer.from(block.payloadHash, 'hex') 289 | for (let i = 0; i < payloadHashBuffer.length; i++) { 290 | byteBuffer.writeByte(payloadHashBuffer[i]) 291 | } 292 | 293 | const generatorPublicKeyBuffer = Buffer.from( 294 | block.generatorPublicKey, 295 | 'hex', 296 | ) 297 | for (let i = 0; i < generatorPublicKeyBuffer.length; i++) { 298 | byteBuffer.writeByte(generatorPublicKeyBuffer[i]) 299 | } 300 | 301 | if (block.blockSignature) { 302 | const blockSignatureBuffer = Buffer.from(block.blockSignature, 'hex') 303 | for (let i = 0; i < blockSignatureBuffer.length; i++) { 304 | byteBuffer.writeByte(blockSignatureBuffer[i]) 305 | } 306 | } 307 | 308 | byteBuffer.flip() 309 | const buffer = byteBuffer.toBuffer() 310 | 311 | return buffer 312 | } catch (error) { 313 | throw error 314 | } 315 | } 316 | } 317 | -------------------------------------------------------------------------------- /packages/js-deployer/lib/schema.js: -------------------------------------------------------------------------------- 1 | const Joi = require('joi') 2 | 3 | module.exports = Joi.object().keys({ 4 | network: Joi.string().required(), 5 | name: Joi.string().required(), 6 | coreIp: Joi.string().required(), 7 | p2pPort: Joi.number().required(), 8 | apiPort: Joi.number().required(), 9 | dbHost: Joi.string().required(), 10 | dbPort: Joi.number().required(), 11 | dbUsername: Joi.string().required(), 12 | dbPassword: Joi.string().required(), 13 | dbDatabase: Joi.string().required(), 14 | explorerUrl: Joi.string() 15 | .uri({ scheme: ["http", "https"] }) 16 | .required(), 17 | forgers: Joi.number().required(), 18 | epoch: Joi.string() 19 | .regex( 20 | /\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z)/ 21 | ) 22 | .required(), 23 | rewardHeight: Joi.number() 24 | .integer() 25 | .positive() 26 | .required(), 27 | rewardPerBlock: Joi.number().required(), 28 | vendorFieldLength: Joi.number().required(), 29 | blocktime: Joi.number().required(), 30 | token: Joi.string().required(), 31 | symbol: Joi.string().required(), 32 | peers: Joi.string().allow(""), 33 | prefixHash: Joi.number().required(), 34 | transactionsPerBlock: Joi.number().required(), 35 | wifPrefix: Joi.number() 36 | .integer() 37 | .min(1) 38 | .max(255) 39 | .required(), 40 | totalPremine: Joi.string().required(), 41 | configPath: Joi.string().required(), 42 | // Static Fees 43 | feeStaticTransfer: Joi.number().required(), 44 | feeStaticVote: Joi.number().required(), 45 | feeStaticSecondSignature: Joi.number().required(), 46 | feeStaticDelegateRegistration: Joi.number().required(), 47 | feeStaticMultiSignature: Joi.number().required(), 48 | feeStaticIpfs: Joi.number().required(), 49 | feeStaticMultiPayment: Joi.number().required(), 50 | feeStaticDelegateResignation: Joi.number().required(), 51 | // Dynamic Fees 52 | feeDynamicEnabled: Joi.boolean().required(), 53 | feeDynamicPoolMinFee: Joi.number().required(), 54 | feeDynamicBroadcastMinFee: Joi.number().required(), 55 | feeDynamicBytesTransfer: Joi.number().required(), 56 | feeDynamicBytesSecondSignature: Joi.number().required(), 57 | feeDynamicBytesDelegateRegistration: Joi.number().required(), 58 | feeDynamicBytesVote: Joi.number().required(), 59 | feeDynamicBytesMultiSignature: Joi.number().required(), 60 | feeDynamicBytesIpfs: Joi.number().required(), 61 | feeDynamicBytesMultiPayment: Joi.number().required(), 62 | feeDynamicBytesDelegateResignation: Joi.number().required() 63 | }); 64 | -------------------------------------------------------------------------------- /packages/js-deployer/lib/utils/get-random-number.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Get a random number from range. 3 | * @param {Number} min 4 | * @param {Number} max 5 | * @return {Number} 6 | */ 7 | module.exports = (min, max) => Math.floor(Math.random() * (max - min) + min) 8 | -------------------------------------------------------------------------------- /packages/js-deployer/lib/utils/logger.js: -------------------------------------------------------------------------------- 1 | const pino = require('pino') 2 | 3 | module.exports = pino({ 4 | name: 'ark-tester-cli', 5 | safe: true, 6 | prettyPrint: true, 7 | }) 8 | -------------------------------------------------------------------------------- /packages/js-deployer/lib/utils/update-config.js: -------------------------------------------------------------------------------- 1 | const set = require('lodash.set') 2 | const fs = require('fs-extra') 3 | const path = require('path') 4 | 5 | /** 6 | * Update the contents of the given file and return config. 7 | * @param {String} file 8 | * @param {Object} values 9 | * @return {Object} 10 | */ 11 | module.exports = (file, values, configPath, forceOverwrite) => { 12 | configPath = configPath || `${process.env.ARK_PATH_CONFIG}/deployer` 13 | configPath = path.resolve(configPath, file) 14 | let config 15 | if (fs.existsSync(configPath) && !forceOverwrite) { 16 | config = require(configPath) 17 | Object.keys(values).forEach(key => set(config, key, values[key])) 18 | } else { 19 | config = values 20 | } 21 | 22 | fs.ensureFileSync(configPath) 23 | fs.writeFileSync(configPath, JSON.stringify(config, null, 2)) 24 | 25 | return config 26 | } 27 | -------------------------------------------------------------------------------- /packages/js-deployer/lib/utils/write-env.js: -------------------------------------------------------------------------------- 1 | const envfile = require('envfile') 2 | const expandHomeDir = require('expand-home-dir') 3 | const fs = require('fs-extra') 4 | const path = require('path') 5 | 6 | /** 7 | * Write Environment variables to file. 8 | * @param {Object} object 9 | * @param {String} path 10 | * @return {void} 11 | */ 12 | module.exports = (object, filePath) => { 13 | filePath = expandHomeDir(filePath) 14 | fs.ensureDirSync(path.dirname(filePath)) 15 | fs.writeFileSync(filePath, envfile.stringifySync(object)) 16 | } 17 | -------------------------------------------------------------------------------- /packages/js-deployer/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@arkecosystem/core-deployer", 3 | "description": "Deployer for ARK Core", 4 | "version": "0.2.0", 5 | "contributors": [ 6 | "Alex Barnsley " 7 | ], 8 | "license": "MIT", 9 | "bin": { 10 | "ark:deployer": "./bin/deployer" 11 | }, 12 | "scripts": { 13 | "start": "./bin/deployer" 14 | }, 15 | "dependencies": { 16 | "@arkecosystem/crypto": "^2.6.57", 17 | "bip39": "^3.0.0", 18 | "bytebuffer": "^5.0.1", 19 | "commander": "^4.0.0", 20 | "envfile": "^4.0.0", 21 | "expand-home-dir": "0.0.3", 22 | "fs-extra": "^8.0.0", 23 | "joi": "^14.3.0", 24 | "lodash.set": "^4.3.2", 25 | "pino": "^5.9.0", 26 | "pino-pretty": "^3.0.0" 27 | }, 28 | "publishConfig": { 29 | "access": "public" 30 | }, 31 | "engines": { 32 | "node": ">=10.x" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/js-deployer/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@arkecosystem/crypto@^2.6.57": 6 | version "2.6.57" 7 | resolved "https://registry.yarnpkg.com/@arkecosystem/crypto/-/crypto-2.6.57.tgz#56c29bdc0d9bce88954efba4b0285b1fc9ed8dc4" 8 | integrity sha512-H3qjejdWJGaV9r4THMh1UgixY4WL3nm90x6aXryjcXrdcEXnUDh3TBqmfnwXTjo14pOZFbH9dPoBrShhh4hu6g== 9 | dependencies: 10 | "@arkecosystem/utils" "^1.2" 11 | "@types/bytebuffer" "^5.0.40" 12 | ajv "^6.10.2" 13 | ajv-keywords "^3.4.1" 14 | bcrypto "^5.2.0" 15 | bip32 "^2.0.3" 16 | bip39 "^3.0.2" 17 | browserify-aes "^1.2.0" 18 | bstring "^0.3.9" 19 | buffer-xor "^2.0.2" 20 | bytebuffer "^5.0.1" 21 | dayjs "^1.8.15" 22 | deepmerge "^4.0.0" 23 | fast-memoize "^2.5.1" 24 | ipaddr.js "^1.9.0" 25 | lodash.get "^4.4.2" 26 | lodash.set "^4.3.2" 27 | lodash.sumby "^4.6.0" 28 | tiny-glob "^0.2.6" 29 | wif "^2.0.6" 30 | 31 | "@arkecosystem/utils@^1.2": 32 | version "1.2.0" 33 | resolved "https://registry.yarnpkg.com/@arkecosystem/utils/-/utils-1.2.0.tgz#f58e9dca0e4478503e996c5f276bb210ab142e92" 34 | integrity sha512-FNemFa4V0/8O4ZDpCGxvrnt8U6PmDq4fyxFaCx6wgJmSTxoxxJpvKCnhXPTbYtDGyhk0XsmittTj3uHZQQCXVQ== 35 | dependencies: 36 | "@hapi/bourne" "^2.0.0" 37 | deepmerge "^4.2.2" 38 | fast-copy "^2.1.0" 39 | fast-deep-equal "^3.1.3" 40 | fast-sort "^2.2.0" 41 | type-fest "^0.16.0" 42 | 43 | "@hapi/bourne@^1.3.2": 44 | version "1.3.2" 45 | resolved "https://registry.yarnpkg.com/@hapi/bourne/-/bourne-1.3.2.tgz#0a7095adea067243ce3283e1b56b8a8f453b242a" 46 | integrity sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA== 47 | 48 | "@hapi/bourne@^2.0.0": 49 | version "2.0.0" 50 | resolved "https://registry.yarnpkg.com/@hapi/bourne/-/bourne-2.0.0.tgz#5bb2193eb685c0007540ca61d166d4e1edaf918d" 51 | integrity sha512-WEezM1FWztfbzqIUbsDzFRVMxSoLy3HugVcux6KDDtTqzPsLE8NDRHfXvev66aH1i2oOKKar3/XDjbvh/OUBdg== 52 | 53 | "@types/bytebuffer@^5.0.40": 54 | version "5.0.40" 55 | resolved "https://registry.yarnpkg.com/@types/bytebuffer/-/bytebuffer-5.0.40.tgz#d6faac40dcfb09cd856cdc4c01d3690ba536d3ee" 56 | integrity sha512-h48dyzZrPMz25K6Q4+NCwWaxwXany2FhQg/ErOcdZS1ZpsaDnDMZg8JYLMTGz7uvXKrcKGJUZJlZObyfgdaN9g== 57 | dependencies: 58 | "@types/long" "*" 59 | "@types/node" "*" 60 | 61 | "@types/long@*": 62 | version "4.0.1" 63 | resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9" 64 | integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w== 65 | 66 | "@types/node@*": 67 | version "13.9.0" 68 | resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.0.tgz#5b6ee7a77faacddd7de719017d0bc12f52f81589" 69 | integrity sha512-0ARSQootUG1RljH2HncpsY2TJBfGQIKOOi7kxzUY6z54ePu/ZD+wJA8zI2Q6v8rol2qpG/rvqsReco8zNMPvhQ== 70 | 71 | "@types/node@10.12.18": 72 | version "10.12.18" 73 | resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" 74 | integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ== 75 | 76 | "@types/node@11.11.6": 77 | version "11.11.6" 78 | resolved "https://registry.yarnpkg.com/@types/node/-/node-11.11.6.tgz#df929d1bb2eee5afdda598a41930fe50b43eaa6a" 79 | integrity sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ== 80 | 81 | ajv-keywords@^3.4.1: 82 | version "3.4.1" 83 | resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" 84 | integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ== 85 | 86 | ajv@^6.10.2: 87 | version "6.12.6" 88 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" 89 | integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== 90 | dependencies: 91 | fast-deep-equal "^3.1.1" 92 | fast-json-stable-stringify "^2.0.0" 93 | json-schema-traverse "^0.4.1" 94 | uri-js "^4.2.2" 95 | 96 | ambi@^6.4.0: 97 | version "6.4.0" 98 | resolved "https://registry.yarnpkg.com/ambi/-/ambi-6.4.0.tgz#3eb9cd70888503d06d4bd10f35cf0bfb42334e96" 99 | integrity sha512-eMoOhqmD9FNSRdKG2LyEReBEeEGMOYM+2oNmLO0IOXjrPTRfxCGnsQiC/yIbnFNRPOyti54uFYA8NFW2PWfu/Q== 100 | dependencies: 101 | typechecker "^6.2.0" 102 | 103 | ansi-styles@^3.2.1: 104 | version "3.2.1" 105 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" 106 | integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== 107 | dependencies: 108 | color-convert "^1.9.0" 109 | 110 | args@^5.0.1: 111 | version "5.0.1" 112 | resolved "https://registry.yarnpkg.com/args/-/args-5.0.1.tgz#4bf298df90a4799a09521362c579278cc2fdd761" 113 | integrity sha512-1kqmFCFsPffavQFGt8OxJdIcETti99kySRUPMpOhaGjL6mRJn8HFU1OxKY5bMqfZKUwTQc1mZkAjmGYaVOHFtQ== 114 | dependencies: 115 | camelcase "5.0.0" 116 | chalk "2.4.2" 117 | leven "2.1.0" 118 | mri "1.1.4" 119 | 120 | base-x@^3.0.2: 121 | version "3.0.8" 122 | resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.8.tgz#1e1106c2537f0162e8b52474a557ebb09000018d" 123 | integrity sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA== 124 | dependencies: 125 | safe-buffer "^5.0.1" 126 | 127 | bcrypto@^5.2.0: 128 | version "5.2.0" 129 | resolved "https://registry.yarnpkg.com/bcrypto/-/bcrypto-5.2.0.tgz#7cc944d2cc2b7beeff04c74f8611a001612a981d" 130 | integrity sha512-yy+kDrUG6aXP7NIYq7kKIwlrXtx/51488IGfuqhyM6FYF8zNI1mPRwvAPvQ1RfE5e7WW7fVdZt4yHlmN4HJ4Hg== 131 | dependencies: 132 | bufio "~1.0.7" 133 | loady "~0.0.1" 134 | 135 | bindings@^1.3.0: 136 | version "1.5.0" 137 | resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" 138 | integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== 139 | dependencies: 140 | file-uri-to-path "1.0.0" 141 | 142 | bip32@^2.0.3: 143 | version "2.0.5" 144 | resolved "https://registry.yarnpkg.com/bip32/-/bip32-2.0.5.tgz#e3808a9e97a880dbafd0f5f09ca4a1e14ee275d2" 145 | integrity sha512-zVY4VvJV+b2fS0/dcap/5XLlpqtgwyN8oRkuGgAS1uLOeEp0Yo6Tw2yUTozTtlrMJO3G8n4g/KX/XGFHW6Pq3g== 146 | dependencies: 147 | "@types/node" "10.12.18" 148 | bs58check "^2.1.1" 149 | create-hash "^1.2.0" 150 | create-hmac "^1.1.7" 151 | tiny-secp256k1 "^1.1.3" 152 | typeforce "^1.11.5" 153 | wif "^2.0.6" 154 | 155 | bip39@^3.0.0, bip39@^3.0.2: 156 | version "3.0.2" 157 | resolved "https://registry.yarnpkg.com/bip39/-/bip39-3.0.2.tgz#2baf42ff3071fc9ddd5103de92e8f80d9257ee32" 158 | integrity sha512-J4E1r2N0tUylTKt07ibXvhpT2c5pyAFgvuA5q1H9uDy6dEGpjV8jmymh3MTYJDLCNbIVClSB9FbND49I6N24MQ== 159 | dependencies: 160 | "@types/node" "11.11.6" 161 | create-hash "^1.1.0" 162 | pbkdf2 "^3.0.9" 163 | randombytes "^2.0.1" 164 | 165 | bn.js@^4.11.8, bn.js@^4.11.9: 166 | version "4.12.0" 167 | resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" 168 | integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== 169 | 170 | brorand@^1.1.0: 171 | version "1.1.0" 172 | resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" 173 | integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= 174 | 175 | browserify-aes@^1.2.0: 176 | version "1.2.0" 177 | resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" 178 | integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== 179 | dependencies: 180 | buffer-xor "^1.0.3" 181 | cipher-base "^1.0.0" 182 | create-hash "^1.1.0" 183 | evp_bytestokey "^1.0.3" 184 | inherits "^2.0.1" 185 | safe-buffer "^5.0.1" 186 | 187 | bs58@^4.0.0: 188 | version "4.0.1" 189 | resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" 190 | integrity sha1-vhYedsNU9veIrkBx9j806MTwpCo= 191 | dependencies: 192 | base-x "^3.0.2" 193 | 194 | bs58check@<3.0.0, bs58check@^2.1.1: 195 | version "2.1.2" 196 | resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" 197 | integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== 198 | dependencies: 199 | bs58 "^4.0.0" 200 | create-hash "^1.1.0" 201 | safe-buffer "^5.1.2" 202 | 203 | bsert@~0.0.10: 204 | version "0.0.10" 205 | resolved "https://registry.yarnpkg.com/bsert/-/bsert-0.0.10.tgz#231ac82873a1418c6ade301ab5cd9ae385895597" 206 | integrity sha512-NHNwlac+WPy4t2LoNh8pXk8uaIGH3NSaIUbTTRXGpE2WEbq0te/tDykYHkFK57YKLPjv/aGHmbqvnGeVWDz57Q== 207 | 208 | bstring@^0.3.9: 209 | version "0.3.9" 210 | resolved "https://registry.yarnpkg.com/bstring/-/bstring-0.3.9.tgz#dc50294b54e9e767c07ca5592795dcc59ef1bf2e" 211 | integrity sha512-D95flI7SXL+UsQi9mW+hH+AK2AFfafIJi+3GbbyTAWMe2FqwR9keBxsjGiGd/JM+77Y9WsC+M4EhZVNVcym9jw== 212 | dependencies: 213 | bsert "~0.0.10" 214 | loady "~0.0.1" 215 | nan "^2.13.1" 216 | 217 | buffer-xor@^1.0.3: 218 | version "1.0.3" 219 | resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" 220 | integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= 221 | 222 | buffer-xor@^2.0.2: 223 | version "2.0.2" 224 | resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-2.0.2.tgz#34f7c64f04c777a1f8aac5e661273bb9dd320289" 225 | integrity sha512-eHslX0bin3GB+Lx2p7lEYRShRewuNZL3fUl4qlVJGGiwoPGftmt8JQgk2Y9Ji5/01TnVDo33E5b5O3vUB1HdqQ== 226 | dependencies: 227 | safe-buffer "^5.1.1" 228 | 229 | bufio@~1.0.7: 230 | version "1.0.7" 231 | resolved "https://registry.yarnpkg.com/bufio/-/bufio-1.0.7.tgz#b7f63a1369a0829ed64cc14edf0573b3e382a33e" 232 | integrity sha512-bd1dDQhiC+bEbEfg56IdBv7faWa6OipMs/AFFFvtFnB3wAYjlwQpQRZ0pm6ZkgtfL0pILRXhKxOiQj6UzoMR7A== 233 | 234 | bytebuffer@^5.0.1: 235 | version "5.0.1" 236 | resolved "https://registry.yarnpkg.com/bytebuffer/-/bytebuffer-5.0.1.tgz#582eea4b1a873b6d020a48d58df85f0bba6cfddd" 237 | integrity sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0= 238 | dependencies: 239 | long "~3" 240 | 241 | camelcase@5.0.0: 242 | version "5.0.0" 243 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42" 244 | integrity sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA== 245 | 246 | chalk@2.4.2, chalk@^2.4.2: 247 | version "2.4.2" 248 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" 249 | integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== 250 | dependencies: 251 | ansi-styles "^3.2.1" 252 | escape-string-regexp "^1.0.5" 253 | supports-color "^5.3.0" 254 | 255 | cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: 256 | version "1.0.4" 257 | resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" 258 | integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== 259 | dependencies: 260 | inherits "^2.0.1" 261 | safe-buffer "^5.0.1" 262 | 263 | color-convert@^1.9.0: 264 | version "1.9.3" 265 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" 266 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== 267 | dependencies: 268 | color-name "1.1.3" 269 | 270 | color-name@1.1.3: 271 | version "1.1.3" 272 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 273 | integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= 274 | 275 | commander@^4.0.0: 276 | version "4.1.1" 277 | resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" 278 | integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== 279 | 280 | create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: 281 | version "1.2.0" 282 | resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" 283 | integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== 284 | dependencies: 285 | cipher-base "^1.0.1" 286 | inherits "^2.0.1" 287 | md5.js "^1.3.4" 288 | ripemd160 "^2.0.1" 289 | sha.js "^2.4.0" 290 | 291 | create-hmac@^1.1.4, create-hmac@^1.1.7: 292 | version "1.1.7" 293 | resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" 294 | integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== 295 | dependencies: 296 | cipher-base "^1.0.3" 297 | create-hash "^1.1.0" 298 | inherits "^2.0.1" 299 | ripemd160 "^2.0.0" 300 | safe-buffer "^5.0.1" 301 | sha.js "^2.4.8" 302 | 303 | dateformat@^3.0.3: 304 | version "3.0.3" 305 | resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" 306 | integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== 307 | 308 | dayjs@^1.8.15: 309 | version "1.8.21" 310 | resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.21.tgz#98299185b72b9b679f31c7ed987b63923c961552" 311 | integrity sha512-1kbWK0hziklUHkGgiKr7xm59KwAg/K3Tp7H/8X+f58DnNCwY3pKYjOCJpIlVs125FRBukGVZdKZojC073D0IeQ== 312 | 313 | deepmerge@^4.0.0, deepmerge@^4.2.2: 314 | version "4.2.2" 315 | resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" 316 | integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== 317 | 318 | eachr@^4.5.0: 319 | version "4.5.0" 320 | resolved "https://registry.yarnpkg.com/eachr/-/eachr-4.5.0.tgz#495eb3aab6a41811da1e04e510424df32075cf04" 321 | integrity sha512-9I664RWp6p8jvcHZIwo7bWaiSaUmA1wNSLKwNZEiaYjqiTARq3cGjyRiIunsopZv4QMmX3T5Hs17QoPAzdYxfg== 322 | dependencies: 323 | typechecker "^6.2.0" 324 | 325 | elliptic@^6.4.0: 326 | version "6.5.4" 327 | resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" 328 | integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== 329 | dependencies: 330 | bn.js "^4.11.9" 331 | brorand "^1.1.0" 332 | hash.js "^1.0.0" 333 | hmac-drbg "^1.0.1" 334 | inherits "^2.0.4" 335 | minimalistic-assert "^1.0.1" 336 | minimalistic-crypto-utils "^1.0.1" 337 | 338 | end-of-stream@^1.1.0: 339 | version "1.4.4" 340 | resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" 341 | integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== 342 | dependencies: 343 | once "^1.4.0" 344 | 345 | envfile@^4.0.0: 346 | version "4.5.0" 347 | resolved "https://registry.yarnpkg.com/envfile/-/envfile-4.5.0.tgz#3ca690377714bee899cbcdf6503c01f37868b99b" 348 | integrity sha512-y/RIRDYqbb4ng1PtH/VIsnUceo3vBgmOxhJvsh7rwnXokcQMyEV1R9e+so2SekbZise3OqmGFUuXpOL6yZgJ/w== 349 | dependencies: 350 | ambi "^6.4.0" 351 | eachr "^4.5.0" 352 | typechecker "^6.2.0" 353 | 354 | escape-string-regexp@^1.0.5: 355 | version "1.0.5" 356 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 357 | integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= 358 | 359 | evp_bytestokey@^1.0.3: 360 | version "1.0.3" 361 | resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" 362 | integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== 363 | dependencies: 364 | md5.js "^1.3.4" 365 | safe-buffer "^5.1.1" 366 | 367 | expand-home-dir@0.0.3: 368 | version "0.0.3" 369 | resolved "https://registry.yarnpkg.com/expand-home-dir/-/expand-home-dir-0.0.3.tgz#72de8a0486cc28a3bbd704635398825b5b62827d" 370 | integrity sha1-ct6KBIbMKKO71wRjU5iCW1tign0= 371 | 372 | fast-copy@^2.1.0: 373 | version "2.1.0" 374 | resolved "https://registry.yarnpkg.com/fast-copy/-/fast-copy-2.1.0.tgz#99c1b842aee063f8212d6f749080c196a822b293" 375 | integrity sha512-j4VxAVJsu9NHveYrIj0+nJxXe2lOlibKTlyy0jH8DBwcuV6QyXTy0zTqZhmMKo7EYvuaUk/BFj/o6NU6grE5ag== 376 | 377 | fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: 378 | version "3.1.3" 379 | resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" 380 | integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== 381 | 382 | fast-json-stable-stringify@^2.0.0: 383 | version "2.1.0" 384 | resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" 385 | integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== 386 | 387 | fast-memoize@^2.5.1: 388 | version "2.5.1" 389 | resolved "https://registry.yarnpkg.com/fast-memoize/-/fast-memoize-2.5.1.tgz#c3519241e80552ce395e1a32dcdde8d1fd680f5d" 390 | integrity sha512-xdmw296PCL01tMOXx9mdJSmWY29jQgxyuZdq0rEHMu+Tpe1eOEtCycoG6chzlcrWsNgpZP7oL8RiQr7+G6Bl6g== 391 | 392 | fast-redact@^2.0.0: 393 | version "2.0.0" 394 | resolved "https://registry.yarnpkg.com/fast-redact/-/fast-redact-2.0.0.tgz#17bb8f5e1f56ecf4a38c8455985e5eab4c478431" 395 | integrity sha512-zxpkULI9W9MNTK2sJ3BpPQrTEXFNESd2X6O1tXMFpK/XM0G5c5Rll2EVYZH2TqI3xRGK/VaJ+eEOt7pnENJpeA== 396 | 397 | fast-safe-stringify@^2.0.7: 398 | version "2.0.7" 399 | resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743" 400 | integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA== 401 | 402 | fast-sort@^2.2.0: 403 | version "2.2.0" 404 | resolved "https://registry.yarnpkg.com/fast-sort/-/fast-sort-2.2.0.tgz#20903763531fbcbb41c9df5ab1bf5f2cefc8476a" 405 | integrity sha512-W7zqnn2zsYoQA87FKmYtgOsbJohOrh7XrtZrCVHN5XZKqTBTv5UG+rSS3+iWbg/nepRQUOu+wnas8BwtK8kiCg== 406 | 407 | file-uri-to-path@1.0.0: 408 | version "1.0.0" 409 | resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" 410 | integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== 411 | 412 | flatstr@^1.0.12: 413 | version "1.0.12" 414 | resolved "https://registry.yarnpkg.com/flatstr/-/flatstr-1.0.12.tgz#c2ba6a08173edbb6c9640e3055b95e287ceb5931" 415 | integrity sha512-4zPxDyhCyiN2wIAtSLI6gc82/EjqZc1onI4Mz/l0pWrAlsSfYH/2ZIcU+e3oA2wDwbzIWNKwa23F8rh6+DRWkw== 416 | 417 | fs-extra@^8.0.0: 418 | version "8.1.0" 419 | resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" 420 | integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== 421 | dependencies: 422 | graceful-fs "^4.2.0" 423 | jsonfile "^4.0.0" 424 | universalify "^0.1.0" 425 | 426 | globalyzer@^0.1.0: 427 | version "0.1.4" 428 | resolved "https://registry.yarnpkg.com/globalyzer/-/globalyzer-0.1.4.tgz#bc8e273afe1ac7c24eea8def5b802340c5cc534f" 429 | integrity sha512-LeguVWaxgHN0MNbWC6YljNMzHkrCny9fzjmEUdnF1kQ7wATFD1RHFRqA1qxaX2tgxGENlcxjOflopBwj3YZiXA== 430 | 431 | globrex@^0.1.1: 432 | version "0.1.2" 433 | resolved "https://registry.yarnpkg.com/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098" 434 | integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg== 435 | 436 | graceful-fs@^4.1.6, graceful-fs@^4.2.0: 437 | version "4.2.3" 438 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" 439 | integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== 440 | 441 | has-flag@^3.0.0: 442 | version "3.0.0" 443 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 444 | integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= 445 | 446 | hash-base@^3.0.0: 447 | version "3.0.4" 448 | resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" 449 | integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg= 450 | dependencies: 451 | inherits "^2.0.1" 452 | safe-buffer "^5.0.1" 453 | 454 | hash.js@^1.0.0, hash.js@^1.0.3: 455 | version "1.1.7" 456 | resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" 457 | integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== 458 | dependencies: 459 | inherits "^2.0.3" 460 | minimalistic-assert "^1.0.1" 461 | 462 | hmac-drbg@^1.0.1: 463 | version "1.0.1" 464 | resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" 465 | integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= 466 | dependencies: 467 | hash.js "^1.0.3" 468 | minimalistic-assert "^1.0.0" 469 | minimalistic-crypto-utils "^1.0.1" 470 | 471 | hoek@6.x.x: 472 | version "6.1.3" 473 | resolved "https://registry.yarnpkg.com/hoek/-/hoek-6.1.3.tgz#73b7d33952e01fe27a38b0457294b79dd8da242c" 474 | integrity sha512-YXXAAhmF9zpQbC7LEcREFtXfGq5K1fmd+4PHkBq8NUqmzW3G+Dq10bI/i0KucLRwss3YYFQ0fSfoxBZYiGUqtQ== 475 | 476 | inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4: 477 | version "2.0.4" 478 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 479 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 480 | 481 | ipaddr.js@^1.9.0: 482 | version "1.9.1" 483 | resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" 484 | integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== 485 | 486 | isemail@3.x.x: 487 | version "3.2.0" 488 | resolved "https://registry.yarnpkg.com/isemail/-/isemail-3.2.0.tgz#59310a021931a9fb06bbb51e155ce0b3f236832c" 489 | integrity sha512-zKqkK+O+dGqevc93KNsbZ/TqTUFd46MwWjYOoMrjIMZ51eU7DtQG3Wmd9SQQT7i7RVnuTPEiYEWHU3MSbxC1Tg== 490 | dependencies: 491 | punycode "2.x.x" 492 | 493 | jmespath@^0.15.0: 494 | version "0.15.0" 495 | resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" 496 | integrity sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc= 497 | 498 | joi@^14.3.0: 499 | version "14.3.1" 500 | resolved "https://registry.yarnpkg.com/joi/-/joi-14.3.1.tgz#164a262ec0b855466e0c35eea2a885ae8b6c703c" 501 | integrity sha512-LQDdM+pkOrpAn4Lp+neNIFV3axv1Vna3j38bisbQhETPMANYRbFJFUyOZcOClYvM/hppMhGWuKSFEK9vjrB+bQ== 502 | dependencies: 503 | hoek "6.x.x" 504 | isemail "3.x.x" 505 | topo "3.x.x" 506 | 507 | joycon@^2.2.5: 508 | version "2.2.5" 509 | resolved "https://registry.yarnpkg.com/joycon/-/joycon-2.2.5.tgz#8d4cf4cbb2544d7b7583c216fcdfec19f6be1615" 510 | integrity sha512-YqvUxoOcVPnCp0VU1/56f+iKSdvIRJYPznH22BdXV3xMk75SFXhWeJkZ8C9XxUWt1b5x2X1SxuFygW1U0FmkEQ== 511 | 512 | json-schema-traverse@^0.4.1: 513 | version "0.4.1" 514 | resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" 515 | integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== 516 | 517 | jsonfile@^4.0.0: 518 | version "4.0.0" 519 | resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" 520 | integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= 521 | optionalDependencies: 522 | graceful-fs "^4.1.6" 523 | 524 | leven@2.1.0: 525 | version "2.1.0" 526 | resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" 527 | integrity sha1-wuep93IJTe6dNCAq6KzORoeHVYA= 528 | 529 | loady@~0.0.1: 530 | version "0.0.1" 531 | resolved "https://registry.yarnpkg.com/loady/-/loady-0.0.1.tgz#24a99c14cfed9cd0bffed365b1836035303f7e5d" 532 | integrity sha512-PW5Z13Jd0v6ZcA1P6ZVUc3EV8BJwQuAiwUvvT6VQGHoaZ1d/tu7r1QZctuKfQqwy9SFBWeAGfcIdLxhp7ZW3Rw== 533 | 534 | lodash.get@^4.4.2: 535 | version "4.4.2" 536 | resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" 537 | integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= 538 | 539 | lodash.set@^4.3.2: 540 | version "4.3.2" 541 | resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23" 542 | integrity sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM= 543 | 544 | lodash.sumby@^4.6.0: 545 | version "4.6.0" 546 | resolved "https://registry.yarnpkg.com/lodash.sumby/-/lodash.sumby-4.6.0.tgz#7d87737ddb216da2f7e5e7cd2dd9c403a7887346" 547 | integrity sha1-fYdzfdshbaL35efNLdnEA6eIc0Y= 548 | 549 | long@~3: 550 | version "3.2.0" 551 | resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b" 552 | integrity sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s= 553 | 554 | md5.js@^1.3.4: 555 | version "1.3.5" 556 | resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" 557 | integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== 558 | dependencies: 559 | hash-base "^3.0.0" 560 | inherits "^2.0.1" 561 | safe-buffer "^5.1.2" 562 | 563 | minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: 564 | version "1.0.1" 565 | resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" 566 | integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== 567 | 568 | minimalistic-crypto-utils@^1.0.1: 569 | version "1.0.1" 570 | resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" 571 | integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= 572 | 573 | mri@1.1.4: 574 | version "1.1.4" 575 | resolved "https://registry.yarnpkg.com/mri/-/mri-1.1.4.tgz#7cb1dd1b9b40905f1fac053abe25b6720f44744a" 576 | integrity sha512-6y7IjGPm8AzlvoUrwAaw1tLnUBudaS3752vcd8JtrpGGQn+rXIe63LFVHm/YMwtqAuh+LJPCFdlLYPWM1nYn6w== 577 | 578 | nan@^2.13.1, nan@^2.13.2: 579 | version "2.14.0" 580 | resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" 581 | integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== 582 | 583 | once@^1.3.1, once@^1.4.0: 584 | version "1.4.0" 585 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 586 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 587 | dependencies: 588 | wrappy "1" 589 | 590 | pbkdf2@^3.0.9: 591 | version "3.0.17" 592 | resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" 593 | integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== 594 | dependencies: 595 | create-hash "^1.1.2" 596 | create-hmac "^1.1.4" 597 | ripemd160 "^2.0.1" 598 | safe-buffer "^5.0.1" 599 | sha.js "^2.4.8" 600 | 601 | pino-pretty@^3.0.0: 602 | version "3.6.0" 603 | resolved "https://registry.yarnpkg.com/pino-pretty/-/pino-pretty-3.6.0.tgz#a6c23948c7d16f4d925da3ff9646e6bdaa87ecca" 604 | integrity sha512-gTVA+Kx4DoVQl+sXO4/HdLVaNgr281b+NDJWmXzreIoQ+3fd7xVyTg31c0hpzCUbheuW4TpzQOqDg9uOIsbw7Q== 605 | dependencies: 606 | "@hapi/bourne" "^1.3.2" 607 | args "^5.0.1" 608 | chalk "^2.4.2" 609 | dateformat "^3.0.3" 610 | fast-safe-stringify "^2.0.7" 611 | jmespath "^0.15.0" 612 | joycon "^2.2.5" 613 | pump "^3.0.0" 614 | readable-stream "^3.4.0" 615 | split2 "^3.1.1" 616 | strip-json-comments "^3.0.1" 617 | 618 | pino-std-serializers@^2.4.2: 619 | version "2.4.2" 620 | resolved "https://registry.yarnpkg.com/pino-std-serializers/-/pino-std-serializers-2.4.2.tgz#cb5e3e58c358b26f88969d7e619ae54bdfcc1ae1" 621 | integrity sha512-WaL504dO8eGs+vrK+j4BuQQq6GLKeCCcHaMB2ItygzVURcL1CycwNEUHTD/lHFHs/NL5qAz2UKrjYWXKSf4aMQ== 622 | 623 | pino@^5.9.0: 624 | version "5.16.0" 625 | resolved "https://registry.yarnpkg.com/pino/-/pino-5.16.0.tgz#94d01cb38b5f4a16dd4d7c47aa489fbfe40c3c06" 626 | integrity sha512-k9cDzHd9S/oYSQ9B9g9+7RXkfsZX78sQXERC8x4p2XArECZXULx9nqNwZvJHsLj779wPCt+ybN+dG8jFR70p6Q== 627 | dependencies: 628 | fast-redact "^2.0.0" 629 | fast-safe-stringify "^2.0.7" 630 | flatstr "^1.0.12" 631 | pino-std-serializers "^2.4.2" 632 | quick-format-unescaped "^3.0.3" 633 | sonic-boom "^0.7.5" 634 | 635 | pump@^3.0.0: 636 | version "3.0.0" 637 | resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" 638 | integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== 639 | dependencies: 640 | end-of-stream "^1.1.0" 641 | once "^1.3.1" 642 | 643 | punycode@2.x.x, punycode@^2.1.0: 644 | version "2.1.1" 645 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" 646 | integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== 647 | 648 | quick-format-unescaped@^3.0.3: 649 | version "3.0.3" 650 | resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-3.0.3.tgz#fb3e468ac64c01d22305806c39f121ddac0d1fb9" 651 | integrity sha512-dy1yjycmn9blucmJLXOfZDx1ikZJUi6E8bBZLnhPG5gBrVhHXx2xVyqqgKBubVNEXmx51dBACMHpoMQK/N/AXQ== 652 | 653 | randombytes@^2.0.1: 654 | version "2.1.0" 655 | resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" 656 | integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== 657 | dependencies: 658 | safe-buffer "^5.1.0" 659 | 660 | readable-stream@^3.0.0, readable-stream@^3.4.0: 661 | version "3.6.0" 662 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" 663 | integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== 664 | dependencies: 665 | inherits "^2.0.3" 666 | string_decoder "^1.1.1" 667 | util-deprecate "^1.0.1" 668 | 669 | ripemd160@^2.0.0, ripemd160@^2.0.1: 670 | version "2.0.2" 671 | resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" 672 | integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== 673 | dependencies: 674 | hash-base "^3.0.0" 675 | inherits "^2.0.1" 676 | 677 | safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: 678 | version "5.2.0" 679 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" 680 | integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== 681 | 682 | sha.js@^2.4.0, sha.js@^2.4.8: 683 | version "2.4.11" 684 | resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" 685 | integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== 686 | dependencies: 687 | inherits "^2.0.1" 688 | safe-buffer "^5.0.1" 689 | 690 | sonic-boom@^0.7.5: 691 | version "0.7.6" 692 | resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-0.7.6.tgz#c42df6df884a6a3d54fa7a45b11e4e2196818d45" 693 | integrity sha512-k9E2QQ4zxuVRLDW+ZW6ISzJs3wlEorVdmM7ApDgor7wsGKSDG5YGHsGmgLY4XYh4DMlr/2ap2BWAE7yTFJtWnQ== 694 | dependencies: 695 | flatstr "^1.0.12" 696 | 697 | split2@^3.1.1: 698 | version "3.1.1" 699 | resolved "https://registry.yarnpkg.com/split2/-/split2-3.1.1.tgz#c51f18f3e06a8c4469aaab487687d8d956160bb6" 700 | integrity sha512-emNzr1s7ruq4N+1993yht631/JH+jaj0NYBosuKmLcq+JkGQ9MmTw1RB1fGaTCzUuseRIClrlSLHRNYGwWQ58Q== 701 | dependencies: 702 | readable-stream "^3.0.0" 703 | 704 | string_decoder@^1.1.1: 705 | version "1.3.0" 706 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" 707 | integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== 708 | dependencies: 709 | safe-buffer "~5.2.0" 710 | 711 | strip-json-comments@^3.0.1: 712 | version "3.0.1" 713 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7" 714 | integrity sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw== 715 | 716 | supports-color@^5.3.0: 717 | version "5.5.0" 718 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" 719 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== 720 | dependencies: 721 | has-flag "^3.0.0" 722 | 723 | tiny-glob@^0.2.6: 724 | version "0.2.6" 725 | resolved "https://registry.yarnpkg.com/tiny-glob/-/tiny-glob-0.2.6.tgz#9e056e169d9788fe8a734dfa1ff02e9b92ed7eda" 726 | integrity sha512-A7ewMqPu1B5PWwC3m7KVgAu96Ch5LA0w4SnEN/LbDREj/gAD0nPWboRbn8YoP9ISZXqeNAlMvKSKoEuhcfK3Pw== 727 | dependencies: 728 | globalyzer "^0.1.0" 729 | globrex "^0.1.1" 730 | 731 | tiny-secp256k1@^1.1.3: 732 | version "1.1.3" 733 | resolved "https://registry.yarnpkg.com/tiny-secp256k1/-/tiny-secp256k1-1.1.3.tgz#e93b1e1bf62e9bd1ad3ab24af27ff6127ce0e077" 734 | integrity sha512-ZpobrhOtHP98VYEN51IYQH1YcrbFpnxFhI6ceWa3OEbJn7eHvSd8YFjGPxbedGCy7PNYU1v/+BRsdvyr5uRd4g== 735 | dependencies: 736 | bindings "^1.3.0" 737 | bn.js "^4.11.8" 738 | create-hmac "^1.1.7" 739 | elliptic "^6.4.0" 740 | nan "^2.13.2" 741 | 742 | topo@3.x.x: 743 | version "3.0.3" 744 | resolved "https://registry.yarnpkg.com/topo/-/topo-3.0.3.tgz#d5a67fb2e69307ebeeb08402ec2a2a6f5f7ad95c" 745 | integrity sha512-IgpPtvD4kjrJ7CRA3ov2FhWQADwv+Tdqbsf1ZnPUSAtCJ9e1Z44MmoSGDXGk4IppoZA7jd/QRkNddlLJWlUZsQ== 746 | dependencies: 747 | hoek "6.x.x" 748 | 749 | type-fest@^0.16.0: 750 | version "0.16.0" 751 | resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.16.0.tgz#3240b891a78b0deae910dbeb86553e552a148860" 752 | integrity sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg== 753 | 754 | typechecker@^6.2.0: 755 | version "6.3.0" 756 | resolved "https://registry.yarnpkg.com/typechecker/-/typechecker-6.3.0.tgz#c8ee2fee30e1d1156d3063efb9d115c859c3cf5b" 757 | integrity sha512-XZmZISfAzrzGHaC2nAwXyh/O1srpTIw/sFS5K0wGRIoWgc+bpGXJLkpI5VoZg9+2SwV6tFIS3WCb3l0bNitLag== 758 | 759 | typeforce@^1.11.5: 760 | version "1.18.0" 761 | resolved "https://registry.yarnpkg.com/typeforce/-/typeforce-1.18.0.tgz#d7416a2c5845e085034d70fcc5b6cc4a90edbfdc" 762 | integrity sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g== 763 | 764 | universalify@^0.1.0: 765 | version "0.1.2" 766 | resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" 767 | integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== 768 | 769 | uri-js@^4.2.2: 770 | version "4.4.1" 771 | resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" 772 | integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== 773 | dependencies: 774 | punycode "^2.1.0" 775 | 776 | util-deprecate@^1.0.1: 777 | version "1.0.2" 778 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 779 | integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= 780 | 781 | wif@^2.0.6: 782 | version "2.0.6" 783 | resolved "https://registry.yarnpkg.com/wif/-/wif-2.0.6.tgz#08d3f52056c66679299726fade0d432ae74b4704" 784 | integrity sha1-CNP1IFbGZnkplyb63g1DKudLRwQ= 785 | dependencies: 786 | bs58check "<3.0.0" 787 | 788 | wrappy@1: 789 | version "1.0.2" 790 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 791 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 792 | -------------------------------------------------------------------------------- /prefixes.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": 0, 3 | "2": 3, 4 | "3": 5, 5 | "4": 8, 6 | "5": 10, 7 | "6": 13, 8 | "7": 15, 9 | "8": 18, 10 | "9": 20, 11 | "A": 23, 12 | "B": 25, 13 | "C": 28, 14 | "D": 30, 15 | "E": 33, 16 | "F": 35, 17 | "G": 38, 18 | "H": 40, 19 | "J": 43, 20 | "K": 45, 21 | "L": 48, 22 | "M": 50, 23 | "N": 53, 24 | "P": 55, 25 | "Q": 58, 26 | "R": 60, 27 | "S": 63, 28 | "T": 65, 29 | "U": 68, 30 | "V": 70, 31 | "W": 73, 32 | "X": 75, 33 | "Y": 78, 34 | "Z": 80, 35 | "a": 83, 36 | "b": 85, 37 | "c": 87, 38 | "d": 90, 39 | "e": 92, 40 | "f": 95, 41 | "g": 97, 42 | "h": 100, 43 | "j": 105, 44 | "k": 107, 45 | "m": 110, 46 | "n": 112, 47 | "o": 115, 48 | "p": 117, 49 | "q": 120, 50 | "r": 122, 51 | "s": 125, 52 | "t": 127, 53 | "u": 130, 54 | "v": 132, 55 | "w": 135, 56 | "x": 137, 57 | "y": 140, 58 | "z": 142 59 | } 60 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["config:base", ":preserveSemverRanges"] 3 | } 4 | -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | curl -sL https://deb.nodesource.com/setup_12.x | sudo bash - 4 | curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - 5 | echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list 6 | sudo apt-get update && sudo apt-get install -y nodejs yarn jq 7 | 8 | if [[ -f ~/.profile ]]; then 9 | echo "export PATH=\"\$PATH:\$(yarn global bin)\"" >> ~/.profile 10 | source ~/.profile 11 | elif [ -f ~/.bash_profile ]; then 12 | echo "export PATH=\"\$PATH:\$(yarn global bin)\"" >> ~/.bash_profile 13 | source ~/.bash_profile 14 | fi 15 | -------------------------------------------------------------------------------- /vagrant/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "coreIp": "192.168.33.10", 3 | "p2pPort": 4102, 4 | "apiPort": 4103, 5 | "webhookPort": 4104, 6 | "jsonRpcPort": 8080, 7 | "explorerIp": "192.168.33.10", 8 | "explorerPort": 4200, 9 | "chainName": "MyTest", 10 | "token": "MYTEST", 11 | "databaseHost": "localhost", 12 | "databasePort": "5432", 13 | "databaseName": "core_mytest", 14 | "symbol": "MT", 15 | "mainnetPeers": [], 16 | "devnetPeers": [], 17 | "mainnetPrefix": "M", 18 | "devnetPrefix": "D", 19 | "testnetPrefix": "T", 20 | "fees": { 21 | "static": { 22 | "transfer": 10000000, 23 | "vote": 100000000, 24 | "secondSignature": 500000000, 25 | "delegateRegistration": 2500000000, 26 | "multiSignature": 500000000, 27 | "ipfs": 500000000, 28 | "multiPayment": 10000000, 29 | "delegateResignation": 2500000000 30 | }, 31 | "dynamic": { 32 | "enabled": false, 33 | "minFeePool": 3000, 34 | "minFeeBroadcast": 3000, 35 | "addonBytes": { 36 | "transfer": 100, 37 | "secondSignature": 250, 38 | "delegateRegistration": 400000, 39 | "vote": 100, 40 | "multiSignature": 500, 41 | "ipfs": 250, 42 | "multiPayment": 500, 43 | "delegateResignation": 400000 44 | } 45 | } 46 | }, 47 | "forgers": 5, 48 | "blocktime": 16, 49 | "transactionsPerBlock": 500, 50 | "totalPremine": 2100000000000000, 51 | "rewardHeightStart": 100, 52 | "rewardPerBlock": 200000000, 53 | "vendorFieldLength": 255, 54 | "bridgechainPath": "$HOME/core-bridgechain", 55 | "explorerPath": "$HOME/core-explorer", 56 | "gitCoreCommit": true, 57 | "gitCoreOrigin": "git@github.com:ArkEcosystem/vagrant-core.git", 58 | "gitExplorerCommit": true, 59 | "gitExplorerOrigin": "git@github.com:ArkEcosystem/vagrant-explorer.git", 60 | "licenseName": "MyTest Vagrant", 61 | "licenseEmail": "vagrant@mytest.com" 62 | } 63 | -------------------------------------------------------------------------------- /vagrant/setup.sh: -------------------------------------------------------------------------------- 1 | ############################ 2 | # ARK Deployer Vagrant # 3 | ############################ 4 | 5 | ## Remount /vagrant as Read/Write 6 | sudo mount -o remount,rw /vagrant/vagrant /vagrant 7 | 8 | ## Update and Install Initial Packages 9 | sudo apt-get update && sudo apt-get install -y jq git curl software-properties-common 10 | 11 | ## Install NodeJS & NPM 12 | curl -sL https://deb.nodesource.com/setup_12.x | sudo bash - 13 | sudo apt-get update && sudo apt-get install nodejs 14 | 15 | ## Install Yarn 16 | curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - 17 | echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list 18 | sudo apt-get update && sudo apt-get install -y yarn 19 | 20 | ## Link Codebase 21 | if [[ ! -d ~/ark-deployer/ ]]; then 22 | ln -s /vagrant ~/ark-deployer 23 | fi 24 | 25 | ## Config 26 | CONFIG_PATH="/vagrant/vagrant/config.json" 27 | CHAIN_NAME=$(jq -r '.chainName' "$CONFIG_PATH") 28 | 29 | ## Install Core & Explorer with Dependencies 30 | cd ~/ark-deployer 31 | ./bridgechain.sh install-core --config "$CONFIG_PATH" --autoinstall-deps --non-interactive 32 | ./bridgechain.sh install-explorer --config "$CONFIG_PATH" --skip-deps --non-interactive 33 | 34 | ## Setup startup and login scripts 35 | cat >> ~/.profile <<- EOS 36 | export PATH="/home/vagrant/bin:/home/vagrant/.local/bin:/home/vagrant/.yarn/bin:\$PATH" 37 | EOS 38 | 39 | cat > ~/startup.sh <<- EOS 40 | #!/bin/bash -l 41 | ~/ark-deployer/bridgechain.sh start-core --network "testnet" &>> ~/core.log & 42 | ~/ark-deployer/bridgechain.sh start-explorer --network "testnet" &>> ~/explorer.log & 43 | EOS 44 | chmod u+x ~/startup.sh 45 | 46 | echo '@reboot sleep 10; sudo mount -t vboxsf -o ro vagrant /vagrant &>> ~/mount.log' > ~/cron.sh 47 | echo '@reboot sleep 15; env USER=$LOGNAME ~/startup.sh' >> ~/cron.sh 48 | crontab ~/cron.sh 49 | rm ~/cron.sh 50 | 51 | API_PORT=$(jq -r '.apiPort' "$CONFIG_PATH") 52 | P2P_PORT=$(jq -r '.p2pPort' "$CONFIG_PATH") 53 | EXPLORER_PORT=$(jq -r '.explorerPort' "$CONFIG_PATH") 54 | 55 | ~/ark-deployer/bridgechain.sh passphrases 56 | 57 | echo 'Rebooting Vagrant Machine - check back in a few minutes on the below:' 58 | echo " Core P2P API: http://192.168.33.10:$P2P_PORT/" 59 | echo " Core Public API: http://192.168.33.10:$API_PORT/" 60 | echo " Explorer: http://192.168.33.10:$EXPLORER_PORT/" 61 | 62 | sudo reboot 63 | --------------------------------------------------------------------------------