소스 검색

[contract-manager] Contract manager improvements (#1000)

* Use arrays instead of separate files per config

* Remove redundant endpoint on cosmwasm

* Add functions for upgrading the wormhole guardian sets

* Add wormhole contract management on evm and cosmwasm

* Add getter functions to check what sort of wormhole-deployment is used

* Reorganize contract manager package to be used via other packages

* Remove .env files per network and create a script that outputs the same file

* Use env variables in truffle config and output config in deployments

* Add executeUpdatePriceFeed to contract interface

* Add update pricefeed script

* Add saving functionality to store

* Save new contract configs automatically on Evm

* Make deploy script use the create-env.js internally

* Add utility function to get implementation address for Evm Proxy contracts

* Add shimmer testnet and replace evmos nunfunctional rpc

* New procedure for contract verification

* Update docs and remove duplicate configurations

* Remove shimmer configs

* Read default data source configs via contract manager

* Remove flattened contract before compiling/deploying
Mohammad Amin Khashkhashi Moghaddam 2 년 전
부모
커밋
272f3c1984
100개의 변경된 파일865개의 추가작업 그리고 608개의 파일을 삭제
  1. 7 2
      contract_manager/package.json
  2. 52 0
      contract_manager/scripts/update_pricefeed.ts
  3. 84 0
      contract_manager/src/base.ts
  4. 24 8
      contract_manager/src/chains.ts
  5. 62 34
      contract_manager/src/contracts/cosmwasm.ts
  6. 83 5
      contract_manager/src/contracts/evm.ts
  7. 5 0
      contract_manager/src/contracts/index.ts
  8. 4 0
      contract_manager/src/contracts/sui.ts
  9. 25 0
      contract_manager/src/contracts/wormhole.ts
  10. 30 0
      contract_manager/src/executor.ts
  11. 0 30
      contract_manager/src/governance.ts
  12. 5 0
      contract_manager/src/index.ts
  13. 73 62
      contract_manager/src/store.ts
  14. 0 10
      contract_manager/src/test.ts
  15. 0 5
      contract_manager/store/chains/AptosChain/aptos_mainnet.yaml
  16. 0 5
      contract_manager/store/chains/AptosChain/aptos_testnet.yaml
  17. 10 0
      contract_manager/store/chains/AptosChains.yaml
  18. 0 5
      contract_manager/store/chains/CosmWasmChain/injective.yaml
  19. 0 5
      contract_manager/store/chains/CosmWasmChain/injective_testnet.yaml
  20. 0 9
      contract_manager/store/chains/CosmWasmChain/juno_testnet.yaml
  21. 0 9
      contract_manager/store/chains/CosmWasmChain/neutron.yaml
  22. 0 9
      contract_manager/store/chains/CosmWasmChain/neutron_testnet_pion_1.yaml
  23. 0 9
      contract_manager/store/chains/CosmWasmChain/osmosis.yaml
  24. 0 9
      contract_manager/store/chains/CosmWasmChain/osmosis_testnet_5.yaml
  25. 0 9
      contract_manager/store/chains/CosmWasmChain/sei_pacific_1.yaml
  26. 0 9
      contract_manager/store/chains/CosmWasmChain/sei_testnet_atlantic_2.yaml
  27. 66 0
      contract_manager/store/chains/CosmWasmChains.yaml
  28. 0 6
      contract_manager/store/chains/EvmChain/arbitrum.yaml
  29. 0 6
      contract_manager/store/chains/EvmChain/arbitrum_testnet.yaml
  30. 0 6
      contract_manager/store/chains/EvmChain/aurora.yaml
  31. 0 6
      contract_manager/store/chains/EvmChain/aurora_testnet.yaml
  32. 0 6
      contract_manager/store/chains/EvmChain/avalanche.yaml
  33. 0 6
      contract_manager/store/chains/EvmChain/base.yaml
  34. 0 6
      contract_manager/store/chains/EvmChain/base_goerli.yaml
  35. 0 6
      contract_manager/store/chains/EvmChain/bnb.yaml
  36. 0 6
      contract_manager/store/chains/EvmChain/bnb_testnet.yaml
  37. 0 6
      contract_manager/store/chains/EvmChain/canto.yaml
  38. 0 6
      contract_manager/store/chains/EvmChain/canto_testnet.yaml
  39. 0 6
      contract_manager/store/chains/EvmChain/celo.yaml
  40. 0 6
      contract_manager/store/chains/EvmChain/celo_alfajores_testnet.yaml
  41. 0 6
      contract_manager/store/chains/EvmChain/chiado.yaml
  42. 0 6
      contract_manager/store/chains/EvmChain/conflux_espace.yaml
  43. 0 6
      contract_manager/store/chains/EvmChain/conflux_espace_testnet.yaml
  44. 0 6
      contract_manager/store/chains/EvmChain/cronos.yaml
  45. 0 6
      contract_manager/store/chains/EvmChain/cronos_testnet.yaml
  46. 0 6
      contract_manager/store/chains/EvmChain/eos.yaml
  47. 0 6
      contract_manager/store/chains/EvmChain/eos_testnet.yaml
  48. 0 6
      contract_manager/store/chains/EvmChain/ethereum.yaml
  49. 0 6
      contract_manager/store/chains/EvmChain/evmos.yaml
  50. 0 6
      contract_manager/store/chains/EvmChain/evmos_testnet.yaml
  51. 0 6
      contract_manager/store/chains/EvmChain/fantom.yaml
  52. 0 6
      contract_manager/store/chains/EvmChain/fantom_testnet.yaml
  53. 0 6
      contract_manager/store/chains/EvmChain/fuji.yaml
  54. 0 6
      contract_manager/store/chains/EvmChain/gnosis.yaml
  55. 0 6
      contract_manager/store/chains/EvmChain/goerli.yaml
  56. 0 6
      contract_manager/store/chains/EvmChain/kava.yaml
  57. 0 6
      contract_manager/store/chains/EvmChain/kava_testnet.yaml
  58. 0 6
      contract_manager/store/chains/EvmChain/kcc.yaml
  59. 0 6
      contract_manager/store/chains/EvmChain/kcc_testnet.yaml
  60. 0 6
      contract_manager/store/chains/EvmChain/linea.yaml
  61. 0 6
      contract_manager/store/chains/EvmChain/linea_goerli.yaml
  62. 0 6
      contract_manager/store/chains/EvmChain/mantle.yaml
  63. 0 6
      contract_manager/store/chains/EvmChain/mantle_testnet.yaml
  64. 0 6
      contract_manager/store/chains/EvmChain/meter.yaml
  65. 0 6
      contract_manager/store/chains/EvmChain/meter_testnet.yaml
  66. 0 6
      contract_manager/store/chains/EvmChain/mumbai.yaml
  67. 0 6
      contract_manager/store/chains/EvmChain/neon.yaml
  68. 0 6
      contract_manager/store/chains/EvmChain/neon_devnet.yaml
  69. 0 6
      contract_manager/store/chains/EvmChain/optimism.yaml
  70. 0 6
      contract_manager/store/chains/EvmChain/optimism_goerli.yaml
  71. 0 6
      contract_manager/store/chains/EvmChain/polygon.yaml
  72. 0 6
      contract_manager/store/chains/EvmChain/polygon_zkevm.yaml
  73. 0 6
      contract_manager/store/chains/EvmChain/polygon_zkevm_testnet.yaml
  74. 0 6
      contract_manager/store/chains/EvmChain/shimmer_testnet.yaml
  75. 0 6
      contract_manager/store/chains/EvmChain/syndr_nitro_testnet.yaml
  76. 0 6
      contract_manager/store/chains/EvmChain/wemix.yaml
  77. 0 6
      contract_manager/store/chains/EvmChain/wemix_testnet.yaml
  78. 0 6
      contract_manager/store/chains/EvmChain/zksync.yaml
  79. 0 6
      contract_manager/store/chains/EvmChain/zksync_goerli.yaml
  80. 312 0
      contract_manager/store/chains/EvmChains.yaml
  81. 0 5
      contract_manager/store/chains/SuiChain/sui_devnet.yaml
  82. 0 5
      contract_manager/store/chains/SuiChain/sui_mainnet.yaml
  83. 0 5
      contract_manager/store/chains/SuiChain/sui_testnet.yaml
  84. 15 0
      contract_manager/store/chains/SuiChains.yaml
  85. 0 4
      contract_manager/store/contracts/AptosContract/aptos_mainnet_0xbd6d205f2aa288baa71270e66716d3d1bafe173ab9f312de4e9dd761ddef5409.yaml
  86. 0 4
      contract_manager/store/contracts/AptosContract/aptos_testnet_0xbd6d205f2aa288baa71270e66716d3d1bafe173ab9f312de4e9dd761ddef5409.yaml
  87. 8 0
      contract_manager/store/contracts/AptosContracts.yaml
  88. 0 3
      contract_manager/store/contracts/CosmWasmContract/injective_inj12j43nf2f0qumnt2zrrmpvnsqgzndxefujlvr08.yaml
  89. 0 3
      contract_manager/store/contracts/CosmWasmContract/injective_testnet_inj18hckkzqf47mdhd734g6papk6wj20y24rm43sk9.yaml
  90. 0 3
      contract_manager/store/contracts/CosmWasmContract/injective_testnet_inj18rlflp3735h25jmjx97d22c72sxk260amdjxlu.yaml
  91. 0 3
      contract_manager/store/contracts/CosmWasmContract/juno_testnet_juno1eacsrua27njc35pxz37y97gmcjs899t59f8pf0rkejjyvtmhws5q6lxsdd.yaml
  92. 0 3
      contract_manager/store/contracts/CosmWasmContract/juno_testnet_juno1h93q9kwlnfml2gum4zj54al9w4jdmuhtzrh6vhycnemsqlqv9l9snnznxs.yaml
  93. 0 3
      contract_manager/store/contracts/CosmWasmContract/neutron_neutron1m2emc93m9gpwgsrsf2vylv9xvgqh654630v7dfrhrkmr5slly53spg85wv.yaml
  94. 0 3
      contract_manager/store/contracts/CosmWasmContract/neutron_testnet_pion_1_neutron15ldst8t80982akgr8w8ekcytejzkmfpgdkeq4xgtge48qs7435jqp87u3t.yaml
  95. 0 3
      contract_manager/store/contracts/CosmWasmContract/neutron_testnet_pion_1_neutron16zwrmx3zgggmxhzau86xfycm42cr4sj888hdvzsxya3qarp6zhhqzhlkvz.yaml
  96. 0 3
      contract_manager/store/contracts/CosmWasmContract/osmosis_osmo1hpdzqku55lmfmptpyj6wdlugqs5etr6teqf7r4yqjjrxjznjhtuqqu5kdh.yaml
  97. 0 3
      contract_manager/store/contracts/CosmWasmContract/osmosis_testnet_5_osmo1hpdzqku55lmfmptpyj6wdlugqs5etr6teqf7r4yqjjrxjznjhtuqqu5kdh.yaml
  98. 0 3
      contract_manager/store/contracts/CosmWasmContract/osmosis_testnet_5_osmo1lltupx02sj99suakmuk4sr4ppqf34ajedaxut3ukjwkv6469erwqtpg9t3.yaml
  99. 0 3
      contract_manager/store/contracts/CosmWasmContract/sei_pacific_1_sei15d2tyq2jzxmpg32y3am3w62dts32qgzmds9qnr6c87r0gwwr7ynqal0x38.yaml
  100. 0 3
      contract_manager/store/contracts/CosmWasmContract/sei_testnet_atlantic_2_sei1kpntez76v38yuxhhaaahdmvjxnr5tkr8tq077smefs7uw70rj5yqw2aewy.yaml

+ 7 - 2
contract_manager/package.json

@@ -1,10 +1,15 @@
 {
-  "name": "@pythnetwork/pyth-contract-manager",
+  "name": "contract_manager",
   "version": "1.0.0",
   "description": "Set of tools to manage pyth contracts",
   "private": true,
-  "main": "index.js",
+  "main": "lib/index.js",
+  "types": "lib/index.d.ts",
+  "files": [
+    "lib/**/*"
+  ],
   "scripts": {
+    "build": "tsc",
     "shell": "ts-node ./src/shell.ts"
   },
   "author": "",

+ 52 - 0
contract_manager/scripts/update_pricefeed.ts

@@ -0,0 +1,52 @@
+import yargs from "yargs";
+import { hideBin } from "yargs/helpers";
+import { DefaultStore } from "../src";
+import { PriceServiceConnection } from "@pythnetwork/price-service-client";
+
+const parser = yargs(hideBin(process.argv))
+  .scriptName("update_pricefeed.ts")
+  .usage(
+    "Usage: $0 --contract <contract_id> --feed-id <feed-id> --private-key <private-key>"
+  )
+  .options({
+    contract: {
+      type: "string",
+      demandOption: true,
+      desc: "Contract to update price feeds for (e.g mumbai_0xff1a0f4744e8582DF1aE09D5611b887B6a12925C)",
+    },
+    "feed-id": {
+      type: "array",
+      demandOption: true,
+      desc: "Price feed ids to update without the leading 0x (e.g f9c0172ba10dfa4d19088d94f5bf61d3b54d5bd7483a322a982e1373ee8ea31b). Can be provided multiple times for multiple feed updates",
+    },
+    "private-key": {
+      type: "string",
+      demandOption: true,
+      desc: "Private key to use to sign transaction",
+    },
+    endpoint: {
+      type: "string",
+      desc: "Price service endpoint to use, defaults to https://xc-mainnet.pyth.network for mainnet and https://xc-testnet.pyth.network for testnet",
+    },
+  });
+
+async function main() {
+  const argv = await parser.argv;
+  const contract = DefaultStore.contracts[argv.contract];
+  if (!contract) {
+    throw new Error(`Contract ${argv.contract} not found`);
+  }
+  const defaultEndpoint = contract.getChain().isMainnet()
+    ? "https://xc-mainnet.pyth.network"
+    : "https://xc-testnet.pyth.network";
+  const priceService = new PriceServiceConnection(
+    argv.endpoint || defaultEndpoint
+  );
+  const vaas = await priceService.getLatestVaas(argv["feed-id"] as string[]);
+  await contract.executeUpdatePriceFeed(
+    argv["private-key"],
+    vaas.map((vaa) => Buffer.from(vaa, "base64"))
+  );
+}
+
+main();

+ 84 - 0
contract_manager/src/base.ts

@@ -69,6 +69,16 @@ export abstract class Contract extends Storable {
    */
   abstract getPriceFeed(feedId: string): Promise<PriceFeed | undefined>;
 
+  /**
+   * Executes the update instructions contained in the VAAs using the sender credentials
+   * @param senderPrivateKey private key of the sender in hex format without 0x prefix
+   * @param vaas an array of VAAs containing price update messages to execute
+   */
+  abstract executeUpdatePriceFeed(
+    senderPrivateKey: string,
+    vaas: Buffer[]
+  ): Promise<any>;
+
   /**
    * Executes the governance instruction contained in the VAA using the sender credentials
    * @param senderPrivateKey private key of the sender in hex format without 0x prefix
@@ -84,3 +94,77 @@ export abstract class Contract extends Storable {
    */
   abstract getGovernanceDataSource(): Promise<DataSource>;
 }
+
+export function getDefaultDeploymentConfig(deploymentType: "stable" | "edge"): {
+  dataSources: DataSource[];
+  governanceDataSource: DataSource;
+  wormholeConfig: {
+    governanceChainId: Number;
+    governanceContract: string; // 32 byte address in 64 char hex format
+    initialGuardianSet: string[]; // 20 byte addresses in 40 char hex format
+  };
+} {
+  if (deploymentType === "stable")
+    return {
+      dataSources: [
+        {
+          emitterChain: 1,
+          emitterAddress:
+            "6bb14509a612f01fbbc4cffeebd4bbfb492a86df717ebe92eb6df432a3f00a25",
+        },
+        {
+          emitterChain: 26,
+          emitterAddress:
+            "f8cd23c2ab91237730770bbea08d61005cdda0984348f3f6eecb559638c0bba0",
+        },
+        {
+          emitterChain: 26,
+          emitterAddress:
+            "e101faedac5851e32b9b23b5f9411a8c2bac4aae3ed4dd7b811dd1a72ea4aa71",
+        },
+      ],
+      governanceDataSource: {
+        emitterChain: 1,
+        emitterAddress:
+          "5635979a221c34931e32620b9293a463065555ea71fe97cd6237ade875b12e9e",
+      },
+      wormholeConfig: {
+        governanceChainId: 1,
+        governanceContract:
+          "0000000000000000000000000000000000000000000000000000000000000004",
+        initialGuardianSet: ["58cc3ae5c097b213ce3c81979e1b9f9570746aa5"],
+      },
+    };
+  else if (deploymentType === "edge")
+    return {
+      dataSources: [
+        {
+          emitterChain: 1,
+          emitterAddress:
+            "f346195ac02f37d60d4db8ffa6ef74cb1be3550047543a4a9ee9acf4d78697b0",
+        },
+        {
+          emitterChain: 26,
+          emitterAddress:
+            "a27839d641b07743c0cb5f68c51f8cd31d2c0762bec00dc6fcd25433ef1ab5b6",
+        },
+        {
+          emitterChain: 26,
+          emitterAddress:
+            "e101faedac5851e32b9b23b5f9411a8c2bac4aae3ed4dd7b811dd1a72ea4aa71",
+        },
+      ],
+      governanceDataSource: {
+        emitterChain: 1,
+        emitterAddress:
+          "63278d271099bfd491951b3e648f08b1c71631e4a53674ad43e8f9f98068c385",
+      },
+      wormholeConfig: {
+        governanceChainId: 1,
+        governanceContract:
+          "0000000000000000000000000000000000000000000000000000000000000004",
+        initialGuardianSet: ["13947bd48b18e53fdaeee77f3473391ac727c638"],
+      },
+    };
+  else throw new Error(`Invalid deployment type ${deploymentType}`);
+}

+ 24 - 8
contract_manager/src/chains.ts

@@ -14,7 +14,12 @@ import {
 } from "xc_admin_common";
 import { AptosClient } from "aptos";
 import Web3 from "web3";
-import { CosmwasmQuerier } from "@pythnetwork/cosmwasm-deploy-tools";
+import {
+  CosmwasmExecutor,
+  CosmwasmQuerier,
+  InjectiveExecutor,
+} from "@pythnetwork/cosmwasm-deploy-tools";
+import { Network } from "@injectivelabs/networks";
 
 export abstract class Chain extends Storable {
   public wormholeChainName: ChainName;
@@ -119,8 +124,7 @@ export class CosmWasmChain extends Chain {
     id: string,
     mainnet: boolean,
     wormholeChainName: string,
-    public querierEndpoint: string,
-    public executorEndpoint: string,
+    public endpoint: string,
     public gasPrice: string,
     public prefix: string,
     public feeDenom: string
@@ -134,8 +138,7 @@ export class CosmWasmChain extends Chain {
       parsed.id,
       parsed.mainnet,
       parsed.wormholeChainName,
-      parsed.querierEndpoint,
-      parsed.executorEndpoint,
+      parsed.endpoint,
       parsed.gasPrice,
       parsed.prefix,
       parsed.feeDenom
@@ -144,8 +147,7 @@ export class CosmWasmChain extends Chain {
 
   toJson(): any {
     return {
-      querierEndpoint: this.querierEndpoint,
-      executorEndpoint: this.executorEndpoint,
+      endpoint: this.endpoint,
       id: this.id,
       wormholeChainName: this.wormholeChainName,
       mainnet: this.mainnet,
@@ -161,13 +163,27 @@ export class CosmWasmChain extends Chain {
   }
 
   async getCode(codeId: number): Promise<Buffer> {
-    const chainQuerier = await CosmwasmQuerier.connect(this.querierEndpoint);
+    const chainQuerier = await CosmwasmQuerier.connect(this.endpoint);
     return await chainQuerier.getCode({ codeId });
   }
 
   generateGovernanceUpgradePayload(codeId: bigint): Buffer {
     return new CosmosUpgradeContract(this.wormholeChainName, codeId).encode();
   }
+
+  async getExecutor(privateKey: string) {
+    if (this.getId().indexOf("injective") > -1) {
+      return InjectiveExecutor.fromPrivateKey(
+        this.isMainnet() ? Network.Mainnet : Network.Testnet,
+        privateKey
+      );
+    }
+    return new CosmwasmExecutor(
+      this.endpoint,
+      await CosmwasmExecutor.getSignerFromPrivateKey(privateKey, this.prefix),
+      this.gasPrice + this.feeDenom
+    );
+  }
 }
 
 export class SuiChain extends Chain {

+ 62 - 34
contract_manager/src/contracts/cosmwasm.ts

@@ -2,19 +2,17 @@ import { Chain, CosmWasmChain } from "../chains";
 import { readFileSync } from "fs";
 import {
   ContractInfoResponse,
-  CosmwasmExecutor,
   CosmwasmQuerier,
   DeploymentType,
   getPythConfig,
-  InjectiveExecutor,
   Price,
   PythWrapperExecutor,
   PythWrapperQuerier,
 } from "@pythnetwork/cosmwasm-deploy-tools";
 import { CHAINS, DataSource } from "xc_admin_common";
-import { Network } from "@injectivelabs/networks";
 import { CosmWasmClient } from "@cosmjs/cosmwasm-stargate";
 import { Contract } from "../base";
+import { WormholeContract } from "./wormhole";
 
 /**
  * Variables here need to be snake case to match the on-chain contract configs
@@ -37,6 +35,52 @@ namespace CosmWasmContract {
   }
 }
 
+export class WormholeCosmWasmContract extends WormholeContract {
+  constructor(public chain: CosmWasmChain, public address: string) {
+    super();
+  }
+
+  async getConfig() {
+    const chainQuerier = await CosmwasmQuerier.connect(this.chain.endpoint);
+    return (await chainQuerier.getAllContractState({
+      contractAddr: this.address,
+    })) as any;
+  }
+
+  async getCurrentGuardianSetIndex(): Promise<number> {
+    const config = await this.getConfig();
+    return JSON.parse(config["\x00\x06config"])["guardian_set_index"];
+  }
+
+  async getGuardianSet(): Promise<string[]> {
+    const config = await this.getConfig();
+    const guardianSetIndex = JSON.parse(config["\x00\x06config"])[
+      "guardian_set_index"
+    ];
+    let key = "\x00\fguardian_set";
+    //append guardianSetIndex as 4 bytes to key string
+    key += Buffer.from(guardianSetIndex.toString(16).padStart(8, "0"), "hex");
+
+    const guardianSet = JSON.parse(config[key])["addresses"];
+    return guardianSet.map((entry: { bytes: string }) =>
+      Buffer.from(entry.bytes, "base64").toString("hex")
+    );
+  }
+
+  async upgradeGuardianSets(
+    senderPrivateKey: string,
+    vaa: Buffer
+  ): Promise<any> {
+    const executor = await this.chain.getExecutor(senderPrivateKey);
+    return executor.executeContract({
+      contractAddr: this.address,
+      msg: {
+        submit_v_a_a: { vaa: vaa.toString("base64") },
+      },
+    });
+  }
+}
+
 export class CosmWasmContract extends Contract {
   async getDataSources(): Promise<DataSource[]> {
     const config = await this.getConfig();
@@ -102,7 +146,7 @@ export class CosmWasmContract extends Contract {
     wasmPath: string
   ) {
     const contractBytes = readFileSync(wasmPath);
-    let executor = await this.getExecutor(chain, privateKey);
+    let executor = await chain.getExecutor(privateKey);
     return executor.storeCode({ contractBytes });
   }
 
@@ -119,7 +163,7 @@ export class CosmWasmContract extends Contract {
     config: CosmWasmContract.DeploymentConfig,
     privateKey: string
   ): Promise<CosmWasmContract> {
-    let executor = await this.getExecutor(chain, privateKey);
+    let executor = await chain.getExecutor(privateKey);
     let result = await executor.instantiateContract({
       codeId: codeId,
       instMsg: config,
@@ -154,20 +198,6 @@ export class CosmWasmContract extends Contract {
     return this.initialize(chain, codeId, config, privateKey);
   }
 
-  private static async getExecutor(chain: CosmWasmChain, privateKey: string) {
-    if (chain.getId().indexOf("injective") > -1) {
-      return InjectiveExecutor.fromPrivateKey(
-        chain.isMainnet() ? Network.Mainnet : Network.Testnet,
-        privateKey
-      );
-    }
-    return new CosmwasmExecutor(
-      chain.executorEndpoint,
-      await CosmwasmExecutor.getSignerFromPrivateKey(privateKey, chain.prefix),
-      chain.gasPrice + chain.feeDenom
-    );
-  }
-
   getId(): string {
     return `${this.chain.getId()}_${this.address}`;
   }
@@ -181,9 +211,7 @@ export class CosmWasmContract extends Contract {
   }
 
   async getQuerier(): Promise<PythWrapperQuerier> {
-    const chainQuerier = await CosmwasmQuerier.connect(
-      this.chain.querierEndpoint
-    );
+    const chainQuerier = await CosmwasmQuerier.connect(this.chain.endpoint);
     const pythQuerier = new PythWrapperQuerier(chainQuerier);
     return pythQuerier;
   }
@@ -194,16 +222,12 @@ export class CosmWasmContract extends Contract {
   }
 
   async getWasmContractInfo(): Promise<ContractInfoResponse> {
-    const chainQuerier = await CosmwasmQuerier.connect(
-      this.chain.querierEndpoint
-    );
+    const chainQuerier = await CosmwasmQuerier.connect(this.chain.endpoint);
     return chainQuerier.getContractInfo({ contractAddr: this.address });
   }
 
   async getConfig() {
-    const chainQuerier = await CosmwasmQuerier.connect(
-      this.chain.querierEndpoint
-    );
+    const chainQuerier = await CosmwasmQuerier.connect(this.chain.endpoint);
     let allStates = (await chainQuerier.getAllContractState({
       contractAddr: this.address,
     })) as any;
@@ -300,10 +324,7 @@ export class CosmWasmContract extends Contract {
   async executeUpdatePriceFeed(senderPrivateKey: string, vaas: Buffer[]) {
     const base64Vaas = vaas.map((v) => v.toString("base64"));
     const fund = await this.getUpdateFee(base64Vaas);
-    let executor = await CosmWasmContract.getExecutor(
-      this.chain,
-      senderPrivateKey
-    );
+    let executor = await this.chain.getExecutor(senderPrivateKey);
     let pythExecutor = new PythWrapperExecutor(executor);
     return pythExecutor.executeUpdatePriceFeeds({
       contractAddr: this.address,
@@ -313,7 +334,7 @@ export class CosmWasmContract extends Contract {
   }
 
   async executeGovernanceInstruction(privateKey: string, vaa: Buffer) {
-    let executor = await CosmWasmContract.getExecutor(this.chain, privateKey);
+    let executor = await this.chain.getExecutor(privateKey);
     let pythExecutor = new PythWrapperExecutor(executor);
     return pythExecutor.executeGovernanceInstruction({
       contractAddr: this.address,
@@ -321,6 +342,13 @@ export class CosmWasmContract extends Contract {
     });
   }
 
+  async getWormholeContract(): Promise<WormholeCosmWasmContract> {
+    let config = await this.getConfig();
+    const chainQuerier = await CosmwasmQuerier.connect(this.chain.endpoint);
+    const wormholeAddress = config.config_v1.wormhole_contract;
+    return new WormholeCosmWasmContract(this.chain, wormholeAddress);
+  }
+
   async getUpdateFee(msgs: string[]): Promise<any> {
     let querier = await this.getQuerier();
     return querier.getUpdateFee(this.address, msgs);
@@ -341,7 +369,7 @@ export class CosmWasmContract extends Contract {
   }
 
   async getValidTimePeriod() {
-    let client = await CosmWasmClient.connect(this.chain.querierEndpoint);
+    let client = await CosmWasmClient.connect(this.chain.endpoint);
     let result = await client.queryContractSmart(
       this.address,
       "get_valid_time_period"

+ 83 - 5
contract_manager/src/contracts/evm.ts

@@ -3,6 +3,7 @@ import PythInterfaceAbi from "@pythnetwork/pyth-sdk-solidity/abis/IPyth.json";
 import { Contract } from "../base";
 import { Chain, EvmChain } from "../chains";
 import { DataSource } from "xc_admin_common";
+import { WormholeContract } from "./wormhole";
 
 // Just to make sure tx gas limit is enough
 const GAS_ESTIMATE_MULTIPLIER = 2;
@@ -184,27 +185,94 @@ const WORMHOLE_ABI = [
     stateMutability: "view",
     type: "function",
   },
+  {
+    inputs: [
+      {
+        internalType: "bytes",
+        name: "_vm",
+        type: "bytes",
+      },
+    ],
+    name: "submitNewGuardianSet",
+    outputs: [],
+    stateMutability: "nonpayable",
+    type: "function",
+  },
+  {
+    inputs: [],
+    name: "messageFee",
+    outputs: [
+      {
+        internalType: "uint256",
+        name: "",
+        type: "uint256",
+      },
+    ],
+    stateMutability: "view",
+    type: "function",
+  },
 ] as any;
-export class WormholeEvmContract {
-  constructor(public chain: EvmChain, public address: string) {}
+export class WormholeEvmContract extends WormholeContract {
+  constructor(public chain: EvmChain, public address: string) {
+    super();
+  }
   getContract() {
     const web3 = new Web3(this.chain.getRpcUrl());
     return new web3.eth.Contract(WORMHOLE_ABI, this.address);
   }
 
+  async getCurrentGuardianSetIndex(): Promise<number> {
+    const wormholeContract = this.getContract();
+    return Number(
+      await wormholeContract.methods.getCurrentGuardianSetIndex().call()
+    );
+  }
+
   /**
    * Returns an array of guardian addresses used for VAA verification in this contract
    */
   async getGuardianSet(): Promise<string[]> {
     const wormholeContract = this.getContract();
-    const currentIndex = await wormholeContract.methods
-      .getCurrentGuardianSetIndex()
-      .call();
+    const currentIndex = await this.getCurrentGuardianSetIndex();
     const [currentSet] = await wormholeContract.methods
       .getGuardianSet(currentIndex)
       .call();
     return currentSet;
   }
+
+  /**
+   * Checks whether this contract is a deployment of wormhole-receiver or wormhole.
+   * The wormhole-receiver is a subset of the wormhole contract optimized for just verifying the VAAs.
+   * The check is done by calling a function that only exists in the wormhole contract and not in the wormhole-receiver.
+   * If the function call fails, we know that this is a wormhole-receiver contract.
+   */
+  async isWormholeReceiver(): Promise<boolean> {
+    const wormholeContract = this.getContract();
+    try {
+      await wormholeContract.methods.messageFee().call();
+      return false;
+    } catch (e) {
+      return true;
+    }
+  }
+
+  async upgradeGuardianSets(senderPrivateKey: string, vaa: Buffer) {
+    const web3 = new Web3(this.chain.getRpcUrl());
+    const { address } = web3.eth.accounts.wallet.add(senderPrivateKey);
+    const wormholeContract = new web3.eth.Contract(WORMHOLE_ABI, this.address);
+    const transactionObject = wormholeContract.methods.submitNewGuardianSet(
+      "0x" + vaa.toString("hex")
+    );
+    const gasEstiamte = await transactionObject.estimateGas({
+      from: address,
+      gas: 100000000,
+    });
+    return transactionObject.send({
+      from: address,
+      gas: gasEstiamte * GAS_ESTIMATE_MULTIPLIER,
+      gasPrice: await this.chain.getGasPrice(),
+    });
+  }
 }
 
 export class EvmContract extends Contract {
@@ -283,6 +351,16 @@ export class EvmContract extends Contract {
     return web3.eth.getCode(this.address);
   }
 
+  async getImplementationAddress(): Promise<string> {
+    const web3 = new Web3(this.chain.getRpcUrl());
+    // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1) according to EIP-1967
+    let storagePosition =
+      "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc";
+    let address = await web3.eth.getStorageAt(this.address, storagePosition);
+    address = "0x" + address.slice(26);
+    return address;
+  }
+
   /**
    * Returns the keccak256 digest of the contract bytecode after replacing any occurrences of the contract addr in
    * the bytecode with 0.The bytecode stores the deployment address as an immutable variable.

+ 5 - 0
contract_manager/src/contracts/index.ts

@@ -0,0 +1,5 @@
+export * from "./aptos";
+export * from "./cosmwasm";
+export * from "./evm";
+export * from "./sui";
+export * from "./wormhole";

+ 4 - 0
contract_manager/src/contracts/sui.ts

@@ -195,6 +195,10 @@ export class SuiContract extends Contract {
     return this.executeTransaction(tx, keypair);
   }
 
+  async executeUpdatePriceFeed(senderPrivateKey: string, vaas: Buffer[]) {
+    throw new Error("Not implemented");
+  }
+
   async executeGovernanceInstruction(senderPrivateKey: string, vaa: Buffer) {
     const keypair = Ed25519Keypair.fromSecretKey(
       Buffer.from(senderPrivateKey, "hex")

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 25 - 0
contract_manager/src/contracts/wormhole.ts


+ 30 - 0
contract_manager/src/executor.ts

@@ -0,0 +1,30 @@
+import { parseVaa } from "@certusone/wormhole-sdk";
+import { decodeGovernancePayload } from "xc_admin_common";
+import { DefaultStore } from "./store";
+
+/**
+ * A general executor that tries to find any contract that can execute a given VAA and executes it
+ * @param senderPrivateKey the private key to execute the governance instruction with
+ * @param vaa the VAA to execute
+ */
+export async function executeVaa(senderPrivateKey: string, vaa: Buffer) {
+  const parsedVaa = parseVaa(vaa);
+  const action = decodeGovernancePayload(parsedVaa.payload);
+  if (!action) return; //TODO: handle other actions
+  for (const contract of Object.values(DefaultStore.contracts)) {
+    if (
+      action.targetChainId === "unset" ||
+      contract.getChain().wormholeChainName === action.targetChainId
+    ) {
+      const governanceSource = await contract.getGovernanceDataSource();
+      if (
+        governanceSource.emitterAddress ===
+          parsedVaa.emitterAddress.toString("hex") &&
+        governanceSource.emitterChain === parsedVaa.emitterChain
+      ) {
+        // TODO: check governance sequence number as well
+        await contract.executeGovernanceInstruction(senderPrivateKey, vaa);
+      }
+    }
+  }
+}

+ 0 - 30
contract_manager/src/governance.ts

@@ -20,7 +20,6 @@ import SquadsMesh from "@sqds/mesh";
 import { AnchorProvider, Wallet } from "@coral-xyz/anchor/dist/cjs/provider";
 import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet";
 import {
-  decodeGovernancePayload,
   executeProposal,
   MultisigVault,
   WORMHOLE_ADDRESS,
@@ -33,8 +32,6 @@ import {
   deriveWormholeBridgeDataKey,
 } from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole";
 import { Storable } from "./base";
-import { parseVaa } from "@certusone/wormhole-sdk";
-import { DefaultStore } from "./store";
 
 class InvalidTransactionError extends Error {
   constructor(message: string) {
@@ -127,33 +124,6 @@ export class SubmittedWormholeMessage {
   }
 }
 
-/**
- * A general executor that tries to find any contract that can execute a given VAA and executes it
- * @param senderPrivateKey the private key to execute the governance instruction with
- * @param vaa the VAA to execute
- */
-export async function executeVaa(senderPrivateKey: string, vaa: Buffer) {
-  const parsedVaa = parseVaa(vaa);
-  const action = decodeGovernancePayload(parsedVaa.payload);
-  if (!action) return; //TODO: handle other actions
-  for (const contract of Object.values(DefaultStore.contracts)) {
-    if (
-      action.targetChainId === "unset" ||
-      contract.getChain().wormholeChainName === action.targetChainId
-    ) {
-      const governanceSource = await contract.getGovernanceDataSource();
-      if (
-        governanceSource.emitterAddress ===
-          parsedVaa.emitterAddress.toString("hex") &&
-        governanceSource.emitterChain === parsedVaa.emitterChain
-      ) {
-        // TODO: check governance sequence number as well
-        await contract.executeGovernanceInstruction(senderPrivateKey, vaa);
-      }
-    }
-  }
-}
-
 function asPythCluster(cluster: string): PythCluster {
   const pythCluster = cluster as PythCluster;
   getPythClusterApiUrl(pythCluster); // throws if cluster is invalid

+ 5 - 0
contract_manager/src/index.ts

@@ -0,0 +1,5 @@
+export * from "./governance";
+export * from "./chains";
+export * from "./store";
+export * from "./base";
+export * from "./contracts";

+ 73 - 62
contract_manager/src/store.ts

@@ -6,23 +6,18 @@ import {
   GlobalChain,
   SuiChain,
 } from "./chains";
-import { CosmWasmContract } from "./contracts/cosmwasm";
-import { SuiContract } from "./contracts/sui";
+import {
+  AptosContract,
+  CosmWasmContract,
+  EvmContract,
+  SuiContract,
+} from "./contracts";
 import { Contract } from "./base";
 import { parse, stringify } from "yaml";
-import {
-  existsSync,
-  mkdirSync,
-  readdirSync,
-  readFileSync,
-  statSync,
-  writeFileSync,
-} from "fs";
-import { EvmContract } from "./contracts/evm";
-import { AptosContract } from "./contracts/aptos";
+import { readdirSync, readFileSync, statSync, writeFileSync } from "fs";
 import { Vault } from "./governance";
 
-class Store {
+export class Store {
   public chains: Record<string, Chain> = { global: new GlobalChain() };
   public contracts: Record<string, Contract> = {};
   public vaults: Record<string, Vault> = {};
@@ -33,30 +28,8 @@ class Store {
     this.loadAllVaults();
   }
 
-  save(obj: any) {
-    let dir, file, content;
-    if (obj instanceof Contract) {
-      let contract = obj;
-      dir = `${this.path}/contracts/${contract.getType()}`;
-      file = contract.getId();
-      content = contract.toJson();
-    } else if (obj instanceof Chain) {
-      let chain = obj;
-      dir = `${this.path}/chains/${chain.getType()}`;
-      file = chain.getId();
-      content = chain.toJson();
-    } else if (obj instanceof Vault) {
-      let vault = obj;
-      dir = `${this.path}/vaults`;
-      file = vault.getId();
-      content = vault.toJson();
-    } else {
-      throw new Error("Invalid type");
-    }
-    if (!existsSync(dir)) {
-      mkdirSync(dir, { recursive: true });
-    }
-    writeFileSync(`${dir}/${file}.yaml`, stringify(content));
+  static serialize(obj: Contract | Chain | Vault) {
+    return stringify([obj.toJson()]);
   }
 
   getYamlFiles(path: string) {
@@ -88,15 +61,49 @@ class Store {
     };
 
     this.getYamlFiles(`${this.path}/chains/`).forEach((yamlFile) => {
-      let parsed = parse(readFileSync(yamlFile, "utf-8"));
-      if (allChainClasses[parsed.type] === undefined) return;
-      let chain = allChainClasses[parsed.type].fromJson(parsed);
-      if (this.chains[chain.getId()])
-        throw new Error(`Multiple chains with id ${chain.getId()} found`);
-      this.chains[chain.getId()] = chain;
+      let parsedArray = parse(readFileSync(yamlFile, "utf-8"));
+      for (const parsed of parsedArray) {
+        if (allChainClasses[parsed.type] === undefined) return;
+        let chain = allChainClasses[parsed.type].fromJson(parsed);
+        if (this.chains[chain.getId()])
+          throw new Error(`Multiple chains with id ${chain.getId()} found`);
+        this.chains[chain.getId()] = chain;
+      }
     });
   }
 
+  saveAllContracts() {
+    let contractsByType: Record<string, Contract[]> = {};
+    for (const contract of Object.values(this.contracts)) {
+      if (!contractsByType[contract.getType()]) {
+        contractsByType[contract.getType()] = [];
+      }
+      contractsByType[contract.getType()].push(contract);
+    }
+    for (const [type, contracts] of Object.entries(contractsByType)) {
+      writeFileSync(
+        `${this.path}/contracts/${type}s.yaml`,
+        stringify(contracts.map((c) => c.toJson()))
+      );
+    }
+  }
+
+  saveAllChains() {
+    let chainsByType: Record<string, Chain[]> = {};
+    for (const chain of Object.values(this.chains)) {
+      if (!chainsByType[chain.getType()]) {
+        chainsByType[chain.getType()] = [];
+      }
+      chainsByType[chain.getType()].push(chain);
+    }
+    for (const [type, chains] of Object.entries(chainsByType)) {
+      writeFileSync(
+        `${this.path}/chains/${type}s.yaml`,
+        stringify(chains.map((c) => c.toJson()))
+      );
+    }
+  }
+
   loadAllContracts() {
     let allContractClasses = {
       [CosmWasmContract.type]: CosmWasmContract,
@@ -105,32 +112,36 @@ class Store {
       [AptosContract.type]: AptosContract,
     };
     this.getYamlFiles(`${this.path}/contracts/`).forEach((yamlFile) => {
-      let parsed = parse(readFileSync(yamlFile, "utf-8"));
-      if (allContractClasses[parsed.type] === undefined) return;
-      if (!this.chains[parsed.chain])
-        throw new Error(`Chain ${parsed.chain} not found`);
-      const chain = this.chains[parsed.chain];
-      let chainContract = allContractClasses[parsed.type].fromJson(
-        chain,
-        parsed
-      );
-      if (this.contracts[chainContract.getId()])
-        throw new Error(
-          `Multiple contracts with id ${chainContract.getId()} found`
+      let parsedArray = parse(readFileSync(yamlFile, "utf-8"));
+      for (const parsed of parsedArray) {
+        if (allContractClasses[parsed.type] === undefined) return;
+        if (!this.chains[parsed.chain])
+          throw new Error(`Chain ${parsed.chain} not found`);
+        const chain = this.chains[parsed.chain];
+        let chainContract = allContractClasses[parsed.type].fromJson(
+          chain,
+          parsed
         );
-      this.contracts[chainContract.getId()] = chainContract;
+        if (this.contracts[chainContract.getId()])
+          throw new Error(
+            `Multiple contracts with id ${chainContract.getId()} found`
+          );
+        this.contracts[chainContract.getId()] = chainContract;
+      }
     });
   }
 
   loadAllVaults() {
     this.getYamlFiles(`${this.path}/vaults/`).forEach((yamlFile) => {
-      let parsed = parse(readFileSync(yamlFile, "utf-8"));
-      if (parsed.type !== Vault.type) return;
+      let parsedArray = parse(readFileSync(yamlFile, "utf-8"));
+      for (const parsed of parsedArray) {
+        if (parsed.type !== Vault.type) return;
 
-      const vault = Vault.fromJson(parsed);
-      if (this.vaults[vault.getId()])
-        throw new Error(`Multiple vaults with id ${vault.getId()} found`);
-      this.vaults[vault.getId()] = vault;
+        const vault = Vault.fromJson(parsed);
+        if (this.vaults[vault.getId()])
+          throw new Error(`Multiple vaults with id ${vault.getId()} found`);
+        this.vaults[vault.getId()] = vault;
+      }
     });
   }
 }

+ 0 - 10
contract_manager/src/test.ts

@@ -1,10 +0,0 @@
-import { DefaultStore } from "./store";
-
-async function test() {
-  for (const contract of Object.values(DefaultStore.contracts)) {
-    console.log("Contract", contract.getId());
-    console.log(await contract.getGovernanceDataSource());
-  }
-}
-
-test();

+ 0 - 5
contract_manager/store/chains/AptosChain/aptos_mainnet.yaml

@@ -1,5 +0,0 @@
-id: aptos_mainnet
-wormholeChainName: aptos
-mainnet: true
-rpcUrl: https://fullnode.mainnet.aptoslabs.com/v1
-type: AptosChain

+ 0 - 5
contract_manager/store/chains/AptosChain/aptos_testnet.yaml

@@ -1,5 +0,0 @@
-id: aptos_testnet
-wormholeChainName: aptos
-mainnet: false
-rpcUrl: https://fullnode.testnet.aptoslabs.com/v1
-type: AptosChain

+ 10 - 0
contract_manager/store/chains/AptosChains.yaml

@@ -0,0 +1,10 @@
+- id: aptos_testnet
+  wormholeChainName: aptos
+  mainnet: false
+  rpcUrl: https://fullnode.testnet.aptoslabs.com/v1
+  type: AptosChain
+- id: aptos_mainnet
+  wormholeChainName: aptos
+  mainnet: true
+  rpcUrl: https://fullnode.mainnet.aptoslabs.com/v1
+  type: AptosChain

+ 0 - 5
contract_manager/store/chains/CosmWasmChain/injective.yaml

@@ -1,5 +0,0 @@
-querierEndpoint: https://injective-rpc.quickapi.com:443
-id: injective
-wormholeChainName: injective
-mainnet: true
-type: CosmWasmChain

+ 0 - 5
contract_manager/store/chains/CosmWasmChain/injective_testnet.yaml

@@ -1,5 +0,0 @@
-querierEndpoint: https://k8s.testnet.tm.injective.network:443
-id: injective_testnet
-wormholeChainName: injective_testnet
-mainnet: false
-type: CosmWasmChain

+ 0 - 9
contract_manager/store/chains/CosmWasmChain/juno_testnet.yaml

@@ -1,9 +0,0 @@
-querierEndpoint: https://rpc.uni.junonetwork.io/
-executorEndpoint: https://rpc.uni.junonetwork.io/
-id: juno_testnet
-wormholeChainName: juno_testnet
-mainnet: false
-gasPrice: "0.025"
-prefix: juno
-feeDenom: ujunox
-type: CosmWasmChain

+ 0 - 9
contract_manager/store/chains/CosmWasmChain/neutron.yaml

@@ -1,9 +0,0 @@
-querierEndpoint: https://rpc-kralum.neutron-1.neutron.org
-executorEndpoint: https://rpc-kralum.neutron-1.neutron.org
-id: neutron
-wormholeChainName: neutron
-mainnet: true
-gasPrice: "0.025"
-prefix: neutron
-feeDenom: untrn
-type: CosmWasmChain

+ 0 - 9
contract_manager/store/chains/CosmWasmChain/neutron_testnet_pion_1.yaml

@@ -1,9 +0,0 @@
-querierEndpoint: https://rpc-palvus.pion-1.ntrn.tech/
-executorEndpoint: https://rpc-palvus.pion-1.ntrn.tech/
-id: neutron_testnet_pion_1
-wormholeChainName: neutron_testnet_pion_1
-mainnet: false
-gasPrice: "0.05"
-prefix: neutron
-feeDenom: untrn
-type: CosmWasmChain

+ 0 - 9
contract_manager/store/chains/CosmWasmChain/osmosis.yaml

@@ -1,9 +0,0 @@
-querierEndpoint: https://rpc.osmosis.zone:443
-executorEndpoint: https://rpc.osmosis.zone:443
-id: osmosis
-wormholeChainName: osmosis
-mainnet: true
-gasPrice: "0.025"
-prefix: osmo
-feeDenom: uosmo
-type: CosmWasmChain

+ 0 - 9
contract_manager/store/chains/CosmWasmChain/osmosis_testnet_5.yaml

@@ -1,9 +0,0 @@
-querierEndpoint: https://rpc.osmotest5.osmosis.zone/
-executorEndpoint: https://rpc.osmotest5.osmosis.zone/
-id: osmosis_testnet_5
-wormholeChainName: osmosis_testnet_5
-mainnet: false
-gasPrice: "0.025"
-prefix: osmo
-feeDenom: uosmo
-type: CosmWasmChain

+ 0 - 9
contract_manager/store/chains/CosmWasmChain/sei_pacific_1.yaml

@@ -1,9 +0,0 @@
-querierEndpoint: https://sei-rpc.polkachu.com
-executorEndpoint: https://sei-rpc.polkachu.com
-id: sei_pacific_1
-wormholeChainName: sei_pacific_1
-mainnet: true
-gasPrice: "0.025"
-prefix: sei
-feeDenom: usei
-type: CosmWasmChain

+ 0 - 9
contract_manager/store/chains/CosmWasmChain/sei_testnet_atlantic_2.yaml

@@ -1,9 +0,0 @@
-querierEndpoint: https://rpc.atlantic-2.seinetwork.io/
-executorEndpoint: https://rpc.atlantic-2.seinetwork.io/
-id: sei_testnet_atlantic_2
-wormholeChainName: sei_testnet_atlantic_2
-mainnet: false
-gasPrice: "0.10"
-prefix: sei
-feeDenom: usei
-type: CosmWasmChain

+ 66 - 0
contract_manager/store/chains/CosmWasmChains.yaml

@@ -0,0 +1,66 @@
+- endpoint: https://injective-rpc.quickapi.com:443
+  id: injective
+  wormholeChainName: injective
+  mainnet: true
+  type: CosmWasmChain
+- endpoint: https://rpc.atlantic-2.seinetwork.io/
+  id: sei_testnet_atlantic_2
+  wormholeChainName: sei_testnet_atlantic_2
+  mainnet: false
+  gasPrice: "0.10"
+  prefix: sei
+  feeDenom: usei
+  type: CosmWasmChain
+- endpoint: https://rpc.osmosis.zone:443
+  id: osmosis
+  wormholeChainName: osmosis
+  mainnet: true
+  gasPrice: "0.025"
+  prefix: osmo
+  feeDenom: uosmo
+  type: CosmWasmChain
+- endpoint: https://k8s.testnet.tm.injective.network:443
+  id: injective_testnet
+  wormholeChainName: injective_testnet
+  mainnet: false
+  type: CosmWasmChain
+- endpoint: https://rpc-palvus.pion-1.ntrn.tech/
+  id: neutron_testnet_pion_1
+  wormholeChainName: neutron_testnet_pion_1
+  mainnet: false
+  gasPrice: "0.05"
+  prefix: neutron
+  feeDenom: untrn
+  type: CosmWasmChain
+- endpoint: https://rpc.osmotest5.osmosis.zone/
+  id: osmosis_testnet_5
+  wormholeChainName: osmosis_testnet_5
+  mainnet: false
+  gasPrice: "0.025"
+  prefix: osmo
+  feeDenom: uosmo
+  type: CosmWasmChain
+- endpoint: https://sei-rpc.polkachu.com
+  id: sei_pacific_1
+  wormholeChainName: sei_pacific_1
+  mainnet: true
+  gasPrice: "0.025"
+  prefix: sei
+  feeDenom: usei
+  type: CosmWasmChain
+- endpoint: https://rpc-kralum.neutron-1.neutron.org
+  id: neutron
+  wormholeChainName: neutron
+  mainnet: true
+  gasPrice: "0.025"
+  prefix: neutron
+  feeDenom: untrn
+  type: CosmWasmChain
+- endpoint: https://rpc.uni.junonetwork.io/
+  id: juno_testnet
+  wormholeChainName: juno_testnet
+  mainnet: false
+  gasPrice: "0.025"
+  prefix: juno
+  feeDenom: ujunox
+  type: CosmWasmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/arbitrum.yaml

@@ -1,6 +0,0 @@
-id: arbitrum
-wormholeChainName: arbitrum
-mainnet: true
-rpcUrl: https://arb1.arbitrum.io/rpc
-networkId: 42161
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/arbitrum_testnet.yaml

@@ -1,6 +0,0 @@
-id: arbitrum_testnet
-wormholeChainName: arbitrum
-mainnet: false
-rpcUrl: https://goerli-rollup.arbitrum.io/rpc
-networkId: 421613
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/aurora.yaml

@@ -1,6 +0,0 @@
-id: aurora
-wormholeChainName: aurora
-mainnet: true
-rpcUrl: https://mainnet.aurora.dev
-networkId: 1313161554
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/aurora_testnet.yaml

@@ -1,6 +0,0 @@
-id: aurora_testnet
-wormholeChainName: aurora
-mainnet: false
-rpcUrl: https://testnet.aurora.dev
-networkId: 1313161555
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/avalanche.yaml

@@ -1,6 +0,0 @@
-id: avalanche
-wormholeChainName: avalanche
-mainnet: true
-rpcUrl: https://api.avax.network/ext/bc/C/rpc
-networkId: 43114
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/base.yaml

@@ -1,6 +0,0 @@
-id: base
-wormholeChainName: base
-mainnet: true
-rpcUrl: https://developer-access-mainnet.base.org/
-networkId: 8453
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/base_goerli.yaml

@@ -1,6 +0,0 @@
-id: base_goerli
-wormholeChainName: base
-mainnet: false
-rpcUrl: https://goerli.base.org
-networkId: 84531
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/bnb.yaml

@@ -1,6 +0,0 @@
-id: bnb
-wormholeChainName: bsc
-mainnet: true
-rpcUrl: https://rpc.ankr.com/bsc
-networkId: 56
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/bnb_testnet.yaml

@@ -1,6 +0,0 @@
-id: bnb_testnet
-wormholeChainName: bsc
-mainnet: false
-rpcUrl: https://rpc.ankr.com/bsc_testnet_chapel
-networkId: 97
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/canto.yaml

@@ -1,6 +0,0 @@
-id: canto
-wormholeChainName: canto
-mainnet: true
-rpcUrl: https://canto.gravitychain.io
-networkId: 7700
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/canto_testnet.yaml

@@ -1,6 +0,0 @@
-id: canto_testnet
-wormholeChainName: canto
-mainnet: false
-rpcUrl: https://canto-testnet.plexnode.wtf
-networkId: 7701
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/celo.yaml

@@ -1,6 +0,0 @@
-id: celo
-wormholeChainName: celo
-mainnet: true
-rpcUrl: https://forno.celo.org
-networkId: 42220
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/celo_alfajores_testnet.yaml

@@ -1,6 +0,0 @@
-id: celo_alfajores_testnet
-wormholeChainName: celo
-mainnet: false
-rpcUrl: https://alfajores-forno.celo-testnet.org
-networkId: 44787
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/chiado.yaml

@@ -1,6 +0,0 @@
-id: chiado
-wormholeChainName: gnosis
-mainnet: false
-rpcUrl: https://rpc.chiadochain.net
-networkId: 10200
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/conflux_espace.yaml

@@ -1,6 +0,0 @@
-id: conflux_espace
-wormholeChainName: conflux_espace
-mainnet: true
-rpcUrl: https://evm.confluxrpc.org
-networkId: 1030
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/conflux_espace_testnet.yaml

@@ -1,6 +0,0 @@
-id: conflux_espace_testnet
-wormholeChainName: conflux_espace
-mainnet: false
-rpcUrl: https://evmtestnet.confluxrpc.com
-networkId: 71
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/cronos.yaml

@@ -1,6 +0,0 @@
-id: cronos
-wormholeChainName: cronos
-mainnet: true
-rpcUrl: https://cronosrpc-1.xstaking.sg
-networkId: 25
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/cronos_testnet.yaml

@@ -1,6 +0,0 @@
-id: cronos_testnet
-wormholeChainName: cronos
-mainnet: false
-rpcUrl: https://evm-t3.cronos.org
-networkId: 338
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/eos.yaml

@@ -1,6 +0,0 @@
-id: eos
-wormholeChainName: eos
-mainnet: true
-rpcUrl: https://api.evm.eosnetwork.com
-networkId: 17777
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/eos_testnet.yaml

@@ -1,6 +0,0 @@
-id: eos_testnet
-wormholeChainName: eos
-mainnet: false
-rpcUrl: https://api.testnet.evm.eosnetwork.com
-networkId: 15557
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/ethereum.yaml

@@ -1,6 +0,0 @@
-id: ethereum
-wormholeChainName: ethereum
-mainnet: true
-rpcUrl: https://eth.llamarpc.com
-networkId: 1
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/evmos.yaml

@@ -1,6 +0,0 @@
-id: evmos
-wormholeChainName: evmos
-mainnet: true
-rpcUrl: https://eth.bd.evmos.org:8545/
-networkId: 9001
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/evmos_testnet.yaml

@@ -1,6 +0,0 @@
-id: evmos_testnet
-wormholeChainName: evmos
-mainnet: false
-rpcUrl: https://eth.bd.evmos.dev:8545/
-networkId: 9000
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/fantom.yaml

@@ -1,6 +0,0 @@
-id: fantom
-wormholeChainName: fantom
-mainnet: true
-rpcUrl: https://rpc.ankr.com/fantom
-networkId: 250
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/fantom_testnet.yaml

@@ -1,6 +0,0 @@
-id: fantom_testnet
-wormholeChainName: fantom
-mainnet: false
-rpcUrl: https://rpc.ankr.com/fantom_testnet
-networkId: 4002
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/fuji.yaml

@@ -1,6 +0,0 @@
-id: fuji
-wormholeChainName: avalanche
-mainnet: false
-rpcUrl: https://api.avax-test.network/ext/bc/C/rpc
-networkId: 43113
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/gnosis.yaml

@@ -1,6 +0,0 @@
-id: gnosis
-wormholeChainName: gnosis
-mainnet: true
-rpcUrl: https://rpc.gnosischain.com
-networkId: 100
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/goerli.yaml

@@ -1,6 +0,0 @@
-id: goerli
-wormholeChainName: ethereum
-mainnet: false
-rpcUrl: https://rpc.goerli.eth.gateway.fm
-networkId: 5
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/kava.yaml

@@ -1,6 +0,0 @@
-id: kava
-wormholeChainName: kava
-mainnet: true
-rpcUrl: https://evm.kava.io
-networkId: 2222
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/kava_testnet.yaml

@@ -1,6 +0,0 @@
-id: kava_testnet
-wormholeChainName: kava
-mainnet: false
-rpcUrl: https://evm.testnet.kava.io
-networkId: 2221
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/kcc.yaml

@@ -1,6 +0,0 @@
-id: kcc
-wormholeChainName: kcc
-mainnet: true
-rpcUrl: https://rpc-mainnet.kcc.network
-networkId: 321
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/kcc_testnet.yaml

@@ -1,6 +0,0 @@
-id: kcc_testnet
-wormholeChainName: kcc
-mainnet: false
-rpcUrl: https://rpc-testnet.kcc.network
-networkId: 322
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/linea.yaml

@@ -1,6 +0,0 @@
-id: linea
-wormholeChainName: linea
-mainnet: true
-rpcUrl: https://linea.rpc.thirdweb.com
-networkId: 59144
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/linea_goerli.yaml

@@ -1,6 +0,0 @@
-id: linea_goerli
-wormholeChainName: linea
-mainnet: false
-rpcUrl: https://rpc.goerli.linea.build
-networkId: 59140
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/mantle.yaml

@@ -1,6 +0,0 @@
-id: mantle
-wormholeChainName: mantle
-mainnet: true
-rpcUrl: https://rpc.mantle.xyz/
-networkId: 5000
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/mantle_testnet.yaml

@@ -1,6 +0,0 @@
-id: mantle_testnet
-wormholeChainName: mantle
-mainnet: false
-rpcUrl: https://rpc.testnet.mantle.xyz/
-networkId: 5001
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/meter.yaml

@@ -1,6 +0,0 @@
-id: meter
-wormholeChainName: meter
-mainnet: true
-rpcUrl: https://rpc-meter.jellypool.xyz
-networkId: 82
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/meter_testnet.yaml

@@ -1,6 +0,0 @@
-id: meter_testnet
-wormholeChainName: meter
-mainnet: false
-rpcUrl: https://rpctest.meter.io
-networkId: 83
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/mumbai.yaml

@@ -1,6 +0,0 @@
-id: mumbai
-wormholeChainName: polygon
-mainnet: false
-rpcUrl: https://polygon-testnet-rpc.allthatnode.com:8545
-networkId: 80001
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/neon.yaml

@@ -1,6 +0,0 @@
-id: neon
-wormholeChainName: neon
-mainnet: true
-rpcUrl: https://neon-proxy-mainnet.solana.p2p.org
-networkId: 245022934
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/neon_devnet.yaml

@@ -1,6 +0,0 @@
-id: neon_devnet
-wormholeChainName: neon
-mainnet: false
-rpcUrl: https://devnet.neonevm.org
-networkId: 245022926
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/optimism.yaml

@@ -1,6 +0,0 @@
-id: optimism
-wormholeChainName: optimism
-mainnet: true
-rpcUrl: https://rpc.ankr.com/optimism
-networkId: 10
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/optimism_goerli.yaml

@@ -1,6 +0,0 @@
-id: optimism_goerli
-wormholeChainName: optimism
-mainnet: false
-rpcUrl: https://rpc.ankr.com/optimism_testnet
-networkId: 420
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/polygon.yaml

@@ -1,6 +0,0 @@
-id: polygon
-wormholeChainName: polygon
-mainnet: true
-rpcUrl: https://polygon-rpc.com
-networkId: 137
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/polygon_zkevm.yaml

@@ -1,6 +0,0 @@
-id: polygon_zkevm
-wormholeChainName: polygon_zkevm
-mainnet: true
-rpcUrl: https://zkevm-rpc.com
-networkId: 1101
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/polygon_zkevm_testnet.yaml

@@ -1,6 +0,0 @@
-id: polygon_zkevm_testnet
-wormholeChainName: polygon_zkevm
-mainnet: false
-rpcUrl: https://rpc.public.zkevm-test.net/
-networkId: 1442
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/shimmer_testnet.yaml

@@ -1,6 +0,0 @@
-id: shimmer_testnet
-wormholeChainName: shimmer
-mainnet: false
-rpcUrl: https://json-rpc.evm.testnet.shimmer.network
-networkId: 1072
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/syndr_nitro_testnet.yaml

@@ -1,6 +0,0 @@
-id: syndr_nitro_testnet
-wormholeChainName: syndr
-mainnet: false
-rpcUrl: https://syndr-nitro-testnet.calderachain.xyz/http
-networkId: 412346
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/wemix.yaml

@@ -1,6 +0,0 @@
-id: wemix
-wormholeChainName: wemix
-mainnet: true
-rpcUrl: https://api.wemix.com
-networkId: 1111
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/wemix_testnet.yaml

@@ -1,6 +0,0 @@
-id: wemix_testnet
-wormholeChainName: wemix
-mainnet: false
-rpcUrl: https://api.test.wemix.com
-networkId: 1112
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/zksync.yaml

@@ -1,6 +0,0 @@
-id: zksync
-wormholeChainName: zksync
-mainnet: true
-rpcUrl: https://zksync2-mainnet.zksync.io
-networkId: 324
-type: EvmChain

+ 0 - 6
contract_manager/store/chains/EvmChain/zksync_goerli.yaml

@@ -1,6 +0,0 @@
-id: zksync_goerli
-wormholeChainName: zksync
-mainnet: false
-rpcUrl: https://zksync2-testnet.zksync.dev
-networkId: 280
-type: EvmChain

+ 312 - 0
contract_manager/store/chains/EvmChains.yaml

@@ -0,0 +1,312 @@
+- id: linea_goerli
+  wormholeChainName: linea
+  mainnet: false
+  rpcUrl: https://rpc.goerli.linea.build
+  networkId: 59140
+  type: EvmChain
+- id: kava
+  wormholeChainName: kava
+  mainnet: true
+  rpcUrl: https://evm.kava.io
+  networkId: 2222
+  type: EvmChain
+- id: evmos
+  wormholeChainName: evmos
+  mainnet: true
+  rpcUrl: https://json-rpc.evmos.blockhunters.org
+  networkId: 9001
+  type: EvmChain
+- id: goerli
+  wormholeChainName: ethereum
+  mainnet: false
+  rpcUrl: https://rpc.goerli.eth.gateway.fm
+  networkId: 5
+  type: EvmChain
+- id: canto
+  wormholeChainName: canto
+  mainnet: true
+  rpcUrl: https://canto.gravitychain.io
+  networkId: 7700
+  type: EvmChain
+- id: fuji
+  wormholeChainName: avalanche
+  mainnet: false
+  rpcUrl: https://api.avax-test.network/ext/bc/C/rpc
+  networkId: 43113
+  type: EvmChain
+- id: base_goerli
+  wormholeChainName: base
+  mainnet: false
+  rpcUrl: https://goerli.base.org
+  networkId: 84531
+  type: EvmChain
+- id: avalanche
+  wormholeChainName: avalanche
+  mainnet: true
+  rpcUrl: https://api.avax.network/ext/bc/C/rpc
+  networkId: 43114
+  type: EvmChain
+- id: cronos_testnet
+  wormholeChainName: cronos
+  mainnet: false
+  rpcUrl: https://evm-t3.cronos.org
+  networkId: 338
+  type: EvmChain
+- id: arbitrum_testnet
+  wormholeChainName: arbitrum
+  mainnet: false
+  rpcUrl: https://goerli-rollup.arbitrum.io/rpc
+  networkId: 421613
+  type: EvmChain
+- id: zksync_goerli
+  wormholeChainName: zksync
+  mainnet: false
+  rpcUrl: https://zksync2-testnet.zksync.dev
+  networkId: 280
+  type: EvmChain
+- id: canto_testnet
+  wormholeChainName: canto
+  mainnet: false
+  rpcUrl: https://canto-testnet.plexnode.wtf
+  networkId: 7701
+  type: EvmChain
+- id: polygon_zkevm_testnet
+  wormholeChainName: polygon_zkevm
+  mainnet: false
+  rpcUrl: https://rpc.public.zkevm-test.net/
+  networkId: 1442
+  type: EvmChain
+- id: aurora_testnet
+  wormholeChainName: aurora
+  mainnet: false
+  rpcUrl: https://testnet.aurora.dev
+  networkId: 1313161555
+  type: EvmChain
+- id: mantle_testnet
+  wormholeChainName: mantle
+  mainnet: false
+  rpcUrl: https://rpc.testnet.mantle.xyz/
+  networkId: 5001
+  type: EvmChain
+- id: gnosis
+  wormholeChainName: gnosis
+  mainnet: true
+  rpcUrl: https://rpc.gnosischain.com
+  networkId: 100
+  type: EvmChain
+- id: fantom_testnet
+  wormholeChainName: fantom
+  mainnet: false
+  rpcUrl: https://rpc.ankr.com/fantom_testnet
+  networkId: 4002
+  type: EvmChain
+- id: neon
+  wormholeChainName: neon
+  mainnet: true
+  rpcUrl: https://neon-proxy-mainnet.solana.p2p.org
+  networkId: 245022934
+  type: EvmChain
+- id: fantom
+  wormholeChainName: fantom
+  mainnet: true
+  rpcUrl: https://rpc.ankr.com/fantom
+  networkId: 250
+  type: EvmChain
+- id: mumbai
+  wormholeChainName: polygon
+  mainnet: false
+  rpcUrl: https://polygon-testnet-rpc.allthatnode.com:8545
+  networkId: 80001
+  type: EvmChain
+- id: neon_devnet
+  wormholeChainName: neon
+  mainnet: false
+  rpcUrl: https://devnet.neonevm.org
+  networkId: 245022926
+  type: EvmChain
+- id: meter
+  wormholeChainName: meter
+  mainnet: true
+  rpcUrl: https://rpc-meter.jellypool.xyz
+  networkId: 82
+  type: EvmChain
+- id: chiado
+  wormholeChainName: gnosis
+  mainnet: false
+  rpcUrl: https://rpc.chiadochain.net
+  networkId: 10200
+  type: EvmChain
+- id: mantle
+  wormholeChainName: mantle
+  mainnet: true
+  rpcUrl: https://rpc.mantle.xyz/
+  networkId: 5000
+  type: EvmChain
+- id: kava_testnet
+  wormholeChainName: kava
+  mainnet: false
+  rpcUrl: https://evm.testnet.kava.io
+  networkId: 2221
+  type: EvmChain
+- id: evmos_testnet
+  wormholeChainName: evmos
+  mainnet: false
+  rpcUrl: https://eth.bd.evmos.dev:8545/
+  networkId: 9000
+  type: EvmChain
+- id: cronos
+  wormholeChainName: cronos
+  mainnet: true
+  rpcUrl: https://cronosrpc-1.xstaking.sg
+  networkId: 25
+  type: EvmChain
+- id: ethereum
+  wormholeChainName: ethereum
+  mainnet: true
+  rpcUrl: https://eth.llamarpc.com
+  networkId: 1
+  type: EvmChain
+- id: bnb_testnet
+  wormholeChainName: bsc
+  mainnet: false
+  rpcUrl: https://rpc.ankr.com/bsc_testnet_chapel
+  networkId: 97
+  type: EvmChain
+- id: wemix
+  wormholeChainName: wemix
+  mainnet: true
+  rpcUrl: https://api.wemix.com
+  networkId: 1111
+  type: EvmChain
+- id: aurora
+  wormholeChainName: aurora
+  mainnet: true
+  rpcUrl: https://mainnet.aurora.dev
+  networkId: 1313161554
+  type: EvmChain
+- id: bnb
+  wormholeChainName: bsc
+  mainnet: true
+  rpcUrl: https://rpc.ankr.com/bsc
+  networkId: 56
+  type: EvmChain
+- id: eos
+  wormholeChainName: eos
+  mainnet: true
+  rpcUrl: https://api.evm.eosnetwork.com
+  networkId: 17777
+  type: EvmChain
+- id: conflux_espace_testnet
+  wormholeChainName: conflux_espace
+  mainnet: false
+  rpcUrl: https://evmtestnet.confluxrpc.com
+  networkId: 71
+  type: EvmChain
+- id: conflux_espace
+  wormholeChainName: conflux_espace
+  mainnet: true
+  rpcUrl: https://evm.confluxrpc.org
+  networkId: 1030
+  type: EvmChain
+- id: optimism_goerli
+  wormholeChainName: optimism
+  mainnet: false
+  rpcUrl: https://rpc.ankr.com/optimism_testnet
+  networkId: 420
+  type: EvmChain
+- id: celo
+  wormholeChainName: celo
+  mainnet: true
+  rpcUrl: https://forno.celo.org
+  networkId: 42220
+  type: EvmChain
+- id: polygon
+  wormholeChainName: polygon
+  mainnet: true
+  rpcUrl: https://polygon-rpc.com
+  networkId: 137
+  type: EvmChain
+- id: wemix_testnet
+  wormholeChainName: wemix
+  mainnet: false
+  rpcUrl: https://api.test.wemix.com
+  networkId: 1112
+  type: EvmChain
+- id: kcc
+  wormholeChainName: kcc
+  mainnet: true
+  rpcUrl: https://rpc-mainnet.kcc.network
+  networkId: 321
+  type: EvmChain
+- id: polygon_zkevm
+  wormholeChainName: polygon_zkevm
+  mainnet: true
+  rpcUrl: https://zkevm-rpc.com
+  networkId: 1101
+  type: EvmChain
+- id: celo_alfajores_testnet
+  wormholeChainName: celo
+  mainnet: false
+  rpcUrl: https://alfajores-forno.celo-testnet.org
+  networkId: 44787
+  type: EvmChain
+- id: syndr_nitro_testnet
+  wormholeChainName: syndr
+  mainnet: false
+  rpcUrl: https://syndr-nitro-testnet.calderachain.xyz/http
+  networkId: 412346
+  type: EvmChain
+- id: zksync
+  wormholeChainName: zksync
+  mainnet: true
+  rpcUrl: https://zksync2-mainnet.zksync.io
+  networkId: 324
+  type: EvmChain
+- id: base
+  wormholeChainName: base
+  mainnet: true
+  rpcUrl: https://developer-access-mainnet.base.org/
+  networkId: 8453
+  type: EvmChain
+- id: arbitrum
+  wormholeChainName: arbitrum
+  mainnet: true
+  rpcUrl: https://arb1.arbitrum.io/rpc
+  networkId: 42161
+  type: EvmChain
+- id: optimism
+  wormholeChainName: optimism
+  mainnet: true
+  rpcUrl: https://rpc.ankr.com/optimism
+  networkId: 10
+  type: EvmChain
+- id: kcc_testnet
+  wormholeChainName: kcc
+  mainnet: false
+  rpcUrl: https://rpc-testnet.kcc.network
+  networkId: 322
+  type: EvmChain
+- id: eos_testnet
+  wormholeChainName: eos
+  mainnet: false
+  rpcUrl: https://api.testnet.evm.eosnetwork.com
+  networkId: 15557
+  type: EvmChain
+- id: meter_testnet
+  wormholeChainName: meter
+  mainnet: false
+  rpcUrl: https://rpctest.meter.io
+  networkId: 83
+  type: EvmChain
+- id: linea
+  wormholeChainName: linea
+  mainnet: true
+  rpcUrl: https://linea.rpc.thirdweb.com
+  networkId: 59144
+  type: EvmChain
+- id: shimmer_testnet
+  wormholeChainName: shimmer
+  mainnet: false
+  rpcUrl: https://json-rpc.evm.testnet.shimmer.network
+  networkId: 1072
+  type: EvmChain

+ 0 - 5
contract_manager/store/chains/SuiChain/sui_devnet.yaml

@@ -1,5 +0,0 @@
-id: sui_devnet
-wormholeChainName: sui
-mainnet: false
-rpcUrl: https://fullnode.devnet.sui.io:443
-type: SuiChain

+ 0 - 5
contract_manager/store/chains/SuiChain/sui_mainnet.yaml

@@ -1,5 +0,0 @@
-id: sui_mainnet
-wormholeChainName: sui
-mainnet: true
-rpcUrl: https://fullnode.mainnet.sui.io:443
-type: SuiChain

+ 0 - 5
contract_manager/store/chains/SuiChain/sui_testnet.yaml

@@ -1,5 +0,0 @@
-id: sui_testnet
-wormholeChainName: sui
-mainnet: false
-rpcUrl: https://fullnode.testnet.sui.io:443
-type: SuiChain

+ 15 - 0
contract_manager/store/chains/SuiChains.yaml

@@ -0,0 +1,15 @@
+- id: sui_testnet
+  wormholeChainName: sui
+  mainnet: false
+  rpcUrl: https://fullnode.testnet.sui.io:443
+  type: SuiChain
+- id: sui_devnet
+  wormholeChainName: sui
+  mainnet: false
+  rpcUrl: https://fullnode.devnet.sui.io:443
+  type: SuiChain
+- id: sui_mainnet
+  wormholeChainName: sui
+  mainnet: true
+  rpcUrl: https://fullnode.mainnet.sui.io:443
+  type: SuiChain

+ 0 - 4
contract_manager/store/contracts/AptosContract/aptos_mainnet_0xbd6d205f2aa288baa71270e66716d3d1bafe173ab9f312de4e9dd761ddef5409.yaml

@@ -1,4 +0,0 @@
-chain: aptos_mainnet
-stateId: "0x7e783b349d3e89cf5931af376ebeadbfab855b3fa239b7ada8f5a92fbea6b387"
-wormholeStateId: "0x5bc11445584a763c1fa7ed39081f1b920954da14e04b32440cba863d03e19625"
-type: AptosContract

+ 0 - 4
contract_manager/store/contracts/AptosContract/aptos_testnet_0xbd6d205f2aa288baa71270e66716d3d1bafe173ab9f312de4e9dd761ddef5409.yaml

@@ -1,4 +0,0 @@
-chain: aptos_testnet
-stateId: "0x7e783b349d3e89cf5931af376ebeadbfab855b3fa239b7ada8f5a92fbea6b387"
-wormholeStateId: "0x5bc11445584a763c1fa7ed39081f1b920954da14e04b32440cba863d03e19625"
-type: AptosContract

+ 8 - 0
contract_manager/store/contracts/AptosContracts.yaml

@@ -0,0 +1,8 @@
+- chain: aptos_mainnet
+  stateId: "0x7e783b349d3e89cf5931af376ebeadbfab855b3fa239b7ada8f5a92fbea6b387"
+  wormholeStateId: "0x5bc11445584a763c1fa7ed39081f1b920954da14e04b32440cba863d03e19625"
+  type: AptosContract
+- chain: aptos_testnet
+  stateId: "0x7e783b349d3e89cf5931af376ebeadbfab855b3fa239b7ada8f5a92fbea6b387"
+  wormholeStateId: "0x5bc11445584a763c1fa7ed39081f1b920954da14e04b32440cba863d03e19625"
+  type: AptosContract

+ 0 - 3
contract_manager/store/contracts/CosmWasmContract/injective_inj12j43nf2f0qumnt2zrrmpvnsqgzndxefujlvr08.yaml

@@ -1,3 +0,0 @@
-chain: injective
-address: inj12j43nf2f0qumnt2zrrmpvnsqgzndxefujlvr08
-type: CosmWasmContract

+ 0 - 3
contract_manager/store/contracts/CosmWasmContract/injective_testnet_inj18hckkzqf47mdhd734g6papk6wj20y24rm43sk9.yaml

@@ -1,3 +0,0 @@
-chain: injective_testnet
-address: inj18hckkzqf47mdhd734g6papk6wj20y24rm43sk9
-type: CosmWasmContract

+ 0 - 3
contract_manager/store/contracts/CosmWasmContract/injective_testnet_inj18rlflp3735h25jmjx97d22c72sxk260amdjxlu.yaml

@@ -1,3 +0,0 @@
-chain: injective_testnet
-address: inj18rlflp3735h25jmjx97d22c72sxk260amdjxlu
-type: CosmWasmContract

+ 0 - 3
contract_manager/store/contracts/CosmWasmContract/juno_testnet_juno1eacsrua27njc35pxz37y97gmcjs899t59f8pf0rkejjyvtmhws5q6lxsdd.yaml

@@ -1,3 +0,0 @@
-chain: juno_testnet
-address: juno1eacsrua27njc35pxz37y97gmcjs899t59f8pf0rkejjyvtmhws5q6lxsdd
-type: CosmWasmContract

+ 0 - 3
contract_manager/store/contracts/CosmWasmContract/juno_testnet_juno1h93q9kwlnfml2gum4zj54al9w4jdmuhtzrh6vhycnemsqlqv9l9snnznxs.yaml

@@ -1,3 +0,0 @@
-chain: juno_testnet
-address: juno1h93q9kwlnfml2gum4zj54al9w4jdmuhtzrh6vhycnemsqlqv9l9snnznxs
-type: CosmWasmContract

+ 0 - 3
contract_manager/store/contracts/CosmWasmContract/neutron_neutron1m2emc93m9gpwgsrsf2vylv9xvgqh654630v7dfrhrkmr5slly53spg85wv.yaml

@@ -1,3 +0,0 @@
-chain: neutron
-address: neutron1m2emc93m9gpwgsrsf2vylv9xvgqh654630v7dfrhrkmr5slly53spg85wv
-type: CosmWasmContract

+ 0 - 3
contract_manager/store/contracts/CosmWasmContract/neutron_testnet_pion_1_neutron15ldst8t80982akgr8w8ekcytejzkmfpgdkeq4xgtge48qs7435jqp87u3t.yaml

@@ -1,3 +0,0 @@
-chain: neutron_testnet_pion_1
-address: neutron15ldst8t80982akgr8w8ekcytejzkmfpgdkeq4xgtge48qs7435jqp87u3t
-type: CosmWasmContract

+ 0 - 3
contract_manager/store/contracts/CosmWasmContract/neutron_testnet_pion_1_neutron16zwrmx3zgggmxhzau86xfycm42cr4sj888hdvzsxya3qarp6zhhqzhlkvz.yaml

@@ -1,3 +0,0 @@
-chain: neutron_testnet_pion_1
-address: neutron16zwrmx3zgggmxhzau86xfycm42cr4sj888hdvzsxya3qarp6zhhqzhlkvz
-type: CosmWasmContract

+ 0 - 3
contract_manager/store/contracts/CosmWasmContract/osmosis_osmo1hpdzqku55lmfmptpyj6wdlugqs5etr6teqf7r4yqjjrxjznjhtuqqu5kdh.yaml

@@ -1,3 +0,0 @@
-chain: osmosis
-address: osmo13ge29x4e2s63a8ytz2px8gurtyznmue4a69n5275692v3qn3ks8q7cwck7
-type: CosmWasmContract

+ 0 - 3
contract_manager/store/contracts/CosmWasmContract/osmosis_testnet_5_osmo1hpdzqku55lmfmptpyj6wdlugqs5etr6teqf7r4yqjjrxjznjhtuqqu5kdh.yaml

@@ -1,3 +0,0 @@
-chain: osmosis_testnet_5
-address: osmo1hpdzqku55lmfmptpyj6wdlugqs5etr6teqf7r4yqjjrxjznjhtuqqu5kdh
-type: CosmWasmContract

+ 0 - 3
contract_manager/store/contracts/CosmWasmContract/osmosis_testnet_5_osmo1lltupx02sj99suakmuk4sr4ppqf34ajedaxut3ukjwkv6469erwqtpg9t3.yaml

@@ -1,3 +0,0 @@
-chain: osmosis_testnet_5
-address: osmo1lltupx02sj99suakmuk4sr4ppqf34ajedaxut3ukjwkv6469erwqtpg9t3
-type: CosmWasmContract

+ 0 - 3
contract_manager/store/contracts/CosmWasmContract/sei_pacific_1_sei15d2tyq2jzxmpg32y3am3w62dts32qgzmds9qnr6c87r0gwwr7ynqal0x38.yaml

@@ -1,3 +0,0 @@
-chain: sei_pacific_1
-address: sei15d2tyq2jzxmpg32y3am3w62dts32qgzmds9qnr6c87r0gwwr7ynqal0x38
-type: CosmWasmContract

+ 0 - 3
contract_manager/store/contracts/CosmWasmContract/sei_testnet_atlantic_2_sei1kpntez76v38yuxhhaaahdmvjxnr5tkr8tq077smefs7uw70rj5yqw2aewy.yaml

@@ -1,3 +0,0 @@
-chain: sei_testnet_atlantic_2
-address: sei1kpntez76v38yuxhhaaahdmvjxnr5tkr8tq077smefs7uw70rj5yqw2aewy
-type: CosmWasmContract

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.