guardian-set-init.sh 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. #!/usr/bin/env bash
  2. # This script allows devnet initialization 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. if [[ "$OSTYPE" == "darwin"* ]]; then
  22. # on macOS's sed, the -i flag needs the '' argument to not create
  23. # backup files
  24. sed -i '' -e "/^$key=/s/=.*/=$new_value/" $file
  25. else
  26. sed -i -e "/^$key=/s/=.*/=$new_value/" $file
  27. fi
  28. else
  29. # file does not have the key, add it:
  30. echo "$key=$new_value" >> $file
  31. fi
  32. }
  33. echo "# This file was auto-generated by $(basename $0). Do not modify by hand!" >> $ethFile
  34. echo "# This file was auto-generated by $(basename $0). Do not modify by hand!" >> $envFile
  35. # assert jq exists before trying to use it
  36. if ! type -p jq; then
  37. echo "ERROR: jq is not installed"! >&2
  38. exit 1
  39. fi
  40. # 1) guardian public keys - used as the initial guardian set when initializing contracts.
  41. echo "generating guardian set addresses"
  42. # create an array of strings containing the ECDSA public keys of the devnet guardians in the guardianset:
  43. # guardiansPublicEth has the leading "0x" that Eth scripts expect.
  44. guardiansPublicEth=$(jq -c --argjson lastIndex $numGuardians '.devnetGuardians[:$lastIndex] | [.[].public]' $addressesJson)
  45. # guardiansPublicHex does not have a leading "0x", just hex strings.
  46. guardiansPublicHex=$(jq -c --argjson lastIndex $numGuardians '.devnetGuardians[:$lastIndex] | [.[].public[2:]]' $addressesJson)
  47. # also make a CSV string of the hex addresses, so the client scripts that need that format don't have to.
  48. guardiansPublicHexCSV=$(echo ${guardiansPublicHex} | jq --raw-output -c '. | join(",")')
  49. # write the lists of addresses to the env files
  50. initSigners="INIT_SIGNERS"
  51. upsert_env_file $ethFile $initSigners $guardiansPublicEth
  52. upsert_env_file $envFile $initSigners $guardiansPublicHex
  53. upsert_env_file $envFile "INIT_SIGNERS_CSV" $guardiansPublicHexCSV
  54. # 2) guardian private keys - used for generating the initial governance VAAs (register token bridge & nft bridge contracts on each chain).
  55. echo "generating guardian set keys"
  56. # create an array of strings containing the private keys of the devnet guardians in the guardianset
  57. guardiansPrivate=$(jq -c --argjson lastIndex $numGuardians '.devnetGuardians[:$lastIndex] | [.[].private]' $addressesJson)
  58. # create a CSV string with the private keys of the guardians in the guardianset, that will be used to create registration VAAs
  59. guardiansPrivateCSV=$(echo ${guardiansPrivate} | jq --raw-output -c '. | join(",")')
  60. # write the lists of keys to the env files
  61. upsert_env_file $ethFile "INIT_SIGNERS_KEYS_JSON" $guardiansPrivate
  62. upsert_env_file $envFile "INIT_SIGNERS_KEYS_CSV" $guardiansPrivateCSV
  63. # 3) fetch and store the contract addresses that we need to make contract registration governance VAAs for:
  64. echo "getting contract addresses for chain registrations from $addressesJson"
  65. # get addresses from the constants file
  66. solTokenBridge=$(jq --raw-output '.chains."1".contracts.tokenBridgeEmitterAddress' $addressesJson)
  67. ethTokenBridge=$(jq --raw-output '.chains."2".contracts.tokenBridgeEmitterAddress' $addressesJson)
  68. terraTokenBridge=$(jq --raw-output '.chains."3".contracts.tokenBridgeEmitterAddress' $addressesJson)
  69. bscTokenBridge=$(jq --raw-output '.chains."4".contracts.tokenBridgeEmitterAddress' $addressesJson)
  70. algoTokenBridge=$(jq --raw-output '.chains."8".contracts.tokenBridgeEmitterAddress' $addressesJson)
  71. nearTokenBridge=$(jq --raw-output '.chains."15".contracts.tokenBridgeEmitterAddress' $addressesJson)
  72. terra2TokenBridge=$(jq --raw-output '.chains."18".contracts.tokenBridgeEmitterAddress' $addressesJson)
  73. suiTokenBridge=$(jq --raw-output '.chains."21".contracts.tokenBridgeEmitterAddress' $addressesJson)
  74. aptosTokenBridge=$(jq --raw-output '.chains."22".contracts.tokenBridgeEmitterAddress' $addressesJson)
  75. wormchainTokenBridge=$(jq --raw-output '.chains."3104".contracts.tokenBridgeEmitterAddress' $addressesJson)
  76. solNFTBridge=$(jq --raw-output '.chains."1".contracts.nftBridgeEmitterAddress' $addressesJson)
  77. ethNFTBridge=$(jq --raw-output '.chains."2".contracts.nftBridgeEmitterAddress' $addressesJson)
  78. nearNFTBridge=$(jq --raw-output '.chains."15".contracts.nftBridgeEmitterAddress' $addressesJson)
  79. aptosNFTBridge=$(jq --raw-output '.chains."22".contracts.nftBridgeEmitterAddress' $addressesJson)
  80. # 4) create token bridge registration VAAs
  81. # invoke CLI commands to create registration VAAs
  82. solTokenBridgeVAA=$(worm generate registration -m TokenBridge -c solana -a ${solTokenBridge} -g ${guardiansPrivateCSV})
  83. ethTokenBridgeVAA=$(worm generate registration -m TokenBridge -c ethereum -a ${ethTokenBridge} -g ${guardiansPrivateCSV})
  84. terraTokenBridgeVAA=$(worm generate registration -m TokenBridge -c terra -a ${terraTokenBridge} -g ${guardiansPrivateCSV})
  85. bscTokenBridgeVAA=$(worm generate registration -m TokenBridge -c bsc -a ${bscTokenBridge} -g ${guardiansPrivateCSV})
  86. algoTokenBridgeVAA=$(worm generate registration -m TokenBridge -c algorand -a ${algoTokenBridge} -g ${guardiansPrivateCSV})
  87. nearTokenBridgeVAA=$(worm generate registration -m TokenBridge -c near -a ${nearTokenBridge} -g ${guardiansPrivateCSV})
  88. terra2TokenBridgeVAA=$(worm generate registration -m TokenBridge -c terra2 -a ${terra2TokenBridge} -g ${guardiansPrivateCSV})
  89. suiTokenBridgeVAA=$(worm generate registration -m TokenBridge -c sui -a ${suiTokenBridge} -g ${guardiansPrivateCSV})
  90. aptosTokenBridgeVAA=$(worm generate registration -m TokenBridge -c aptos -a ${aptosTokenBridge} -g ${guardiansPrivateCSV})
  91. wormchainTokenBridgeVAA=$(worm generate registration -m TokenBridge -c wormchain -a ${wormchainTokenBridge} -g ${guardiansPrivateCSV})
  92. # 5) create nft bridge registration VAAs
  93. echo "generating contract registration VAAs for nft bridges"
  94. solNFTBridgeVAA=$(worm generate registration -m NFTBridge -c solana -a ${solNFTBridge} -g ${guardiansPrivateCSV})
  95. ethNFTBridgeVAA=$(worm generate registration -m NFTBridge -c ethereum -a ${ethNFTBridge} -g ${guardiansPrivateCSV})
  96. nearNFTBridgeVAA=$(worm generate registration -m NFTBridge -c near -a ${nearNFTBridge} -g ${guardiansPrivateCSV})
  97. aptosNFTBridgeVAA=$(worm generate registration -m NFTBridge -c aptos -a ${aptosNFTBridge} -g ${guardiansPrivateCSV})
  98. # 6) write the registration VAAs to env files
  99. echo "writing VAAs to .env files"
  100. # define the keys that will hold the chain registration governance VAAs
  101. solTokenBridge="REGISTER_SOL_TOKEN_BRIDGE_VAA"
  102. ethTokenBridge="REGISTER_ETH_TOKEN_BRIDGE_VAA"
  103. terraTokenBridge="REGISTER_TERRA_TOKEN_BRIDGE_VAA"
  104. bscTokenBridge="REGISTER_BSC_TOKEN_BRIDGE_VAA"
  105. algoTokenBridge="REGISTER_ALGO_TOKEN_BRIDGE_VAA"
  106. terra2TokenBridge="REGISTER_TERRA2_TOKEN_BRIDGE_VAA"
  107. nearTokenBridge="REGISTER_NEAR_TOKEN_BRIDGE_VAA"
  108. suiTokenBridge="REGISTER_SUI_TOKEN_BRIDGE_VAA"
  109. aptosTokenBridge="REGISTER_APTOS_TOKEN_BRIDGE_VAA"
  110. wormchainTokenBridge="REGISTER_WORMCHAIN_TOKEN_BRIDGE_VAA"
  111. solNFTBridge="REGISTER_SOL_NFT_BRIDGE_VAA"
  112. ethNFTBridge="REGISTER_ETH_NFT_BRIDGE_VAA"
  113. nearNFTBridge="REGISTER_NEAR_NFT_BRIDGE_VAA"
  114. aptosNFTBridge="REGISTER_APTOS_NFT_BRIDGE_VAA"
  115. # solana token bridge
  116. upsert_env_file $ethFile $solTokenBridge $solTokenBridgeVAA
  117. upsert_env_file $envFile $solTokenBridge $solTokenBridgeVAA
  118. # solana nft bridge
  119. upsert_env_file $ethFile $solNFTBridge $solNFTBridgeVAA
  120. upsert_env_file $envFile $solNFTBridge $solNFTBridgeVAA
  121. # ethereum token bridge
  122. upsert_env_file $ethFile $ethTokenBridge $ethTokenBridgeVAA
  123. upsert_env_file $envFile $ethTokenBridge $ethTokenBridgeVAA
  124. # ethereum nft bridge
  125. upsert_env_file $ethFile $ethNFTBridge $ethNFTBridgeVAA
  126. upsert_env_file $envFile $ethNFTBridge $ethNFTBridgeVAA
  127. # terra token bridge
  128. upsert_env_file $ethFile $terraTokenBridge $terraTokenBridgeVAA
  129. upsert_env_file $envFile $terraTokenBridge $terraTokenBridgeVAA
  130. # bsc token bridge
  131. upsert_env_file $ethFile $bscTokenBridge $bscTokenBridgeVAA
  132. upsert_env_file $envFile $bscTokenBridge $bscTokenBridgeVAA
  133. # algo token bridge
  134. upsert_env_file $ethFile $algoTokenBridge $algoTokenBridgeVAA
  135. upsert_env_file $envFile $algoTokenBridge $algoTokenBridgeVAA
  136. # terra2 token bridge
  137. upsert_env_file $ethFile $terra2TokenBridge $terra2TokenBridgeVAA
  138. upsert_env_file $envFile $terra2TokenBridge $terra2TokenBridgeVAA
  139. # near token bridge
  140. upsert_env_file $ethFile $nearTokenBridge $nearTokenBridgeVAA
  141. upsert_env_file $envFile $nearTokenBridge $nearTokenBridgeVAA
  142. # near nft bridge
  143. upsert_env_file $ethFile $nearNFTBridge $nearNFTBridgeVAA
  144. upsert_env_file $envFile $nearNFTBridge $nearNFTBridgeVAA
  145. # sui token bridge
  146. upsert_env_file $ethFile $suiTokenBridge $suiTokenBridgeVAA
  147. upsert_env_file $envFile $suiTokenBridge $suiTokenBridgeVAA
  148. # aptos token bridge
  149. upsert_env_file $ethFile $aptosTokenBridge $aptosTokenBridgeVAA
  150. upsert_env_file $envFile $aptosTokenBridge $aptosTokenBridgeVAA
  151. # aptos nft bridge
  152. upsert_env_file $ethFile $aptosNFTBridge $aptosNFTBridgeVAA
  153. upsert_env_file $envFile $aptosNFTBridge $aptosNFTBridgeVAA
  154. # wormchain token bridge
  155. upsert_env_file $ethFile $wormchainTokenBridge $wormchainTokenBridgeVAA
  156. upsert_env_file $envFile $wormchainTokenBridge $wormchainTokenBridgeVAA
  157. # 7) copy the local .env file to the solana & terra dirs, if the script is running on the host machine
  158. # chain dirs will not exist if running in docker for Tilt, only if running locally. check before copying.
  159. # copy ethFile to ethereum
  160. if [[ -d ./ethereum ]]; then
  161. echo "copying $ethFile to /ethereum/.env"
  162. cp $ethFile ./ethereum/.env
  163. fi
  164. # copy the hex envFile to each of the non-EVM chains
  165. paths=(
  166. ./algorand/.env
  167. ./near/.env
  168. ./solana/.env
  169. ./terra/tools/.env
  170. ./cosmwasm/deployment/terra2/tools/.env
  171. ./sui/.env
  172. ./aptos/.env
  173. ./wormchain/contracts/tools/.env
  174. )
  175. for envDest in "${paths[@]}"; do
  176. dirname=$(dirname $envDest)
  177. if [[ -d "$dirname" ]]; then
  178. echo "copying $envFile to $envDest"
  179. cp $envFile $envDest
  180. fi
  181. done
  182. echo "guardian set init complete!"