Sfoglia il codice sorgente

Abolish xc governance sdk (#957)

* Replace xc-governance-sdk with xc_admin_common package

xc_admin_package was not using the CHAIN overrides declared in the governance-sdk so it was moved
to that package as well

* Replace xc-governance-sdk with xc_admin_common in other packages

* Remove the package and all of its references

* Fix tests

* Fix bug in GovernanceDataSourceTransfer encoding

* Rename all references to the old package

* Redeploy neutron_testnet contract with new chain id

* Move SetWormholeAddress to separate file
Mohammad Amin Khashkhashi Moghaddam 2 anni fa
parent
commit
c732fcf586
56 ha cambiato i file con 1525 aggiunte e 2370 eliminazioni
  1. 2 6
      .github/workflows/ethereum-contract.yml
  2. 1 0
      contract_manager/.gitignore
  3. 0 1
      contract_manager/package.json
  4. 15 10
      contract_manager/src/aptos.ts
  5. 1 6
      contract_manager/src/base.ts
  6. 47 42
      contract_manager/src/chains.ts
  7. 9 15
      contract_manager/src/cosmwasm.ts
  8. 19 11
      contract_manager/src/evm.ts
  9. 11 13
      contract_manager/src/sui.ts
  10. 4 45
      contract_manager/src/test.ts
  11. 2 2
      contract_manager/store/chains/CosmWasmChain/neutron_testnet_pion_1.yaml
  12. 1 1
      contract_manager/store/contracts/CosmWasmContract/neutron_testnet_pion_1_neutron1xxmcu6wxgawjlajx8jalyk9cxsudnygjg0tvjesfyurh4utvtpes5wmpjp.yaml
  13. 0 1
      governance/xc_admin/packages/xc_admin_common/package.json
  14. 13 7
      governance/xc_admin/packages/xc_admin_common/src/__tests__/GovernancePayload.test.ts
  15. 14 3
      governance/xc_admin/packages/xc_admin_common/src/chains.ts
  16. 5 4
      governance/xc_admin/packages/xc_admin_common/src/contracts/Contract.ts
  17. 6 8
      governance/xc_admin/packages/xc_admin_common/src/contracts/EvmPythUpgradable.ts
  18. 1 1
      governance/xc_admin/packages/xc_admin_common/src/governance_payload/ExecutePostedVaa.ts
  19. 2 2
      governance/xc_admin/packages/xc_admin_common/src/governance_payload/GovernanceDataSourceTransfer.ts
  20. 4 6
      governance/xc_admin/packages/xc_admin_common/src/governance_payload/PythGovernanceAction.ts
  21. 1 1
      governance/xc_admin/packages/xc_admin_common/src/governance_payload/SetDataSources.ts
  22. 1 1
      governance/xc_admin/packages/xc_admin_common/src/governance_payload/SetFee.ts
  23. 1 1
      governance/xc_admin/packages/xc_admin_common/src/governance_payload/SetValidPeriod.ts
  24. 33 0
      governance/xc_admin/packages/xc_admin_common/src/governance_payload/SetWormholeAddress.ts
  25. 30 1
      governance/xc_admin/packages/xc_admin_common/src/governance_payload/UpgradeContract.ts
  26. 10 0
      governance/xc_admin/packages/xc_admin_common/src/governance_payload/index.ts
  27. 1 0
      governance/xc_admin/packages/xc_admin_common/src/index.ts
  28. 1 1
      governance/xc_admin/packages/xc_admin_frontend/Dockerfile
  29. 0 11
      governance/xc_governance_sdk_js/.eslintrc.js
  30. 0 3
      governance/xc_governance_sdk_js/.gitignore
  31. 0 201
      governance/xc_governance_sdk_js/LICENSE
  32. 0 5
      governance/xc_governance_sdk_js/jest.config.js
  33. 0 42
      governance/xc_governance_sdk_js/package.json
  34. 0 24
      governance/xc_governance_sdk_js/src/index.ts
  35. 0 217
      governance/xc_governance_sdk_js/src/instructions.ts
  36. 0 63
      governance/xc_governance_sdk_js/src/serialize.ts
  37. 0 9
      governance/xc_governance_sdk_js/tsconfig.json
  38. 1168 1452
      package-lock.json
  39. 0 1
      package.json
  40. 1 1
      target_chains/cosmwasm/tools/package.json
  41. 2 2
      target_chains/cosmwasm/tools/src/chains-manager/chains.ts
  42. 1 1
      target_chains/cosmwasm/tools/src/configs.ts
  43. 5 5
      target_chains/cosmwasm/tools/store/edge/instantiate-pyth/neutron_testnet_pion_1-1.2.0.json
  44. 7 7
      target_chains/cosmwasm/tools/store/edge/test-contracts/neutron_testnet_pion_1-1.2.0.json
  45. 5 5
      target_chains/cosmwasm/tools/store/stable/instantiate-pyth/neutron_testnet_pion_1-1.2.0.json
  46. 7 7
      target_chains/cosmwasm/tools/store/stable/test-contracts/neutron_testnet_pion_1-1.2.0.json
  47. 1 1
      target_chains/ethereum/contracts/.env.template
  48. 2 2
      target_chains/ethereum/contracts/Deploying.md
  49. 1 1
      target_chains/ethereum/contracts/deploy/zkSyncDeploy.ts
  50. 0 1
      target_chains/ethereum/contracts/deploy/zkSyncDeployNewPythImpl.ts
  51. 1 1
      target_chains/ethereum/contracts/migrations/prod-receiver/2_deploy_wormhole_receiver.js
  52. 1 1
      target_chains/ethereum/contracts/package.json
  53. 18 21
      target_chains/ethereum/contracts/scripts/syncPythState.js
  54. 68 95
      target_chains/ethereum/contracts/test/pyth.js
  55. 1 1
      tilt_devnet/docker_images/Dockerfile.cosmwasm
  56. 1 1
      tilt_devnet/docker_images/Dockerfile.ethereum

+ 2 - 6
.github/workflows/ethereum-contract.yml

@@ -2,13 +2,13 @@ on:
   pull_request:
     paths:
       - target_chains/ethereum/contracts/**
-      - governance/xc_governance_sdk_js/**
+      - governance/xc_admin/packages/xc_admin_common/**
   push:
     branches:
       - main
     paths:
       - target_chains/ethereum/contracts/**
-      - governance/xc_governance_sdk_js/**
+      - governance/xc_admin/packages/xc_admin_common/**
 
 name: Ethereum Contract
 
@@ -22,10 +22,6 @@ jobs:
     steps:
       - uses: actions/checkout@v3
 
-      - name: Install XC-governance sdk dependencies
-        run: npm ci
-        working-directory: governance/xc_governance_sdk_js
-
       - name: Install contract npm dependencies
         run: npm ci
 

+ 1 - 0
contract_manager/.gitignore

@@ -0,0 +1 @@
+lib/

+ 0 - 1
contract_manager/package.json

@@ -17,7 +17,6 @@
     "@certusone/wormhole-sdk": "^0.9.8",
     "@pythnetwork/cosmwasm-deploy-tools": "*",
     "@pythnetwork/price-service-client": "*",
-    "@pythnetwork/xc-governance-sdk": "*",
     "bs58": "^5.0.0",
     "ts-node": "^10.9.1",
     "typescript": "^4.9.3"

+ 15 - 10
contract_manager/src/aptos.ts

@@ -1,7 +1,6 @@
 import { Contract } from "./base";
 import { AptosChain, Chain } from "./chains";
-import { DataSource, HexString32Bytes } from "@pythnetwork/xc-governance-sdk";
-import { AptosClient } from "aptos";
+import { DataSource } from "xc_admin_common";
 
 export class AptosContract extends Contract {
   static type: string = "AptosContract";
@@ -64,19 +63,25 @@ export class AptosContract extends Contract {
   async getDataSources(): Promise<DataSource[]> {
     const data = (await this.findResource("DataSources")) as any;
     return data.sources.keys.map((source: any) => {
-      return new DataSource(
-        Number(source.emitter_chain),
-        new HexString32Bytes(source.emitter_address.external_address)
-      );
+      return {
+        emitterChain: Number(source.emitter_chain),
+        emitterAddress: source.emitter_address.external_address.replace(
+          "0x",
+          ""
+        ),
+      };
     });
   }
 
   async getGovernanceDataSource(): Promise<DataSource> {
     const data = (await this.findResource("GovernanceDataSource")) as any;
-    return new DataSource(
-      Number(data.source.emitter_chain),
-      new HexString32Bytes(data.source.emitter_address.external_address)
-    );
+    return {
+      emitterChain: Number(data.source.emitter_chain),
+      emitterAddress: data.source.emitter_address.external_address.replace(
+        "0x",
+        ""
+      ),
+    };
   }
 
   getId(): string {

+ 1 - 6
contract_manager/src/base.ts

@@ -1,9 +1,4 @@
-import {
-  CHAINS,
-  DataSource,
-  HexString32Bytes,
-  SetFeeInstruction,
-} from "@pythnetwork/xc-governance-sdk";
+import { DataSource } from "xc_admin_common";
 import { Chain } from "./chains";
 
 export abstract class Storable {

+ 47 - 42
contract_manager/src/chains.ts

@@ -1,15 +1,13 @@
-import { readdirSync, readFileSync, writeFileSync } from "fs";
 import { Storable } from "./base";
 import {
+  ChainName,
   CHAINS,
-  CosmwasmUpgradeContractInstruction,
-  EthereumUpgradeContractInstruction,
-  HexString20Bytes,
-  HexString32Bytes,
-  SetFeeInstruction,
-  SuiAuthorizeUpgradeContractInstruction,
-} from "@pythnetwork/xc-governance-sdk";
-import { BufferBuilder } from "@pythnetwork/xc-governance-sdk/lib/serialize";
+  SetFee,
+  CosmosUpgradeContract,
+  EvmUpgradeContract,
+  SuiAuthorizeUpgradeContract,
+  AptosAuthorizeUpgradeContract,
+} from "xc_admin_common";
 import { AptosClient } from "aptos";
 
 export abstract class Chain extends Storable {
@@ -27,11 +25,11 @@ export abstract class Chain extends Storable {
    * @param exponent the new fee exponent to set
    */
   generateGovernanceSetFeePayload(fee: number, exponent: number): Buffer {
-    return new SetFeeInstruction(
-      CHAINS[this.getId() as keyof typeof CHAINS],
+    return new SetFee(
+      this.getId() as ChainName,
       BigInt(fee),
       BigInt(exponent)
-    ).serialize();
+    ).encode();
   }
 
   /**
@@ -84,10 +82,10 @@ export class CosmWasmChain extends Chain {
   }
 
   generateGovernanceUpgradePayload(codeId: bigint): Buffer {
-    return new CosmwasmUpgradeContractInstruction(
-      CHAINS[this.getId() as keyof typeof CHAINS],
+    return new CosmosUpgradeContract(
+      this.getId() as ChainName,
       codeId
-    ).serialize();
+    ).encode();
   }
 }
 
@@ -115,37 +113,42 @@ export class SuiChain extends Chain {
     return SuiChain.type;
   }
 
+  //TODO: Move this logic to xc_admin_common
   private wrapWithWormholeGovernancePayload(
     actionVariant: number,
     payload: Buffer
   ): Buffer {
-    const builder = new BufferBuilder();
-    builder.addBuffer(
+    const actionVariantBuffer = Buffer.alloc(1);
+    actionVariantBuffer.writeUint8(actionVariant, 0);
+    const chainBuffer = Buffer.alloc(2);
+    chainBuffer.writeUint16BE(CHAINS["sui"], 0);
+    const result = Buffer.concat([
       Buffer.from(
         "0000000000000000000000000000000000000000000000000000000000000001",
         "hex"
-      )
-    );
-    builder.addUint8(actionVariant);
-    builder.addUint16(CHAINS["sui"]); // should always be sui (21) no matter devnet or testnet
-    builder.addBuffer(payload);
-    return builder.build();
+      ),
+      actionVariantBuffer,
+      chainBuffer,
+      payload,
+    ]);
+    return result;
   }
 
+  /**
+   * Returns the payload for a governance contract upgrade instruction for contracts deployed on this chain
+   * @param digest hex string of the 32 byte digest for the new package without the 0x prefix
+   */
   generateGovernanceUpgradePayload(digest: string): Buffer {
-    let setFee = new SuiAuthorizeUpgradeContractInstruction(
-      CHAINS["sui"],
-      new HexString32Bytes(digest)
-    ).serialize();
+    let setFee = new SuiAuthorizeUpgradeContract("sui", digest).encode();
     return this.wrapWithWormholeGovernancePayload(0, setFee);
   }
 
   generateGovernanceSetFeePayload(fee: number, exponent: number): Buffer {
-    let setFee = new SetFeeInstruction(
-      CHAINS["sui"],
+    let setFee = new SetFee(
+      "sui", // should always be sui no matter devnet or testnet or mainnet
       BigInt(fee),
       BigInt(exponent)
-    ).serialize();
+    ).encode();
     return this.wrapWithWormholeGovernancePayload(3, setFee);
   }
 }
@@ -162,11 +165,12 @@ export class EVMChain extends Chain {
     return new EVMChain(parsed.id, parsed.rpcUrl);
   }
 
-  generateGovernanceUpgradePayload(address: HexString20Bytes): Buffer {
-    return new EthereumUpgradeContractInstruction(
-      CHAINS[this.getId() as keyof typeof CHAINS],
-      address
-    ).serialize();
+  /**
+   * Returns the payload for a governance contract upgrade instruction for contracts deployed on this chain
+   * @param address hex string of the 20 byte address of the contract to upgrade to without the 0x prefix
+   */
+  generateGovernanceUpgradePayload(address: string): Buffer {
+    return new EvmUpgradeContract(this.getId() as ChainName, address).encode();
   }
 
   toJson(): any {
@@ -193,19 +197,20 @@ export class AptosChain extends Chain {
     return new AptosClient(this.rpcUrl);
   }
 
+  /**
+   * Returns the payload for a governance contract upgrade instruction for contracts deployed on this chain
+   * @param digest hex string of the 32 byte digest for the new package without the 0x prefix
+   */
   generateGovernanceUpgradePayload(digest: string): Buffer {
-    return new SuiAuthorizeUpgradeContractInstruction(
-      CHAINS["aptos"],
-      new HexString32Bytes(digest)
-    ).serialize();
+    return new AptosAuthorizeUpgradeContract("aptos", digest).encode();
   }
 
   generateGovernanceSetFeePayload(fee: number, exponent: number): Buffer {
-    return new SetFeeInstruction(
-      CHAINS["aptos"], // should always be aptos (22) no matter devnet or testnet or mainnet
+    return new SetFee(
+      "aptos", // should always be aptos no matter devnet or testnet or mainnet
       BigInt(fee),
       BigInt(exponent)
-    ).serialize();
+    ).encode();
   }
 
   getType(): string {

+ 9 - 15
contract_manager/src/cosmwasm.ts

@@ -1,11 +1,7 @@
 import { Chain, CosmWasmChain } from "./chains";
 import { readFileSync } from "fs";
 import { getPythConfig } from "@pythnetwork/cosmwasm-deploy-tools/lib/configs";
-import {
-  CHAINS,
-  DataSource,
-  HexString32Bytes,
-} from "@pythnetwork/xc-governance-sdk";
+import { CHAINS, DataSource } from "xc_admin_common";
 import { DeploymentType } from "@pythnetwork/cosmwasm-deploy-tools/lib/helper";
 import {
   CosmwasmExecutor,
@@ -45,10 +41,10 @@ export class CosmWasmContract extends Contract {
   async getDataSources(): Promise<DataSource[]> {
     const config = await this.getConfig();
     return config.config_v1.data_sources.map(({ emitter, chain_id }: any) => {
-      return new DataSource(
-        Number(chain_id),
-        new HexString32Bytes(Buffer.from(emitter, "base64").toString("hex"))
-      );
+      return {
+        emitterChain: Number(chain_id),
+        emitterAddress: Buffer.from(emitter, "base64").toString("hex"),
+      };
     });
   }
 
@@ -56,12 +52,10 @@ export class CosmWasmContract extends Contract {
     const config = await this.getConfig();
     const { emitter: emitterAddress, chain_id: chainId } =
       config.config_v1.governance_source;
-    return new DataSource(
-      Number(chainId),
-      new HexString32Bytes(
-        Buffer.from(emitterAddress, "base64").toString("hex")
-      )
-    );
+    return {
+      emitterChain: Number(chainId),
+      emitterAddress: Buffer.from(emitterAddress, "base64").toString("hex"),
+    };
   }
 
   static type = "CosmWasmContract";

+ 19 - 11
contract_manager/src/evm.ts

@@ -2,7 +2,7 @@ import Web3 from "web3"; //TODO: decide on using web3 or ethers.js
 import PythInterfaceAbi from "@pythnetwork/pyth-sdk-solidity/abis/IPyth.json";
 import { Contract } from "./base";
 import { Chain, EVMChain } from "./chains";
-import { DataSource, HexString32Bytes } from "@pythnetwork/xc-governance-sdk";
+import { DataSource } from "xc_admin_common";
 
 const EXTENDED_PYTH_ABI = [
   {
@@ -136,12 +136,20 @@ export class EVMContract extends Contract {
   async getDataSources(): Promise<DataSource[]> {
     const pythContract = this.getContract();
     const result = await pythContract.methods.validDataSources().call();
-    return result.map(({ chainId, emitterAddress }: any) => {
-      return new DataSource(
-        Number(chainId),
-        new HexString32Bytes(emitterAddress)
-      );
-    });
+    return result.map(
+      ({
+        chainId,
+        emitterAddress,
+      }: {
+        chainId: string;
+        emitterAddress: string;
+      }) => {
+        return {
+          emitterChain: Number(chainId),
+          emitterAddress: emitterAddress.replace("0x", ""),
+        };
+      }
+    );
   }
 
   async getGovernanceDataSource(): Promise<DataSource> {
@@ -149,10 +157,10 @@ export class EVMContract extends Contract {
     const [chainId, emitterAddress] = await pythContract.methods
       .governanceDataSource()
       .call();
-    return new DataSource(
-      Number(chainId),
-      new HexString32Bytes(emitterAddress)
-    );
+    return {
+      emitterChain: Number(chainId),
+      emitterAddress: emitterAddress.replace("0x", ""),
+    };
   }
 
   async executeGovernanceInstruction(privateKey: string, vaa: Buffer) {

+ 11 - 13
contract_manager/src/sui.ts

@@ -8,7 +8,7 @@ import {
   TransactionBlock,
 } from "@mysten/sui.js";
 import { Chain, SuiChain } from "./chains";
-import { DataSource, HexString32Bytes } from "@pythnetwork/xc-governance-sdk";
+import { DataSource } from "xc_admin_common";
 import { Contract } from "./base";
 
 export class SuiContract extends Contract {
@@ -294,14 +294,12 @@ export class SuiContract extends Contract {
     }
     return result.data.content.fields.value.fields.keys.map(
       ({ fields }: any) => {
-        return new DataSource(
-          Number(fields.emitter_chain),
-          new HexString32Bytes(
-            Buffer.from(
-              fields.emitter_address.fields.value.fields.data
-            ).toString("hex")
-          )
-        );
+        return {
+          emitterChain: Number(fields.emitter_chain),
+          emitterAddress: Buffer.from(
+            fields.emitter_address.fields.value.fields.data
+          ).toString("hex"),
+        };
       }
     );
   }
@@ -312,10 +310,10 @@ export class SuiContract extends Contract {
     const chainId = governanceFields.emitter_chain;
     const emitterAddress =
       governanceFields.emitter_address.fields.value.fields.data;
-    return new DataSource(
-      Number(chainId),
-      new HexString32Bytes(Buffer.from(emitterAddress).toString("hex"))
-    );
+    return {
+      emitterChain: Number(chainId),
+      emitterAddress: Buffer.from(emitterAddress).toString("hex"),
+    };
   }
 
   async getBaseUpdateFee() {

+ 4 - 45
contract_manager/src/test.ts

@@ -1,51 +1,10 @@
-import {
-  Vault,
-  Contracts,
-  Vaults,
-  loadHotWallet,
-  WormholeEmitter,
-  SubmittedWormholeMessage,
-} from "./entities";
-import { SuiContract } from "./sui";
-import { CosmWasmContract } from "./cosmwasm";
-import { Ed25519Keypair, RawSigner } from "@mysten/sui.js";
 import { DefaultStore } from "./store";
-import { Chains } from "./chains";
-import { executeProposal } from "xc_admin_common";
-import { EVMContract } from "./evm";
 
 async function test() {
-  // Deploy the same cosmwasm code with different config
-
-  // let c = Contracts.osmosis_testnet_5_osmo1lltupx02sj99suakmuk4sr4ppqf34ajedaxut3ukjwkv6469erwqtpg9t3 as CosmWasmContract;
-  // let old_conf = await c.getConfig();
-  // let config = CosmWasmContract.getDeploymentConfig(c.chain, 'edge', old_conf.config_v1.wormhole_contract);
-  // console.log(config);
-  // config.governance_source.emitter = wallet.publicKey.toBuffer().toString('base64');
-  // let mnemonic = 'FILLME'
-  // console.log(await CosmWasmContract.deploy(c.chain, await c.getCodeId(), config, mnemonic));
-
-  let s = DefaultStore;
-  Object.values(Contracts).forEach((c) => {
-    console.log(c);
-    s.save(c);
-  });
-
-  Object.values(Chains).forEach((c) => {
-    console.log(c);
-    s.save(c);
-  });
-
-  // Execute some governance instruction on sui contract
-
-  // let c = Contracts.sui_testnet_0x651dcb84d579fcdf51f15d79eb28f7e10b416c9202b6a156495bb1a4aecd55ea as SuiContract
-  // let wallet = await loadHotWallet('/tmp/priv.json');
-  // let emitter = new WormholeEmitter("devnet", wallet);
-  // let proposal = c.setUpdateFee(200);
-  // let submittedWormholeMessage = await emitter.sendMessage(proposal);
-  // let vaa = await submittedWormholeMessage.fetchVAA(10);
-  // const keypair = Ed25519Keypair.fromSecretKey(Buffer.from('FILLME', "hex"));
-  // await c.executeGovernanceInstruction(vaa);
+  for (const contract of Object.values(DefaultStore.contracts)) {
+    console.log("Contract", contract.getId());
+    console.log(await contract.getGovernanceDataSource());
+  }
 }
 
 test();

+ 2 - 2
contract_manager/store/chains/CosmWasmChain/neutron_testnet_pion_1.yaml

@@ -1,5 +1,5 @@
-querierEndpoint: https://rpc.pion.rs-testnet.polypore.xyz/
-executorEndpoint: https://rpc.pion.rs-testnet.polypore.xyz/
+querierEndpoint: https://rpc-palvus.pion-1.ntrn.tech/
+executorEndpoint: https://rpc-palvus.pion-1.ntrn.tech/
 id: neutron_testnet_pion_1
 gasPrice: "0.05"
 prefix: neutron

+ 1 - 1
contract_manager/store/contracts/CosmWasmContract/neutron_testnet_pion_1_neutron1xxmcu6wxgawjlajx8jalyk9cxsudnygjg0tvjesfyurh4utvtpes5wmpjp.yaml

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

+ 0 - 1
governance/xc_admin/packages/xc_admin_common/package.json

@@ -24,7 +24,6 @@
     "@coral-xyz/anchor": "^0.26.0",
     "@pythnetwork/client": "^2.17.0",
     "@pythnetwork/pyth-sdk-solidity": "*",
-    "@pythnetwork/xc-governance-sdk": "*",
     "@solana/buffer-layout": "^4.0.1",
     "@solana/web3.js": "^1.73.0",
     "@sqds/mesh": "^1.0.6",

+ 13 - 7
governance/xc_admin/packages/xc_admin_common/src/__tests__/GovernancePayload.test.ts

@@ -9,20 +9,16 @@ import {
   ActionName,
   PythGovernanceAction,
   decodeGovernancePayload,
+  EvmSetWormholeAddress,
 } from "..";
 import * as fc from "fast-check";
-import {
-  ChainId,
-  ChainName,
-  CHAINS,
-  toChainId,
-  toChainName,
-} from "@certusone/wormhole-sdk";
+import { ChainName, CHAINS } from "../chains";
 import { Arbitrary, IntArrayConstraints } from "fast-check";
 import {
   AptosAuthorizeUpgradeContract,
   CosmosUpgradeContract,
   EvmUpgradeContract,
+  SuiAuthorizeUpgradeContract,
 } from "../governance_payload/UpgradeContract";
 import {
   AuthorizeGovernanceDataSourceTransfer,
@@ -219,6 +215,12 @@ function governanceActionArb(): Arbitrary<PythGovernanceAction> {
           );
         }
       );
+
+      const suiArb = hexBytesArb({ minLength: 32, maxLength: 32 }).map(
+        (buffer) => {
+          return new SuiAuthorizeUpgradeContract(header.targetChainId, buffer);
+        }
+      );
       const evmArb = hexBytesArb({ minLength: 20, maxLength: 20 }).map(
         (address) => {
           return new EvmUpgradeContract(header.targetChainId, address);
@@ -254,6 +256,10 @@ function governanceActionArb(): Arbitrary<PythGovernanceAction> {
           parseInt(index.toString())
         );
       });
+    } else if (header.action === "SetWormholeAddress") {
+      return hexBytesArb({ minLength: 20, maxLength: 20 }).map((address) => {
+        return new EvmSetWormholeAddress(header.targetChainId, address);
+      });
     } else {
       throw new Error("Unsupported action type");
     }

+ 14 - 3
governance/xc_governance_sdk_js/src/chains.ts → governance/xc_admin/packages/xc_admin_common/src/chains.ts

@@ -1,6 +1,4 @@
 import { CHAINS as WORMHOLE_CHAINS } from "@certusone/wormhole-sdk";
-
-export { CHAINS as WORMHOLE_CHAINS } from "@certusone/wormhole-sdk";
 // GUIDELINES to add a chain
 // PYTH will have:
 // 1. Mainnet Deployment - which will have pyth mainnet governance and data sources
@@ -34,12 +32,12 @@ export const RECEIVER_CHAINS = {
   sei_pacific_1: 60017,
   sei_testnet_atlantic_2: 60018,
   neutron: 60019,
-  neutron_testnet_pion_1: 60020,
   juno: 60020,
   juno_testnet: 60021,
   kava: 60022,
   wemix: 60023,
   linea: 60024,
+  neutron_testnet_pion_1: 60025,
 };
 
 // If there is any overlapping value the receiver chain will replace the wormhole
@@ -47,3 +45,16 @@ export const RECEIVER_CHAINS = {
 export const CHAINS = { ...WORMHOLE_CHAINS, ...RECEIVER_CHAINS };
 export declare type ChainName = keyof typeof CHAINS;
 export declare type ChainId = typeof CHAINS[ChainName];
+
+export function toChainId(chainName: ChainName): ChainId {
+  return CHAINS[chainName];
+}
+
+const CHAIN_ID_TO_NAME = Object.entries(CHAINS).reduce((obj, [name, id]) => {
+  obj[id] = name;
+  return obj;
+}, {} as any);
+
+export function toChainName(chainId: ChainId): ChainName {
+  return CHAIN_ID_TO_NAME[chainId];
+}

+ 5 - 4
governance/xc_admin/packages/xc_admin_common/src/contracts/Contract.ts

@@ -1,5 +1,6 @@
-import { ChainId, Instruction } from "@pythnetwork/xc-governance-sdk";
+import { ChainId } from "../chains";
 import { ethers } from "ethers";
+import { PythGovernanceAction } from "../governance_payload";
 
 export enum ContractType {
   Oracle,
@@ -70,13 +71,13 @@ export interface SyncOp {
 }
 
 export class SendGovernanceInstruction implements SyncOp {
-  private instruction: Instruction;
+  private instruction: PythGovernanceAction;
   private sender: WormholeAddress;
   // function to submit the signed VAA to the target chain contract
   private submitVaa: (vaa: string) => Promise<boolean>;
 
   constructor(
-    instruction: Instruction,
+    instruction: PythGovernanceAction,
     from: WormholeAddress,
     submitVaa: (vaa: string) => Promise<boolean>
   ) {
@@ -87,7 +88,7 @@ export class SendGovernanceInstruction implements SyncOp {
 
   public id(): string {
     // TODO: use a more understandable identifier (also this may not be unique)
-    return ethers.utils.sha256(this.instruction.serialize());
+    return ethers.utils.sha256(this.instruction.encode());
   }
 
   public async run(cache: Record<string, any>): Promise<boolean> {

+ 6 - 8
governance/xc_admin/packages/xc_admin_common/src/contracts/EvmPythUpgradable.ts

@@ -7,11 +7,9 @@ import {
   WormholeAddress,
   WormholeNetwork,
 } from "./Contract";
-import {
-  ChainId,
-  SetValidPeriodInstruction,
-} from "@pythnetwork/xc-governance-sdk";
 import { ethers } from "ethers";
+import { ChainName } from "../chains";
+import { SetValidPeriod } from "../governance_payload";
 
 export class EvmPythUpgradable implements Contract<EvmPythUpgradableState> {
   public type = ContractType.EvmPythUpgradable;
@@ -45,9 +43,9 @@ export class EvmPythUpgradable implements Contract<EvmPythUpgradableState> {
   }
 
   // get the chainId that identifies this contract
-  public async getChainId(): Promise<ChainId> {
+  public async getChain(): Promise<ChainName> {
     // FIXME: read from data sources
-    return 23;
+    return "polygon";
   }
 
   public async getState(): Promise<EvmPythUpgradableState> {
@@ -65,12 +63,12 @@ export class EvmPythUpgradable implements Contract<EvmPythUpgradableState> {
   public async sync(target: EvmPythUpgradableState): Promise<SyncOp[]> {
     const myState = await this.getState();
     const authority = await this.getAuthority();
-    const myChainId = await this.getChainId();
+    const myChainId = await this.getChain();
     const whInstructions = [];
 
     if (myState.validTimePeriod !== target.validTimePeriod) {
       whInstructions.push(
-        new SetValidPeriodInstruction(myChainId, BigInt(target.validTimePeriod))
+        new SetValidPeriod(myChainId, BigInt(target.validTimePeriod))
       );
     }
 

+ 1 - 1
governance/xc_admin/packages/xc_admin_common/src/governance_payload/ExecutePostedVaa.ts

@@ -1,4 +1,4 @@
-import { ChainId, ChainName } from "@certusone/wormhole-sdk";
+import { ChainName } from "../chains";
 import * as BufferLayout from "@solana/buffer-layout";
 import {
   PythGovernanceAction,

+ 2 - 2
governance/xc_admin/packages/xc_admin_common/src/governance_payload/GovernanceDataSourceTransfer.ts

@@ -5,7 +5,7 @@ import {
   PythGovernanceHeader,
 } from "./PythGovernanceAction";
 import * as BufferLayout from "@solana/buffer-layout";
-import { ChainName } from "@certusone/wormhole-sdk";
+import { ChainName } from "../chains";
 
 /**
  * Authorize transferring the governance data source from the sender's emitter address to another emitter.
@@ -53,7 +53,7 @@ export class AuthorizeGovernanceDataSourceTransfer
 export class RequestGovernanceDataSourceTransfer extends PythGovernanceActionImpl {
   static layout: BufferLayout.Structure<
     Readonly<{ governanceDataSourceIndex: number }>
-  > = BufferLayout.struct([BufferLayout.u32be()]);
+  > = BufferLayout.struct([BufferLayout.u32be("governanceDataSourceIndex")]);
 
   constructor(
     targetChainId: ChainName,

+ 4 - 6
governance/xc_admin/packages/xc_admin_common/src/governance_payload/PythGovernanceAction.ts

@@ -1,9 +1,4 @@
-import {
-  ChainId,
-  ChainName,
-  toChainId,
-  toChainName,
-} from "@certusone/wormhole-sdk";
+import { ChainId, ChainName, toChainId, toChainName } from "../chains";
 import * as BufferLayout from "@solana/buffer-layout";
 import { PACKET_DATA_SIZE } from "@solana/web3.js";
 
@@ -19,6 +14,7 @@ export const TargetAction = {
   SetFee: 3,
   SetValidPeriod: 4,
   RequestGovernanceDataSourceTransfer: 5,
+  SetWormholeAddress: 6,
 } as const;
 
 /** Helper to get the ActionName from a (moduleId, actionId) tuple*/
@@ -41,6 +37,8 @@ export function toActionName(
         return "SetValidPeriod";
       case 5:
         return "RequestGovernanceDataSourceTransfer";
+      case 6:
+        return "SetWormholeAddress";
     }
   }
   return undefined;

+ 1 - 1
governance/xc_admin/packages/xc_admin_common/src/governance_payload/SetDataSources.ts

@@ -4,7 +4,7 @@ import {
   PythGovernanceActionImpl,
   PythGovernanceHeader,
 } from "./PythGovernanceAction";
-import { ChainName } from "@certusone/wormhole-sdk";
+import { ChainName } from "../chains";
 import * as BufferLayout from "@solana/buffer-layout";
 import * as BufferLayoutExt from "./BufferLayoutExt";
 

+ 1 - 1
governance/xc_admin/packages/xc_admin_common/src/governance_payload/SetFee.ts

@@ -1,7 +1,7 @@
 import { PythGovernanceActionImpl } from "./PythGovernanceAction";
 import * as BufferLayout from "@solana/buffer-layout";
 import * as BufferLayoutExt from "./BufferLayoutExt";
-import { ChainName } from "@certusone/wormhole-sdk";
+import { ChainName } from "../chains";
 
 /** Set the fee on the target chain to newFeeValue * 10^newFeeExpo */
 export class SetFee extends PythGovernanceActionImpl {

+ 1 - 1
governance/xc_admin/packages/xc_admin_common/src/governance_payload/SetValidPeriod.ts

@@ -4,7 +4,7 @@ import {
 } from "./PythGovernanceAction";
 import * as BufferLayout from "@solana/buffer-layout";
 import * as BufferLayoutExt from "./BufferLayoutExt";
-import { ChainName } from "@certusone/wormhole-sdk";
+import { ChainName } from "../chains";
 
 /** Set the valid period (the default amount of time in which prices are considered fresh) to the provided value */
 export class SetValidPeriod extends PythGovernanceActionImpl {

+ 33 - 0
governance/xc_admin/packages/xc_admin_common/src/governance_payload/SetWormholeAddress.ts

@@ -0,0 +1,33 @@
+import { ChainName } from "../chains";
+import { PythGovernanceActionImpl } from "./PythGovernanceAction";
+import * as BufferLayout from "@solana/buffer-layout";
+import * as BufferLayoutExt from "./BufferLayoutExt";
+
+export class EvmSetWormholeAddress extends PythGovernanceActionImpl {
+  static layout: BufferLayout.Structure<Readonly<{ address: string }>> =
+    BufferLayout.struct([BufferLayoutExt.hexBytes(20, "address")]);
+
+  constructor(targetChainId: ChainName, readonly address: string) {
+    super(targetChainId, "SetWormholeAddress");
+  }
+
+  static decode(data: Buffer): EvmSetWormholeAddress | undefined {
+    const decoded = PythGovernanceActionImpl.decodeWithPayload(
+      data,
+      "SetWormholeAddress",
+      this.layout
+    );
+    if (!decoded) return undefined;
+
+    return new EvmSetWormholeAddress(
+      decoded[0].targetChainId,
+      decoded[1].address
+    );
+  }
+
+  encode(): Buffer {
+    return super.encodeWithPayload(EvmSetWormholeAddress.layout, {
+      address: this.address,
+    });
+  }
+}

+ 30 - 1
governance/xc_admin/packages/xc_admin_common/src/governance_payload/UpgradeContract.ts

@@ -1,4 +1,4 @@
-import { ChainName } from "@certusone/wormhole-sdk";
+import { ChainName } from "../chains";
 import { PythGovernanceActionImpl } from "./PythGovernanceAction";
 import * as BufferLayout from "@solana/buffer-layout";
 import * as BufferLayoutExt from "./BufferLayoutExt";
@@ -63,6 +63,35 @@ export class AptosAuthorizeUpgradeContract extends PythGovernanceActionImpl {
   }
 }
 
+export class SuiAuthorizeUpgradeContract extends PythGovernanceActionImpl {
+  static layout: BufferLayout.Structure<Readonly<{ hash: string }>> =
+    BufferLayout.struct([BufferLayoutExt.hexBytes(32, "hash")]);
+
+  constructor(targetChainId: ChainName, readonly hash: string) {
+    super(targetChainId, "UpgradeContract");
+  }
+
+  static decode(data: Buffer): SuiAuthorizeUpgradeContract | undefined {
+    const decoded = PythGovernanceActionImpl.decodeWithPayload(
+      data,
+      "UpgradeContract",
+      this.layout
+    );
+    if (!decoded) return undefined;
+
+    return new SuiAuthorizeUpgradeContract(
+      decoded[0].targetChainId,
+      decoded[1].hash
+    );
+  }
+
+  encode(): Buffer {
+    return super.encodeWithPayload(SuiAuthorizeUpgradeContract.layout, {
+      hash: this.hash,
+    });
+  }
+}
+
 export class EvmUpgradeContract extends PythGovernanceActionImpl {
   static layout: BufferLayout.Structure<Readonly<{ address: string }>> =
     BufferLayout.struct([BufferLayoutExt.hexBytes(20, "address")]);

+ 10 - 0
governance/xc_admin/packages/xc_admin_common/src/governance_payload/index.ts

@@ -15,6 +15,7 @@ import {
 import { SetDataSources } from "./SetDataSources";
 import { SetValidPeriod } from "./SetValidPeriod";
 import { SetFee } from "./SetFee";
+import { EvmSetWormholeAddress } from "./SetWormholeAddress";
 
 /** Decode a governance payload */
 export function decodeGovernancePayload(
@@ -50,6 +51,8 @@ export function decodeGovernancePayload(
       return SetValidPeriod.decode(data);
     case "RequestGovernanceDataSourceTransfer":
       return RequestGovernanceDataSourceTransfer.decode(data);
+    case "SetWormholeAddress":
+      return EvmSetWormholeAddress.decode(data);
     default:
       return undefined;
   }
@@ -57,3 +60,10 @@ export function decodeGovernancePayload(
 
 export { ExecutePostedVaa } from "./ExecutePostedVaa";
 export * from "./PythGovernanceAction";
+export * from "./UpgradeContract";
+export * from "./PythGovernanceAction";
+export * from "./GovernanceDataSourceTransfer";
+export * from "./SetDataSources";
+export * from "./SetValidPeriod";
+export * from "./SetFee";
+export * from "./SetWormholeAddress";

+ 1 - 0
governance/xc_admin/packages/xc_admin_common/src/index.ts

@@ -11,3 +11,4 @@ export * from "./cranks";
 export * from "./message_buffer";
 export * from "./contracts";
 export * from "./executor";
+export * from "./chains";

+ 1 - 1
governance/xc_admin/packages/xc_admin_frontend/Dockerfile

@@ -9,7 +9,7 @@ USER 1000
 COPY --chown=1000:1000 governance/xc_admin governance/xc_admin
 COPY --chown=1000:1000 pythnet/message_buffer pythnet/message_buffer
 COPY --chown=1000:1000 target_chains/ethereum/sdk/solidity target_chains/ethereum/sdk/solidity
-COPY --chown=1000:1000 governance/xc_governance_sdk_js governance/xc_governance_sdk_js
+COPY --chown=1000:1000 governance/xc_admin/packages/xc_admin_common governance/xc_admin/packages/xc_admin_common
 
 ENV NODE_ENV production
 ENV NEXT_TELEMETRY_DISABLED 1

+ 0 - 11
governance/xc_governance_sdk_js/.eslintrc.js

@@ -1,11 +0,0 @@
-module.exports = {
-  root: true,
-  parser: "@typescript-eslint/parser",
-  plugins: ["@typescript-eslint"],
-  extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
-  rules: {
-    "@typescript-eslint/no-explicit-any": "off",
-    "@typescript-eslint/no-non-null-assertion": "off",
-    "@typescript-eslint/no-empty-function": "off",
-  },
-};

+ 0 - 3
governance/xc_governance_sdk_js/.gitignore

@@ -1,3 +0,0 @@
-node_modules
-lib
-.dccache

+ 0 - 201
governance/xc_governance_sdk_js/LICENSE

@@ -1,201 +0,0 @@
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [2021] [Pyth Data Foundation]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.

+ 0 - 5
governance/xc_governance_sdk_js/jest.config.js

@@ -1,5 +0,0 @@
-/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
-module.exports = {
-  preset: "ts-jest",
-  testEnvironment: "node",
-};

+ 0 - 42
governance/xc_governance_sdk_js/package.json

@@ -1,42 +0,0 @@
-{
-  "name": "@pythnetwork/xc-governance-sdk",
-  "version": "0.4.0",
-  "description": "Pyth Cross-chain Governance SDK",
-  "private": "true",
-  "homepage": "https://pyth.network",
-  "main": "lib/index.js",
-  "types": "lib/index.d.ts",
-  "files": [
-    "lib/**/*"
-  ],
-  "repository": "https://github.com/pyth-network/pyth-crosschain/",
-  "scripts": {
-    "test": "jest src/ --passWithNoTests",
-    "build": "tsc",
-    "format": "prettier --write \"src/**/*.ts\"",
-    "lint": "eslint src/",
-    "prepublishOnly": "npm run build && npm test && npm run lint",
-    "preversion": "npm run lint",
-    "version": "npm run format && git add -A src"
-  },
-  "keywords": [
-    "pyth",
-    "oracle"
-  ],
-  "license": "Apache-2.0",
-  "devDependencies": {
-    "@types/jest": "^28.0.8",
-    "@typescript-eslint/eslint-plugin": "^5.36.2",
-    "@typescript-eslint/parser": "^5.36.2",
-    "eslint": "^8.23.0",
-    "jest": "^28.0.8",
-    "prettier": "^2.7.1",
-    "ts-jest": "^28.0.8",
-    "ts-node": "^10.9.1",
-    "typescript": "^4.8.3"
-  },
-  "dependencies": {
-    "@certusone/wormhole-sdk": "^0.6.2",
-    "ethers": "^5.7.0"
-  }
-}

+ 0 - 24
governance/xc_governance_sdk_js/src/index.ts

@@ -1,24 +0,0 @@
-export {
-  DataSource,
-  AptosAuthorizeUpgradeContractInstruction,
-  SuiAuthorizeUpgradeContractInstruction,
-  EthereumUpgradeContractInstruction,
-  EthereumSetWormholeAddress,
-  HexString20Bytes,
-  HexString32Bytes,
-  SetDataSourcesInstruction,
-  SetFeeInstruction,
-  SetValidPeriodInstruction,
-  RequestGovernanceDataSourceTransferInstruction,
-  AuthorizeGovernanceDataSourceTransferInstruction,
-  CosmwasmUpgradeContractInstruction,
-  Instruction,
-} from "./instructions";
-
-export {
-  WORMHOLE_CHAINS,
-  RECEIVER_CHAINS,
-  CHAINS,
-  ChainId,
-  ChainName,
-} from "./chains";

+ 0 - 217
governance/xc_governance_sdk_js/src/instructions.ts

@@ -1,217 +0,0 @@
-import { ChainId } from "./chains";
-
-import { Serializable, BufferBuilder } from "./serialize";
-
-enum Module {
-  Executor = 0,
-  Target,
-}
-
-enum TargetAction {
-  UpgradeContract = 0,
-  AuthorizeGovernanceDataSourceTransfer,
-  SetDataSources,
-  SetFee,
-  SetValidPeriod,
-  RequestGovernanceDataSourceTransfer,
-  SetWormholeAddress,
-}
-
-abstract class HexString implements Serializable {
-  private readonly addressBuffer: Buffer;
-
-  constructor(address: string, byteLen: number) {
-    if (address.startsWith("0x")) {
-      address = address.substring(2);
-    }
-    if (address.length !== 2 * byteLen) {
-      throw new Error(
-        `Expected address of length ${2 * byteLen}, found ${address.length}`
-      );
-    }
-    this.addressBuffer = Buffer.from(address, "hex");
-    if (this.addressBuffer.length === 0) {
-      throw new Error(`Given address is not in hex format`);
-    }
-  }
-
-  serialize(): Buffer {
-    return this.addressBuffer;
-  }
-}
-
-export class HexString20Bytes extends HexString {
-  constructor(address: string) {
-    super(address, 20);
-  }
-}
-
-export class HexString32Bytes extends HexString {
-  constructor(address: string) {
-    super(address, 32);
-  }
-}
-
-export class DataSource implements Serializable {
-  constructor(
-    private readonly emitterChain: ChainId,
-    private readonly emitterAddress: HexString32Bytes
-  ) {}
-
-  serialize(): Buffer {
-    return new BufferBuilder()
-      .addUint16(Number(this.emitterChain))
-      .addObject(this.emitterAddress)
-      .build();
-  }
-}
-
-// Magic is `PTGM` encoded as a 4 byte data: Pyth Governance Message
-const MAGIC = 0x5054474d;
-
-export abstract class Instruction implements Serializable {
-  constructor(
-    private module: Module,
-    private action: number,
-    private targetChainId: ChainId
-  ) {}
-
-  protected abstract serializePayload(): Buffer;
-
-  private serializeHeader(): Buffer {
-    return new BufferBuilder()
-      .addUint32(MAGIC)
-      .addUint8(this.module)
-      .addUint8(this.action)
-      .addUint16(Number(this.targetChainId))
-      .build();
-  }
-
-  public serialize(): Buffer {
-    return new BufferBuilder()
-      .addBuffer(this.serializeHeader())
-      .addBuffer(this.serializePayload())
-      .build();
-  }
-}
-
-abstract class TargetInstruction extends Instruction {
-  constructor(action: TargetAction, targetChainId: ChainId) {
-    super(Module.Target, Number(action), targetChainId);
-  }
-}
-
-export class AptosAuthorizeUpgradeContractInstruction extends TargetInstruction {
-  constructor(targetChainId: ChainId, private hash: HexString32Bytes) {
-    super(TargetAction.UpgradeContract, targetChainId);
-  }
-
-  protected serializePayload(): Buffer {
-    return this.hash.serialize();
-  }
-}
-
-export class SuiAuthorizeUpgradeContractInstruction extends TargetInstruction {
-  constructor(targetChainId: ChainId, private digest: HexString32Bytes) {
-    super(TargetAction.UpgradeContract, targetChainId);
-  }
-
-  protected serializePayload(): Buffer {
-    return this.digest.serialize();
-  }
-}
-
-export class EthereumUpgradeContractInstruction extends TargetInstruction {
-  constructor(targetChainId: ChainId, private address: HexString20Bytes) {
-    super(TargetAction.UpgradeContract, targetChainId);
-  }
-
-  protected serializePayload(): Buffer {
-    return this.address.serialize();
-  }
-}
-
-export class CosmwasmUpgradeContractInstruction extends TargetInstruction {
-  constructor(targetChainId: ChainId, private codeId: bigint) {
-    super(TargetAction.UpgradeContract, targetChainId);
-  }
-
-  protected serializePayload(): Buffer {
-    return new BufferBuilder().addBigUint64(this.codeId).build();
-  }
-}
-
-export class AuthorizeGovernanceDataSourceTransferInstruction extends TargetInstruction {
-  constructor(targetChainId: ChainId, private claimVaa: Buffer) {
-    super(TargetAction.AuthorizeGovernanceDataSourceTransfer, targetChainId);
-  }
-
-  protected serializePayload(): Buffer {
-    return this.claimVaa;
-  }
-}
-
-export class SetDataSourcesInstruction extends TargetInstruction {
-  constructor(targetChainId: ChainId, private dataSources: DataSource[]) {
-    super(TargetAction.SetDataSources, targetChainId);
-  }
-
-  protected serializePayload(): Buffer {
-    const builder = new BufferBuilder();
-    builder.addUint8(this.dataSources.length);
-    this.dataSources.forEach((datasource) => builder.addObject(datasource));
-    return builder.build();
-  }
-}
-
-export class SetFeeInstruction extends TargetInstruction {
-  constructor(
-    targetChainId: ChainId,
-    private newFeeValue: bigint,
-    private newFeeExpo: bigint
-  ) {
-    super(TargetAction.SetFee, targetChainId);
-  }
-
-  protected serializePayload(): Buffer {
-    return new BufferBuilder()
-      .addBigUint64(this.newFeeValue)
-      .addBigUint64(this.newFeeExpo)
-      .build();
-  }
-}
-
-export class SetValidPeriodInstruction extends TargetInstruction {
-  constructor(targetChainId: ChainId, private newValidPeriod: bigint) {
-    super(TargetAction.SetValidPeriod, targetChainId);
-  }
-
-  protected serializePayload(): Buffer {
-    return new BufferBuilder().addBigUint64(this.newValidPeriod).build();
-  }
-}
-
-export class RequestGovernanceDataSourceTransferInstruction extends TargetInstruction {
-  constructor(
-    targetChainId: ChainId,
-    private governanceDataSourceIndex: number
-  ) {
-    super(TargetAction.RequestGovernanceDataSourceTransfer, targetChainId);
-  }
-
-  protected serializePayload(): Buffer {
-    return new BufferBuilder()
-      .addUint32(this.governanceDataSourceIndex)
-      .build();
-  }
-}
-
-export class EthereumSetWormholeAddress extends TargetInstruction {
-  constructor(targetChainId: ChainId, private address: HexString20Bytes) {
-    super(TargetAction.SetWormholeAddress, targetChainId);
-  }
-
-  protected serializePayload(): Buffer {
-    return this.address.serialize();
-  }
-}

+ 0 - 63
governance/xc_governance_sdk_js/src/serialize.ts

@@ -1,63 +0,0 @@
-export interface Serializable {
-  serialize(): Buffer;
-}
-
-export class BufferBuilder {
-  private items: Buffer[];
-
-  constructor() {
-    this.items = [];
-  }
-
-  addUint8(value: number): BufferBuilder {
-    const buffer = Buffer.alloc(1);
-    buffer.writeUint8(value);
-    this.items.push(buffer);
-    return this;
-  }
-
-  addUint16(value: number): BufferBuilder {
-    const buffer = Buffer.alloc(2);
-    buffer.writeUint16BE(value);
-    this.items.push(buffer);
-    return this;
-  }
-
-  addUint32(value: number): BufferBuilder {
-    const buffer = Buffer.alloc(4);
-    buffer.writeUint32BE(value);
-    this.items.push(buffer);
-    return this;
-  }
-
-  addBigUint64(value: bigint): BufferBuilder {
-    const buffer = Buffer.alloc(8);
-    buffer.writeBigInt64BE(value);
-    this.items.push(buffer);
-    return this;
-  }
-
-  addObject(obj: Serializable): BufferBuilder {
-    this.items.push(obj.serialize());
-    return this;
-  }
-
-  addBuffer(buffer: Buffer): BufferBuilder {
-    this.items.push(buffer);
-    return this;
-  }
-
-  build(): Buffer {
-    const totalLength = this.items.reduce((prev, cur) => prev + cur.length, 0);
-
-    const result = Buffer.alloc(totalLength);
-
-    let offset = 0;
-    for (const arr of this.items) {
-      result.set(arr, offset);
-      offset += arr.length;
-    }
-
-    return result;
-  }
-}

+ 0 - 9
governance/xc_governance_sdk_js/tsconfig.json

@@ -1,9 +0,0 @@
-{
-  "extends": "../../tsconfig.base.json",
-  "include": ["src"],
-  "exclude": ["node_modules", "**/__tests__/*"],
-  "compilerOptions": {
-    "rootDir": "src/",
-    "outDir": "./lib"
-  }
-}

File diff suppressed because it is too large
+ 1168 - 1452
package-lock.json


+ 0 - 1
package.json

@@ -2,7 +2,6 @@
   "name": "root",
   "workspaces": [
     "governance/xc_admin/packages/*",
-    "governance/xc_governance_sdk_js",
     "governance/multisig_wh_message_builder",
     "price_pusher",
     "price_service/server",

+ 1 - 1
target_chains/cosmwasm/tools/package.json

@@ -19,7 +19,7 @@
     "@injectivelabs/networks": "1.0.68",
     "@injectivelabs/sdk-ts": "1.0.354",
     "@ltd/j-toml": "^1.38.0",
-    "@pythnetwork/xc-governance-sdk": "*",
+    "xc_admin_common": "*",
     "@terra-money/terra.js": "^3.1.3",
     "adm-zip": "^0.5.10",
     "chain-registry": "^1.6.0",

+ 2 - 2
target_chains/cosmwasm/tools/src/chains-manager/chains.ts

@@ -93,8 +93,8 @@ export const CHAINS_NETWORK_CONFIG: Record<ChainId, ChainNetworkConfig> = {
   [ChainId.NEUTRON_TESTNET_PION_1]: {
     chainId: ChainId.NEUTRON_TESTNET_PION_1,
     chainType: ChainType.COSMWASM,
-    executorEndpoint: "https://rpc.pion.rs-testnet.polypore.xyz/",
-    querierEndpoint: "https://rpc.pion.rs-testnet.polypore.xyz/",
+    executorEndpoint: "https://rpc-palvus.pion-1.ntrn.tech/",
+    querierEndpoint: "https://rpc-palvus.pion-1.ntrn.tech/",
     prefix: "neutron",
     gasPrice: "0.025untrn",
   },

+ 1 - 1
target_chains/cosmwasm/tools/src/configs.ts

@@ -1,4 +1,4 @@
-import { CHAINS } from "@pythnetwork/xc-governance-sdk";
+import { CHAINS } from "xc_admin_common";
 import { ChainId } from "./chains-manager/chains";
 import { DeploymentType } from "./helper";
 

+ 5 - 5
target_chains/cosmwasm/tools/store/edge/instantiate-pyth/neutron_testnet_pion_1-1.2.0.json

@@ -2,21 +2,21 @@
   "deploy-pyth-code": {
     "status": "fulfilled",
     "result": {
-      "codeId": 473,
-      "txHash": "73EFB113F0AA5D4C7DC98E96F1452E5DCC1C8C43F335CADEB7351777F0D7F7F1"
+      "codeId": 1175,
+      "txHash": "5A9961A345856E14C2F42D04A881BEF1678A90DEDCC5C9F7B87EE2F6CAA7CA0C"
     }
   },
   "instantiate-contract": {
     "status": "fulfilled",
     "result": {
-      "contractAddr": "neutron1xxmcu6wxgawjlajx8jalyk9cxsudnygjg0tvjesfyurh4utvtpes5wmpjp",
-      "txHash": "CD0D6CB6C80757DB1CBC6B4FF3E1C7526DFD4F8877743A04EB77B5848195D3FF"
+      "contractAddr": "neutron16zwrmx3zgggmxhzau86xfycm42cr4sj888hdvzsxya3qarp6zhhqzhlkvz",
+      "txHash": "1B483BFC11C7D155167E8BAB1D4083B685B69E3A7667CA541C9AE7B9F8C8611B"
     }
   },
   "set-own-admin": {
     "status": "fulfilled",
     "result": {
-      "txHash": "B26BCEB73B826C797B78BE1E1AD35BC23752E3E670E106A396CD1D1648089304"
+      "txHash": "5E160580E230DA5ADD0576ACFDEA02FD0776E272AB84E0AE4C520DD8E5CF70C5"
     }
   }
 }

+ 7 - 7
target_chains/cosmwasm/tools/store/edge/test-contracts/neutron_testnet_pion_1-1.2.0.json

@@ -2,7 +2,7 @@
   "push-price-update": {
     "status": "fulfilled",
     "result": {
-      "txHash": "20B98E3DD44B950E390303281A862734C4DB4BC5252588B02DB7BD0652637E51"
+      "txHash": "ECA134B6CB6C9240AA80B49CF15C8215CA08949C3F68B7720D7E8B9B8E998E41"
     }
   },
   "fetch-price-feed-update": {
@@ -11,16 +11,16 @@
       "price_feed": {
         "id": "f9c0172ba10dfa4d19088d94f5bf61d3b54d5bd7483a322a982e1373ee8ea31b",
         "price": {
-          "price": "2628800000000",
-          "conf": "988214743",
+          "price": "3012903119923",
+          "conf": "722024077",
           "expo": -8,
-          "publish_time": 1684939947
+          "publish_time": 1689590826
         },
         "ema_price": {
-          "price": "2646641040000",
-          "conf": "828376020",
+          "price": "3017327600000",
+          "conf": "741279200",
           "expo": -8,
-          "publish_time": 1684939947
+          "publish_time": 1689590826
         }
       }
     }

+ 5 - 5
target_chains/cosmwasm/tools/store/stable/instantiate-pyth/neutron_testnet_pion_1-1.2.0.json

@@ -2,21 +2,21 @@
   "deploy-pyth-code": {
     "status": "fulfilled",
     "result": {
-      "codeId": 472,
-      "txHash": "00A7125012E7B5ECE6DB5938DC177B37A37C0AEC42B08D3D5A7B3CC9C1A2161D"
+      "codeId": 1176,
+      "txHash": "E71CB5A163B58222D0458F4C661369D00190C81FF6BBF0C6A5442CE5E8558235"
     }
   },
   "instantiate-contract": {
     "status": "fulfilled",
     "result": {
-      "contractAddr": "neutron1f86ct5az9qpz2hqfd5uxru02px2a3tz5zkw7hugd7acqq496dcms22ehpy",
-      "txHash": "3DEBFABE0AFB4BB2F9C40427DB2E2C91BC4F5BC34324FD3E3962158063BFB88D"
+      "contractAddr": "neutron15ldst8t80982akgr8w8ekcytejzkmfpgdkeq4xgtge48qs7435jqp87u3t",
+      "txHash": "EA0B91043F0281D4A4E58D9749C109304BEC3C5A309E70C3918F5C0F8951A079"
     }
   },
   "set-own-admin": {
     "status": "fulfilled",
     "result": {
-      "txHash": "5D4E120C11134B610DD15BD3C32F834300D4662358E10BBABD9907961E34DFF1"
+      "txHash": "572A32BCFF99FB5A83DD5B50A77A20214FA54064F2D4FEA3BD8E70F8372FEA02"
     }
   }
 }

+ 7 - 7
target_chains/cosmwasm/tools/store/stable/test-contracts/neutron_testnet_pion_1-1.2.0.json

@@ -2,7 +2,7 @@
   "push-price-update": {
     "status": "fulfilled",
     "result": {
-      "txHash": "C236ECE2ACA96AE4325AB02C7FCF7BFE5974C3B2D4BF52903FB4F483F1CA5970"
+      "txHash": "0747A3C2A608C154B291BB11C621E1C7C3F30A1356FAA051E138659471765F4E"
     }
   },
   "fetch-price-feed-update": {
@@ -11,16 +11,16 @@
       "price_feed": {
         "id": "e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43",
         "price": {
-          "price": "2630007893200",
-          "conf": "1119111601",
+          "price": "3015369873290",
+          "conf": "941626709",
           "expo": -8,
-          "publish_time": 1684939862
+          "publish_time": 1689590919
         },
         "ema_price": {
-          "price": "2648559910000",
-          "conf": "802705780",
+          "price": "3017698600000",
+          "conf": "899541390",
           "expo": -8,
-          "publish_time": 1684939862
+          "publish_time": 1689590919
         }
       }
     }

+ 1 - 1
target_chains/ethereum/contracts/.env.template

@@ -8,7 +8,7 @@ MIGRATIONS_NETWORK=         # xyz
 # This value should derive from Pyth to wormhole latency, and target chain blocktime and latency.
 VALID_TIME_PERIOD_SECONDS= # 60
 
-WORMHOLE_CHAIN_NAME= # ethereum, defined in <repo-root>/third_party/pyth/xc_governance_sdk_js/src/chains.ts
+WORMHOLE_CHAIN_NAME= # ethereum, defined in <repo-root>/governance/xc_admin/packages/xc_admin_common/src/chains.ts
 
 CLUSTER= #mainnet/testnet The configs below are read from the cluster file
 

+ 2 - 2
target_chains/ethereum/contracts/Deploying.md

@@ -26,7 +26,7 @@ Each network that Pyth is deployed on has some configuration stored on this repo
    - `MIGRATIONS_NETWORK`: Network name in the [`truffle-config.js`](./truffle-config.js) file.
    - `WORMHOLE_CHAIN_NAME`: Chain name in Wormhole. It is either defined in the
      [Wormhole SDK constants](https://github.com/wormhole-foundation/wormhole/blob/dev.v2/sdk/js/src/utils/consts.ts)
-     or is defined in [Wormhole Receiver names](../../../governance/xc_governance_sdk_js/src/chains.ts). If the new
+     or is defined in [Wormhole Receiver names](../../../governance/xc_admin/packages/xc_admin_common/src/chains.ts). If the new
      network requires a Receiver contract you need to update the latter file and add the network there.
    - `CLUSTER`: Cluster of this network. It is either `testnet` or `mainnet`. There are some cluster specific
      configuration that are loaded from [`.env.cluster.testnet`](./.env.cluster.testnet) or
@@ -69,7 +69,7 @@ This is the deployment process:
 5. Make sure the deployment account has proper balance on this network and top it up if needed. Search
    for testnet faucets if it is a testnet network. Sometimes you need to bridge the network token (e.g., L2s).
 6. Deploy the new contract or changes using the [`deploy.sh`](./deploy.sh) script. If you have made changes
-   to [`chains.ts`](../../../governance/xc_governance_sdk_js/src/chains.ts), please make sure to
+   to [`chains.ts`](../../../governance/xc_admin/packages/xc_admin_common/src/chains.ts), please make sure to
    run `npx lerna run build --scope="@pythnetwork/pyth-evm-contract" --include-dependencies` in the
    root directory before running the deployment script.
    You might need to repeat this script because of busy RPCs. Repeating would not cause any problem even

+ 1 - 1
target_chains/ethereum/contracts/deploy/zkSyncDeploy.ts

@@ -2,7 +2,7 @@ import { utils, Wallet } from "zksync-web3";
 import { HardhatRuntimeEnvironment } from "hardhat/types";
 import { Deployer } from "@matterlabs/hardhat-zksync-deploy";
 import loadEnv from "../scripts/loadEnv";
-import { CHAINS } from "@pythnetwork/xc-governance-sdk";
+import { CHAINS } from "xc_admin_common";
 import { assert } from "chai";
 import { writeFileSync } from "fs";
 

+ 0 - 1
target_chains/ethereum/contracts/deploy/zkSyncDeployNewPythImpl.ts

@@ -2,7 +2,6 @@ import { utils, Wallet } from "zksync-web3";
 import { HardhatRuntimeEnvironment } from "hardhat/types";
 import { Deployer } from "@matterlabs/hardhat-zksync-deploy";
 import loadEnv from "../scripts/loadEnv";
-import { CHAINS } from "@pythnetwork/xc-governance-sdk";
 import { assert } from "chai";
 import { writeFileSync } from "fs";
 import { ethers } from "ethers";

+ 1 - 1
target_chains/ethereum/contracts/migrations/prod-receiver/2_deploy_wormhole_receiver.js

@@ -2,7 +2,7 @@ const loadEnv = require("../../scripts/loadEnv");
 loadEnv("../../");
 
 const tdr = require("truffle-deploy-registry");
-const governance = require("@pythnetwork/xc-governance-sdk");
+const governance = require("xc_admin_common");
 const { assert } = require("chai");
 
 const ReceiverSetup = artifacts.require("ReceiverSetup");

+ 1 - 1
target_chains/ethereum/contracts/package.json

@@ -34,7 +34,7 @@
     "@openzeppelin/hardhat-upgrades": "^1.22.1",
     "@pythnetwork/pyth-multisig-wh-message-builder": "*",
     "@pythnetwork/pyth-sdk-solidity": "^2.2.0",
-    "@pythnetwork/xc-governance-sdk": "*",
+    "xc_admin_common": "*",
     "dotenv": "^10.0.0",
     "elliptic": "^6.5.2",
     "ethers": "^5.7.2",

+ 18 - 21
target_chains/ethereum/contracts/scripts/syncPythState.js

@@ -11,7 +11,7 @@
  * the previous step in the next run.
  */
 
-const governance = require("@pythnetwork/xc-governance-sdk");
+const governance = require("xc_admin_common");
 const wormhole = require("@certusone/wormhole-sdk");
 const assertVaaPayloadEquals = require("./assertVaaPayloadEquals");
 const { assert } = require("chai");
@@ -233,10 +233,10 @@ async function upgradeContract(proxy, desiredVersion) {
     newImplementationAddress = newImplementation.address;
   }
 
-  const upgradePayload = new governance.EthereumUpgradeContractInstruction(
-    governance.CHAINS[chainName],
-    new governance.HexString20Bytes(newImplementationAddress)
-  ).serialize();
+  const upgradePayload = new governance.EvmUpgradeContract(
+    chainName,
+    newImplementationAddress.replace("0x", "")
+  ).encode();
 
   const upgradePayloadHex = upgradePayload.toString("hex");
 
@@ -277,11 +277,11 @@ async function syncUpdateFee(proxy) {
         `desired update fee: ${desiredUpdateFee}. Updating...`
     );
 
-    const setFeePayload = new governance.SetFeeInstruction(
-      governance.CHAINS[chainName],
+    const setFeePayload = new governance.SetFee(
+      chainName,
       BigInt(desiredUpdateFee),
       BigInt(0)
-    ).serialize();
+    ).encode();
 
     await createAndExecuteVaaFromPayloadThroughMultiSig(proxy, setFeePayload);
 
@@ -308,10 +308,10 @@ async function syncValidTimePeriod(proxy) {
         `desired valid time period: ${desiredValidTimePeriod}s. Updating...`
     );
 
-    const setValidPeriodPayload = new governance.SetValidPeriodInstruction(
-      governance.CHAINS[chainName],
+    const setValidPeriodPayload = new governance.SetValidPeriod(
+      chainName,
       BigInt(desiredValidTimePeriod)
-    ).serialize();
+    ).encode();
 
     await createAndExecuteVaaFromPayloadThroughMultiSig(
       proxy,
@@ -357,16 +357,13 @@ async function syncDataSources(proxy) {
 
     // Usually this change is universal, so the Payload is generated for all
     // the chains.
-    const setDataSourcesPayload = new governance.SetDataSourcesInstruction(
-      governance.CHAINS[chainName],
-      Array.from(desiredDataSources).map(
-        (ds) =>
-          new governance.DataSource(
-            Number(ds[0]),
-            new governance.HexString32Bytes(ds[1])
-          )
-      )
-    ).serialize();
+    const setDataSourcesPayload = new governance.SetDataSources(
+      chainName,
+      Array.from(desiredDataSources).map((ds) => ({
+        emitterChain: Number(ds[0]),
+        emitterAddress: ds[1].replace("0x", ""),
+      }))
+    ).encode();
     await createAndExecuteVaaFromPayloadThroughMultiSig(
       proxy,
       setDataSourcesPayload

+ 68 - 95
target_chains/ethereum/contracts/test/pyth.js

@@ -1,5 +1,5 @@
 const elliptic = require("elliptic");
-const governance = require("@pythnetwork/xc-governance-sdk");
+const governance = require("xc_admin_common");
 
 const { deployProxy, upgradeProxy } = require("@openzeppelin/truffle-upgrades");
 const {
@@ -8,6 +8,7 @@ const {
   time,
 } = require("@openzeppelin/test-helpers");
 const { assert, expect } = require("chai");
+const { EvmSetWormholeAddress } = require("xc_admin_common");
 
 // Use "WormholeReceiver" if you are testing with Wormhole Receiver
 const Setup = artifacts.require("Setup");
@@ -226,7 +227,7 @@ contract("Pyth", function () {
    * Create a governance instruction VAA from the Instruction object. Then
    * Submit and execute it on the contract.
    * @param contract Pyth contract
-   * @param {governance.Instruction} governanceInstruction
+   * @param {governance.PythGovernanceAction} governanceInstruction
    * @param {number} sequence
    */
   async function createAndThenSubmitGovernanceInstructionVaa(
@@ -236,7 +237,7 @@ contract("Pyth", function () {
   ) {
     await contract.executeGovernanceInstruction(
       await createVAAFromUint8Array(
-        governanceInstruction.serialize(),
+        governanceInstruction.encode(),
         testGovernanceChainId,
         testGovernanceEmitter,
         sequence
@@ -299,11 +300,7 @@ contract("Pyth", function () {
   async function setFeeTo(contract, newFee, governanceSequence) {
     await createAndThenSubmitGovernanceInstructionVaa(
       contract,
-      new governance.SetFeeInstruction(
-        governance.CHAINS.ethereum,
-        BigInt(newFee),
-        BigInt(0)
-      ),
+      new governance.SetFee("ethereum", BigInt(newFee), BigInt(0)),
       governanceSequence ?? 1
     );
   }
@@ -514,10 +511,7 @@ contract("Pyth", function () {
   ) {
     await createAndThenSubmitGovernanceInstructionVaa(
       contract,
-      new governance.SetValidPeriodInstruction(
-        governance.CHAINS.ethereum,
-        BigInt(newValidPeriod)
-      ),
+      new governance.SetValidPeriod("ethereum", BigInt(newValidPeriod)),
       governanceSequence ?? 1
     );
   }
@@ -606,10 +600,7 @@ contract("Pyth", function () {
   // Logics that apply to all governance messages
   it("Make sure invalid magic and module won't work", async function () {
     // First 4 bytes of data are magic and the second byte after that is module
-    const data = new governance.SetValidPeriodInstruction(
-      governance.CHAINS.ethereum,
-      BigInt(10)
-    ).serialize();
+    const data = new governance.SetValidPeriod("ethereum", BigInt(10)).encode();
 
     const wrongMagic = Buffer.from(data);
     wrongMagic[1] = 0;
@@ -658,10 +649,7 @@ contract("Pyth", function () {
   });
 
   it("Make sure governance with wrong sender won't work", async function () {
-    const data = new governance.SetValidPeriodInstruction(
-      governance.CHAINS.ethereum,
-      BigInt(10)
-    ).serialize();
+    const data = new governance.SetValidPeriod("ethereum", BigInt(10)).encode();
 
     const vaaWrongEmitter = await createVAAFromUint8Array(
       data,
@@ -689,10 +677,10 @@ contract("Pyth", function () {
   });
 
   it("Make sure governance with only target chain id and 0 work", async function () {
-    const wrongChainData = new governance.SetValidPeriodInstruction(
-      governance.CHAINS.solana,
+    const wrongChainData = new governance.SetValidPeriod(
+      "solana",
       BigInt(10)
-    ).serialize();
+    ).encode();
 
     const wrongChainVaa = await createVAAFromUint8Array(
       wrongChainData,
@@ -706,10 +694,10 @@ contract("Pyth", function () {
       "InvalidGovernanceTarget"
     );
 
-    const dataForAllChains = new governance.SetValidPeriodInstruction(
-      governance.CHAINS.unset,
+    const dataForAllChains = new governance.SetValidPeriod(
+      "unset",
       BigInt(10)
-    ).serialize();
+    ).encode();
 
     const vaaForAllChains = await createVAAFromUint8Array(
       dataForAllChains,
@@ -720,10 +708,10 @@ contract("Pyth", function () {
 
     await this.pythProxy.executeGovernanceInstruction(vaaForAllChains);
 
-    const dataForEth = new governance.SetValidPeriodInstruction(
-      governance.CHAINS.ethereum,
+    const dataForEth = new governance.SetValidPeriod(
+      "ethereum",
       BigInt(10)
-    ).serialize();
+    ).encode();
 
     const vaaForEth = await createVAAFromUint8Array(
       dataForEth,
@@ -736,10 +724,7 @@ contract("Pyth", function () {
   });
 
   it("Make sure that governance messages are executed in order and cannot be reused", async function () {
-    const data = new governance.SetValidPeriodInstruction(
-      governance.CHAINS.ethereum,
-      BigInt(10)
-    ).serialize();
+    const data = new governance.SetValidPeriod("ethereum", BigInt(10)).encode();
 
     const vaaSeq1 = await createVAAFromUint8Array(
       data,
@@ -778,10 +763,10 @@ contract("Pyth", function () {
   it("Upgrading the contract with chain id 0 is invalid", async function () {
     const newImplementation = await PythUpgradable.new();
 
-    const data = new governance.EthereumUpgradeContractInstruction(
-      governance.CHAINS.unset, // 0
-      new governance.HexString20Bytes(newImplementation.address)
-    ).serialize();
+    const data = new governance.EvmUpgradeContract(
+      "unset", // 0
+      newImplementation.address.replace("0x", "")
+    ).encode();
 
     const vaa = await createVAAFromUint8Array(
       data,
@@ -799,10 +784,10 @@ contract("Pyth", function () {
   it("Upgrading the contract should work", async function () {
     const newImplementation = await PythUpgradable.new();
 
-    const data = new governance.EthereumUpgradeContractInstruction(
-      governance.CHAINS.ethereum,
-      new governance.HexString20Bytes(newImplementation.address)
-    ).serialize();
+    const data = new governance.EvmUpgradeContract(
+      "ethereum",
+      newImplementation.address.replace("0x", "")
+    ).encode();
 
     const vaa = await createVAAFromUint8Array(
       data,
@@ -825,10 +810,10 @@ contract("Pyth", function () {
   it("Upgrading the contract to a non-pyth contract won't work", async function () {
     const newImplementation = await MockUpgradeableProxy.new();
 
-    const data = new governance.EthereumUpgradeContractInstruction(
-      governance.CHAINS.ethereum,
-      new governance.HexString20Bytes(newImplementation.address)
-    ).serialize();
+    const data = new governance.EvmUpgradeContract(
+      "ethereum",
+      newImplementation.address.replace("0x", "")
+    ).encode();
 
     const vaa = await createVAAFromUint8Array(
       data,
@@ -850,10 +835,7 @@ contract("Pyth", function () {
     const newEmitterChain = governance.CHAINS.acala;
 
     const claimInstructionData =
-      new governance.RequestGovernanceDataSourceTransferInstruction(
-        governance.CHAINS.unset,
-        1
-      ).serialize();
+      new governance.RequestGovernanceDataSourceTransfer("unset", 1).encode();
 
     const claimVaaHexString = await createVAAFromUint8Array(
       claimInstructionData,
@@ -869,11 +851,10 @@ contract("Pyth", function () {
 
     const claimVaa = Buffer.from(claimVaaHexString.substring(2), "hex");
 
-    const data =
-      new governance.AuthorizeGovernanceDataSourceTransferInstruction(
-        governance.CHAINS.unset,
-        claimVaa
-      ).serialize();
+    const data = new governance.AuthorizeGovernanceDataSourceTransfer(
+      "unset",
+      claimVaa
+    ).encode();
 
     const vaa = await createVAAFromUint8Array(
       data,
@@ -904,11 +885,10 @@ contract("Pyth", function () {
 
     // Make sure a claim vaa does not get executed
 
-    const claimLonely =
-      new governance.RequestGovernanceDataSourceTransferInstruction(
-        governance.CHAINS.unset,
-        2
-      ).serialize();
+    const claimLonely = new governance.RequestGovernanceDataSourceTransfer(
+      "unset",
+      2
+    ).encode();
 
     const claimLonelyVaa = await createVAAFromUint8Array(
       claimLonely,
@@ -927,10 +907,10 @@ contract("Pyth", function () {
 
     // A wrong vaa that does not move the governance index
     const transferBackClaimInstructionDataWrong =
-      new governance.RequestGovernanceDataSourceTransferInstruction(
-        governance.CHAINS.unset,
+      new governance.RequestGovernanceDataSourceTransfer(
+        "unset",
         1 // The same governance data source index => Should fail
-      ).serialize();
+      ).encode();
 
     const transferBackClaimVaaHexStringWrong = await createVAAFromUint8Array(
       transferBackClaimInstructionDataWrong,
@@ -945,10 +925,10 @@ contract("Pyth", function () {
     );
 
     const transferBackDataWrong =
-      new governance.AuthorizeGovernanceDataSourceTransferInstruction(
-        governance.CHAINS.unset,
+      new governance.AuthorizeGovernanceDataSourceTransfer(
+        "unset",
         transferBackClaimVaaWrong
-      ).serialize();
+      ).encode();
 
     const transferBackVaaWrong = await createVAAFromUint8Array(
       transferBackDataWrong,
@@ -964,17 +944,13 @@ contract("Pyth", function () {
   });
 
   it("Setting data sources should work", async function () {
-    const data = new governance.SetDataSourcesInstruction(
-      governance.CHAINS.ethereum,
-      [
-        new governance.DataSource(
-          governance.CHAINS.acala,
-          new governance.HexString32Bytes(
-            "0x0000000000000000000000000000000000000000000000000000000000001111"
-          )
-        ),
-      ]
-    ).serialize();
+    const data = new governance.SetDataSources("ethereum", [
+      {
+        emitterChain: governance.CHAINS.acala,
+        emitterAddress:
+          "0000000000000000000000000000000000000000000000000000000000001111",
+      },
+    ]).encode();
 
     const vaa = await createVAAFromUint8Array(
       data,
@@ -1020,11 +996,11 @@ contract("Pyth", function () {
   });
 
   it("Setting fee should work", async function () {
-    const data = new governance.SetFeeInstruction(
-      governance.CHAINS.ethereum,
+    const data = new governance.SetFee(
+      "ethereum",
       BigInt(5),
       BigInt(3) // 5*10**3 = 5000
-    ).serialize();
+    ).encode();
 
     const vaa = await createVAAFromUint8Array(
       data,
@@ -1053,10 +1029,7 @@ contract("Pyth", function () {
   });
 
   it("Setting valid period should work", async function () {
-    const data = new governance.SetValidPeriodInstruction(
-      governance.CHAINS.ethereum,
-      BigInt(0)
-    ).serialize();
+    const data = new governance.SetValidPeriod("ethereum", BigInt(0)).encode();
 
     const vaa = await createVAAFromUint8Array(
       data,
@@ -1098,10 +1071,10 @@ contract("Pyth", function () {
     const newWormhole = await Wormhole.new(newSetup.address, initData);
 
     // Creating the vaa to set the new wormhole address
-    const data = new governance.EthereumSetWormholeAddress(
-      governance.CHAINS.ethereum,
-      new governance.HexString20Bytes(newWormhole.address)
-    ).serialize();
+    const data = new governance.EvmSetWormholeAddress(
+      "ethereum",
+      newWormhole.address.replace("0x", "")
+    ).encode();
 
     const vaa = await createVAAFromUint8Array(
       data,
@@ -1146,10 +1119,10 @@ contract("Pyth", function () {
     );
 
     // Creating the vaa to set the new wormhole address
-    const data = new governance.EthereumSetWormholeAddress(
-      governance.CHAINS.ethereum,
-      new governance.HexString20Bytes(newWormholeReceiver.address)
-    ).serialize();
+    const data = new governance.EvmSetWormholeAddress(
+      "ethereum",
+      newWormholeReceiver.address.replace("0x", "")
+    ).encode();
 
     const vaa = await createVAAFromUint8Array(
       data,
@@ -1191,10 +1164,10 @@ contract("Pyth", function () {
     const newWormhole = await Wormhole.new(newSetup.address, initData);
 
     // Creating the vaa to set the new wormhole address
-    const data = new governance.EthereumSetWormholeAddress(
-      governance.CHAINS.ethereum,
-      new governance.HexString20Bytes(newWormhole.address)
-    ).serialize();
+    const data = new governance.EvmSetWormholeAddress(
+      "ethereum",
+      newWormhole.address.replace("0x", "")
+    ).encode();
 
     const wrongVaa = await createVAAFromUint8Array(
       data,

+ 1 - 1
tilt_devnet/docker_images/Dockerfile.cosmwasm

@@ -37,7 +37,7 @@ COPY --from=pyth_builder /code/artifacts/pyth_cosmwasm.wasm /home/node/target_ch
 
 WORKDIR /home/node/
 
-COPY --chown=1000:1000 governance/xc_governance_sdk_js governance/xc_governance_sdk_js
+COPY --chown=1000:1000 governance/xc_admin/packages/xc_admin_common/ governance/xc_admin/packages/xc_admin_common/
 COPY --chown=1000:1000 target_chains/cosmwasm/tools target_chains/cosmwasm/tools
 
 RUN npx lerna run build --scope="@pythnetwork/cosmwasm-deploy-tools" --include-dependencies

+ 1 - 1
tilt_devnet/docker_images/Dockerfile.ethereum

@@ -8,7 +8,7 @@ RUN apt-get update && apt-get install -y ncat
 USER 1000
 WORKDIR /home/node
 COPY --chown=1000:1000 governance/multisig_wh_message_builder governance/multisig_wh_message_builder
-COPY --chown=1000:1000 governance/xc_governance_sdk_js governance/xc_governance_sdk_js
+COPY --chown=1000:1000 governance/xc_admin/packages/xc_admin_common/ governance/xc_admin/packages/xc_admin_common/
 COPY --chown=1000:1000 target_chains/ethereum/sdk/solidity target_chains/ethereum/sdk/solidity
 COPY --chown=1000:1000 target_chains/ethereum/contracts target_chains/ethereum/contracts
 

Some files were not shown because too many files changed in this diff