guardian-set-init.sh 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #!/usr/bin/env bash
  2. # This script allows devnet initalization with more than one guardian.
  3. # First argument is the number of guardians for the initial guardian set.
  4. set -exuo pipefail
  5. numGuardians=$1
  6. echo "number of guardians to initialize: ${numGuardians}"
  7. addressesJson="./scripts/devnet-consts.json"
  8. # working files for accumulating state
  9. envFile="./scripts/.env.hex" # for generic hex data, for solana, terra, etc
  10. ethFile="./scripts/.env.0x" # for "0x" prefixed data, for ethereum scripts
  11. # copy the eth defaults so we can override just the things we need
  12. cp ./ethereum/.env.test $ethFile
  13. # function for updating or inserting a KEY=value pair in a file.
  14. function upsert_env_file {
  15. file=${1} # file will be created if it does not exist.
  16. key=${2} # line must start with the key.
  17. new_value=${3}
  18. # replace the value if it exists, else, append it to the file
  19. if [[ -f $file ]] && grep -q "^$key=" $file; then
  20. # file has the key, update it:
  21. sed -i "/^$key=/s/=.*/=$new_value/" $file
  22. else
  23. # file does not have the key, add it:
  24. echo "$key=$new_value" >> $file
  25. fi
  26. }
  27. # assert jq exists before trying to use it
  28. if ! type -p jq; then
  29. echo "ERROR: jq is not installed"! >&2
  30. exit 1
  31. fi
  32. # 1) guardian public keys - used as the inital guardian set when initializing contracts.
  33. echo "generating guardian set addresses"
  34. # create an array of strings containing the ECDSA public keys of the devnet guardians in the guardianset:
  35. # guardiansPublicEth has the leading "0x" that Eth scripts expect.
  36. guardiansPublicEth=$(jq -c --argjson lastIndex $numGuardians '.devnetGuardians[:$lastIndex] | [.[].public]' $addressesJson)
  37. # guardiansPublicHex does not have a leading "0x", just hex strings.
  38. guardiansPublicHex=$(jq -c --argjson lastIndex $numGuardians '.devnetGuardians[:$lastIndex] | [.[].public[2:]]' $addressesJson)
  39. # also make a CSV string of the hex addresses, so the client scripts that need that format don't have to.
  40. guardiansPublicHexCSV=$(echo ${guardiansPublicHex} | jq --raw-output -c '. | join(",")')
  41. # write the lists of addresses to the env files
  42. initSigners="INIT_SIGNERS"
  43. upsert_env_file $ethFile $initSigners $guardiansPublicEth
  44. upsert_env_file $envFile $initSigners $guardiansPublicHex
  45. upsert_env_file $envFile "INIT_SIGNERS_CSV" $guardiansPublicHexCSV
  46. # 2) guardian private keys - used for generating the initial governance VAAs (register token bridge & nft bridge contracts on each chain).
  47. echo "generating guardian set keys"
  48. # create an array of strings containing the private keys of the devnet guardians in the guardianset
  49. guardiansPrivate=$(jq -c --argjson lastIndex $numGuardians '.devnetGuardians[:$lastIndex] | [.[].private]' $addressesJson)
  50. # create a CSV string with the private keys of the guardians in the guardianset, that will be used to create registration VAAs
  51. guardiansPrivateCSV=$( echo ${guardiansPrivate} | jq --raw-output -c '. | join(",")')
  52. # write the lists of keys to the env files
  53. upsert_env_file $ethFile "INIT_SIGNERS_KEYS_JSON" $guardiansPrivate
  54. upsert_env_file $envFile "INIT_SIGNERS_KEYS_CSV" $guardiansPrivateCSV
  55. # 3) fetch and store the contract addresses that we need to make contract registration governance VAAs for:
  56. echo "getting contract addresses for chain registrations from $addressesJson"
  57. # get addresses from the constants file
  58. solTokenBridge=$(jq --raw-output '.chains."1".contracts.tokenBridgeEmitterAddress' $addressesJson)
  59. ethTokenBridge=$(jq --raw-output '.chains."2".contracts.tokenBridgeEmitterAddress' $addressesJson)
  60. terraTokenBridge=$(jq --raw-output '.chains."3".contracts.tokenBridgeEmitterAddress' $addressesJson)
  61. bscTokenBridge=$(jq --raw-output '.chains."4".contracts.tokenBridgeEmitterAddress' $addressesJson)
  62. algoTokenBridge=$(jq --raw-output '.chains."8".contracts.tokenBridgeEmitterAddress' $addressesJson)
  63. solNFTBridge=$(jq --raw-output '.chains."1".contracts.nftBridgeEmitterAddress' $addressesJson)
  64. ethNFTBridge=$(jq --raw-output '.chains."2".contracts.nftBridgeEmitterAddress' $addressesJson)
  65. terraNFTBridge=$(jq --raw-output '.chains."3".contracts.nftBridgeEmitterAddress' $addressesJson)
  66. # 4) create token bridge registration VAAs
  67. echo "generating contract registration VAAs for token bridges"
  68. # fetch dependencies for the clients/token_bridge script that generates token bridge registration VAAs
  69. if [[ ! -d ./clients/token_bridge/node_modules ]]; then
  70. echo "going to install node modules in clients/token_bridge"
  71. npm ci --prefix clients/token_bridge && npm run build --prefix clients/token_bridge
  72. fi
  73. # invoke clients/token_bridge commands to create registration VAAs
  74. solTokenBridgeVAA=$(npm --prefix clients/token_bridge run --silent main -- generate_register_chain_vaa 1 0x${solTokenBridge} --guardian_secret ${guardiansPrivateCSV})
  75. ethTokenBridgeVAA=$(npm --prefix clients/token_bridge run --silent main -- generate_register_chain_vaa 2 0x${ethTokenBridge} --guardian_secret ${guardiansPrivateCSV} )
  76. terraTokenBridgeVAA=$(npm --prefix clients/token_bridge run --silent main -- generate_register_chain_vaa 3 0x${terraTokenBridge} --guardian_secret ${guardiansPrivateCSV})
  77. bscTokenBridgeVAA=$(npm --prefix clients/token_bridge run --silent main -- generate_register_chain_vaa 4 0x${bscTokenBridge} --guardian_secret ${guardiansPrivateCSV})
  78. algoTokenBridgeVAA=$(npm --prefix clients/token_bridge run --silent main -- generate_register_chain_vaa 8 0x${algoTokenBridge} --guardian_secret ${guardiansPrivateCSV})
  79. # 5) create nft bridge registration VAAs
  80. # fetch dependencies for the clients/nft_bridge script that generates nft bridge registration VAAs
  81. if [[ ! -d ./clients/nft_bridge/node_modules ]]; then
  82. echo "going to install node modules in clients/nft_bridge"
  83. npm ci --prefix clients/nft_bridge && npm run build --prefix clients/nft_bridge
  84. fi
  85. echo "generating contract registration VAAs for nft bridges"
  86. solNFTBridgeVAA=$(npm --prefix clients/nft_bridge run --silent main -- generate_register_chain_vaa 1 0x${solNFTBridge} --guardian_secret ${guardiansPrivateCSV})
  87. ethNFTBridgeVAA=$(npm --prefix clients/nft_bridge run --silent main -- generate_register_chain_vaa 2 0x${ethNFTBridge} --guardian_secret ${guardiansPrivateCSV})
  88. terraNFTBridgeVAA=$(npm --prefix clients/nft_bridge run --silent main -- generate_register_chain_vaa 3 0x${terraNFTBridge} --guardian_secret ${guardiansPrivateCSV})
  89. # 6) write the registration VAAs to env files
  90. echo "writing VAAs to .env files"
  91. # define the keys that will hold the chain registration governance VAAs
  92. solTokenBridge="REGISTER_SOL_TOKEN_BRIDGE_VAA"
  93. ethTokenBridge="REGISTER_ETH_TOKEN_BRIDGE_VAA"
  94. terraTokenBridge="REGISTER_TERRA_TOKEN_BRIDGE_VAA"
  95. bscTokenBridge="REGISTER_BSC_TOKEN_BRIDGE_VAA"
  96. algoTokenBridge="REGISTER_ALGO_TOKEN_BRIDGE_VAA"
  97. solNFTBridge="REGISTER_SOL_NFT_BRIDGE_VAA"
  98. ethNFTBridge="REGISTER_ETH_NFT_BRIDGE_VAA"
  99. terraNFTBridge="REGISTER_TERRA_NFT_BRIDGE_VAA"
  100. # solana token bridge
  101. upsert_env_file $ethFile $solTokenBridge $solTokenBridgeVAA
  102. upsert_env_file $envFile $solTokenBridge $solTokenBridgeVAA
  103. # solana nft bridge
  104. upsert_env_file $ethFile $solNFTBridge $solNFTBridgeVAA
  105. upsert_env_file $envFile $solNFTBridge $solNFTBridgeVAA
  106. # ethereum token bridge
  107. upsert_env_file $ethFile $ethTokenBridge $ethTokenBridgeVAA
  108. upsert_env_file $envFile $ethTokenBridge $ethTokenBridgeVAA
  109. # ethereum nft bridge
  110. upsert_env_file $ethFile $ethNFTBridge $ethNFTBridgeVAA
  111. upsert_env_file $envFile $ethNFTBridge $ethNFTBridgeVAA
  112. # terra token bridge
  113. upsert_env_file $ethFile $terraTokenBridge $terraTokenBridgeVAA
  114. upsert_env_file $envFile $terraTokenBridge $terraTokenBridgeVAA
  115. # terra nft bridge
  116. upsert_env_file $ethFile $terraNFTBridge $terraNFTBridgeVAA
  117. upsert_env_file $envFile $terraNFTBridge $terraNFTBridgeVAA
  118. # bsc token bridge
  119. upsert_env_file $ethFile $bscTokenBridge $bscTokenBridgeVAA
  120. upsert_env_file $envFile $bscTokenBridge $bscTokenBridgeVAA
  121. # algo token bridge
  122. upsert_env_file $ethFile $algoTokenBridge $algoTokenBridgeVAA
  123. upsert_env_file $envFile $algoTokenBridge $algoTokenBridgeVAA
  124. # 7) copy the local .env file to the solana & terra dirs, if the script is running on the host machine
  125. # chain dirs will not exist if running in docker for Tilt, only if running locally. check before copying.
  126. # copy ethFile to ethereum
  127. if [[ -d ./ethereum ]]; then
  128. echo "copying $ethFile to /etherum/.env"
  129. cp $ethFile ./ethereum/.env
  130. fi
  131. # copy the hex envFile to each of the non-EVM chains
  132. for envDest in ./solana/.env ./terra/tools/.env ./algorand/.env; do
  133. dirname=$(dirname $envDest)
  134. if [[ -d "$dirname" ]]; then
  135. echo "copying $envFile to $envDest"
  136. cp $envFile $envDest
  137. fi
  138. done
  139. echo "guardian set init complete!"