Explorar o código

feat(xc-admin): add support for setMaxLatency instruction (#1328)

* Remove Substack link from SocialLinks component

* Update copyright year in Footer component

* fix useEffect dep

* add support for maxLatency

* update wallet interface

* fix

* fix

* revert import format

* fix

* fix

* fix

* fix

* update anchor to 0.29.0

* remove unneeded casts
Daniel Chew hai 1 ano
pai
achega
2bfbfed6ab

+ 1 - 0
contract_manager/package.json

@@ -21,6 +21,7 @@
     "url": "git+https://github.com/pyth-network/pyth-crosschain.git"
   },
   "dependencies": {
+    "@coral-xyz/anchor": "^0.29.0",
     "@certusone/wormhole-sdk": "^0.9.8",
     "@injectivelabs/networks": "1.0.68",
     "@mysten/sui.js": "^0.49.1",

+ 3 - 2
contract_manager/src/governance.ts

@@ -17,7 +17,8 @@ import {
   PythCluster,
 } from "@pythnetwork/client/lib/cluster";
 import SquadsMesh from "@sqds/mesh";
-import { AnchorProvider, Wallet } from "@coral-xyz/anchor/dist/cjs/provider";
+import { AnchorProvider } from "@coral-xyz/anchor";
+import { Wallet } from "@coral-xyz/anchor/dist/cjs/provider";
 import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet";
 import {
   executeProposal,
@@ -344,7 +345,7 @@ export class Vault extends Storable {
   ): Promise<WormholeMultisigProposal> {
     const squad = this.getSquadOrThrow();
     const multisigVault = new MultisigVault(
-      squad.wallet,
+      squad.wallet as Wallet,
       this.cluster,
       squad,
       this.key

+ 1 - 1
governance/xc_admin/packages/crank_executor/package.json

@@ -20,7 +20,7 @@
   },
   "dependencies": {
     "@certusone/wormhole-sdk": "^0.9.9",
-    "@coral-xyz/anchor": "^0.26.0",
+    "@coral-xyz/anchor": "^0.29.0",
     "@pythnetwork/client": "^2.9.0",
     "@solana/web3.js": "^1.73.0",
     "@sqds/mesh": "^1.0.6",

+ 1 - 1
governance/xc_admin/packages/crank_pythnet_relayer/package.json

@@ -20,7 +20,7 @@
   },
   "dependencies": {
     "@certusone/wormhole-sdk": "^0.9.9",
-    "@coral-xyz/anchor": "^0.26.0",
+    "@coral-xyz/anchor": "^0.29.0",
     "@pythnetwork/client": "^2.9.0",
     "@solana/web3.js": "^1.73.0",
     "@sqds/mesh": "^1.0.6",

+ 1 - 1
governance/xc_admin/packages/proposer_server/package.json

@@ -19,7 +19,7 @@
     "format": "prettier --write \"src/**/*.ts\""
   },
   "dependencies": {
-    "@coral-xyz/anchor": "^0.27.0",
+    "@coral-xyz/anchor": "^0.29.0",
     "@pythnetwork/client": "^2.17.0",
     "@solana/web3.js": "^1.76.0",
     "@sqds/mesh": "^1.0.6",

+ 1 - 1
governance/xc_admin/packages/xc_admin_cli/package.json

@@ -20,7 +20,7 @@
     "cli": "npm run build && node lib/cli.js"
   },
   "dependencies": {
-    "@coral-xyz/anchor": "^0.26.0",
+    "@coral-xyz/anchor": "^0.29.0",
     "@ledgerhq/hw-transport": "^6.27.10",
     "@ledgerhq/hw-transport-node-hid": "^6.27.10",
     "@pythnetwork/client": "^2.9.0",

+ 24 - 24
governance/xc_admin/packages/xc_admin_cli/src/index.ts

@@ -1,42 +1,42 @@
+import { Program } from "@coral-xyz/anchor";
+import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet";
+import { Wallet } from "@coral-xyz/anchor/dist/cjs/provider";
+import { TOKEN_PROGRAM_ID } from "@coral-xyz/anchor/dist/cjs/utils/token";
+import { pythOracleProgram } from "@pythnetwork/client";
+import {
+  PythCluster,
+  getPythClusterApiUrl,
+  getPythProgramKeyForCluster,
+} from "@pythnetwork/client/lib/cluster";
+import {
+  createTransferInstruction,
+  getAssociatedTokenAddress,
+  getMint,
+} from "@solana/spl-token";
 import {
+  AccountMeta,
+  Connection,
   Keypair,
+  LAMPORTS_PER_SOL,
   PublicKey,
-  TransactionInstruction,
-  SYSVAR_RENT_PUBKEY,
   SYSVAR_CLOCK_PUBKEY,
-  AccountMeta,
+  SYSVAR_RENT_PUBKEY,
   StakeProgram,
   SystemProgram,
-  LAMPORTS_PER_SOL,
-  Connection,
+  TransactionInstruction,
 } from "@solana/web3.js";
+import SquadsMesh from "@sqds/mesh";
 import { program } from "commander";
-import {
-  getPythProgramKeyForCluster,
-  PythCluster,
-} from "@pythnetwork/client/lib/cluster";
-import { getPythClusterApiUrl } from "@pythnetwork/client/lib/cluster";
-import { AnchorProvider, Program } from "@coral-xyz/anchor";
 import fs from "fs";
-import SquadsMesh from "@sqds/mesh";
-import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet";
 import {
   BPF_UPGRADABLE_LOADER,
-  getMultisigCluster,
-  getProposalInstructions,
   MultisigParser,
-  PROGRAM_AUTHORITY_ESCROW,
   MultisigVault,
+  PROGRAM_AUTHORITY_ESCROW,
+  getMultisigCluster,
+  getProposalInstructions,
 } from "xc_admin_common";
-import { pythOracleProgram } from "@pythnetwork/client";
-import { Wallet } from "@coral-xyz/anchor/dist/cjs/provider";
 import { LedgerNodeWallet } from "./ledger";
-import {
-  createTransferInstruction,
-  getAssociatedTokenAddress,
-  getMint,
-} from "@solana/spl-token";
-import { TOKEN_PROGRAM_ID } from "@coral-xyz/anchor/dist/cjs/utils/token";
 
 export async function loadHotWalletOrLedger(
   wallet: string,

+ 19 - 10
governance/xc_admin/packages/xc_admin_cli/src/ledger.ts

@@ -4,7 +4,7 @@ import Transport, {
   TransportStatusError,
 } from "@ledgerhq/hw-transport";
 import TransportNodeHid from "@ledgerhq/hw-transport-node-hid";
-import { PublicKey, Transaction } from "@solana/web3.js";
+import { PublicKey, Transaction, VersionedTransaction } from "@solana/web3.js";
 
 export class LedgerNodeWallet implements Wallet {
   private _derivationPath: Buffer;
@@ -35,21 +35,30 @@ export class LedgerNodeWallet implements Wallet {
     return new LedgerNodeWallet(derivationPath, transport, publicKey);
   }
 
-  async signTransaction(transaction: Transaction): Promise<Transaction> {
+  async signTransaction<T extends Transaction | VersionedTransaction>(
+    tx: T
+  ): Promise<T> {
     console.log("Please approve the transaction on your ledger device...");
     const transport = this._transport;
     const publicKey = this.publicKey;
 
-    const signature = await signTransaction(
-      transport,
-      transaction,
-      this._derivationPath
-    );
-    transaction.addSignature(publicKey, signature);
-    return transaction;
+    if (tx instanceof Transaction) {
+      const signature = await signTransaction(
+        transport,
+        tx,
+        this._derivationPath
+      );
+      tx.addSignature(publicKey, signature);
+    } else {
+      // Handle VersionedTransaction if necessary
+      throw new Error("VersionedTransaction is not supported yet.");
+    }
+    return tx;
   }
 
-  async signAllTransactions(txs: Transaction[]): Promise<Transaction[]> {
+  async signAllTransactions<T extends Transaction | VersionedTransaction>(
+    txs: T[]
+  ): Promise<T[]> {
     return await Promise.all(txs.map((tx) => this.signTransaction(tx)));
   }
 }

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

@@ -21,7 +21,7 @@
   },
   "dependencies": {
     "@certusone/wormhole-sdk": "^0.9.22",
-    "@coral-xyz/anchor": "^0.26.0",
+    "@coral-xyz/anchor": "^0.29.0",
     "@pythnetwork/client": "^2.17.0",
     "@solana/buffer-layout": "^4.0.1",
     "@solana/web3.js": "^1.73.0",

+ 6 - 2
governance/xc_admin/packages/xc_admin_common/src/propose.ts

@@ -106,7 +106,11 @@ export class MultisigVault {
       opts = AnchorProvider.defaultOptions();
     }
 
-    return new AnchorProvider(this.squad.connection, this.squad.wallet, opts);
+    return new AnchorProvider(
+      this.squad.connection,
+      this.squad.wallet as Wallet,
+      opts
+    );
   }
 
   // Convenience wrappers around squads methods
@@ -515,7 +519,7 @@ async function getPostMessageInstruction(
   const emitter = squad.getAuthorityPDA(vault, 1);
   const provider = new AnchorProvider(
     squad.connection,
-    squad.wallet,
+    squad.wallet as Wallet,
     AnchorProvider.defaultOptions()
   );
   const wormholeProgram = createWormholeProgramInterface(

+ 1 - 7
governance/xc_admin/packages/xc_admin_frontend/components/common/SocialLinks.tsx

@@ -2,7 +2,6 @@ import Link from 'next/link'
 import Discord from '../../images/icons/discord.inline.svg'
 import Github from '../../images/icons/github.inline.svg'
 import LinkedIn from '../../images/icons/linkedin.inline.svg'
-import Substack from '../../images/icons/substack.inline.svg'
 import Telegram from '../../images/icons/telegram.inline.svg'
 import Twitter from '../../images/icons/twitter.inline.svg'
 import Youtube from '../../images/icons/youtube.inline.svg'
@@ -35,12 +34,7 @@ const SocialLinks = () => {
           <Github />
         </a>
       </Link>
-      <Link href="https://pyth.substack.com">
-        <a target="_blank" className="mr-6">
-          <Substack />
-        </a>
-      </Link>
-      <Link href="https://www.youtube.com/channel/UCjCkvPN9ohl0UDvldfn1neg">
+      <Link href="https://www.youtube.com/@pythnetwork">
         <a target="_blank" className="">
           <Youtube />
         </a>

+ 1 - 1
governance/xc_admin/packages/xc_admin_frontend/components/layout/Footer.tsx

@@ -6,7 +6,7 @@ const Footer = () => {
     <footer>
       <div className="flex flex-col-reverse items-center justify-between px-4 pt-12 pb-4 sm:px-10 lg:flex-row lg:py-6">
         <span className="text-[10px] lg:basis-[280px]">
-          © 2022 Pyth Data Association
+          © 2024 Pyth Data Association
         </span>
         <div className="py-10 lg:py-0">
           <Link href="https://pyth.network/">

+ 26 - 4
governance/xc_admin/packages/xc_admin_frontend/components/tabs/General.tsx

@@ -32,6 +32,8 @@ import Modal from '../common/Modal'
 import Spinner from '../common/Spinner'
 import Loadbar from '../loaders/Loadbar'
 import PermissionDepermissionKey from '../PermissionDepermissionKey'
+import { PriceRawConfig } from '../../hooks/usePyth'
+import { Wallet } from '@coral-xyz/anchor/dist/cjs/provider'
 
 const General = ({ proposerServerUrl }: { proposerServerUrl: string }) => {
   const [data, setData] = useState<any>({})
@@ -126,7 +128,7 @@ const General = ({ proposerServerUrl }: { proposerServerUrl: string }) => {
             metadata: {
               ...product.metadata,
             },
-            priceAccounts: product.priceAccounts.map((p) => {
+            priceAccounts: product.priceAccounts.map((p: PriceRawConfig) => {
               return {
                 address: p.address.toBase58(),
                 publishers: p.publishers
@@ -134,6 +136,7 @@ const General = ({ proposerServerUrl }: { proposerServerUrl: string }) => {
                   .slice(0, getMaximumNumberOfPublishers(cluster)),
                 expo: p.expo,
                 minPub: p.minPub,
+                maxLatency: p.maxLatency,
               }
             }),
           }
@@ -144,7 +147,7 @@ const General = ({ proposerServerUrl }: { proposerServerUrl: string }) => {
       setExistingSymbols(new Set(Object.keys(symbolToData)))
       setData(sortDataMemo(symbolToData))
     }
-  }, [rawConfig, dataIsLoading, sortDataMemo])
+  }, [rawConfig, dataIsLoading, sortDataMemo, cluster])
 
   const sortObjectByKeys = (obj: any) => {
     const sortedObj: any = {}
@@ -367,7 +370,6 @@ const General = ({ proposerServerUrl }: { proposerServerUrl: string }) => {
           }
 
           // create add publisher instruction if there are any publishers
-
           for (let publisherKey of newChanges.priceAccounts[0].publishers) {
             instructions.push(
               await pythProgramClient.methods
@@ -489,6 +491,26 @@ const General = ({ proposerServerUrl }: { proposerServerUrl: string }) => {
             )
           }
 
+          // check if maxLatency has changed
+          if (
+            prev.priceAccounts[0].maxLatency !==
+            newChanges.priceAccounts[0].maxLatency
+          ) {
+            // create update product account instruction
+            instructions.push(
+              await pythProgramClient.methods
+                .setMaxLatency(
+                  newChanges.priceAccounts[0].maxLatency,
+                  [0, 0, 0]
+                )
+                .accounts({
+                  priceAccount: new PublicKey(prev.priceAccounts[0].address),
+                  fundingAccount,
+                })
+                .instruction()
+            )
+          }
+
           // check if publishers have changed
           const publisherKeysToAdd =
             newChanges.priceAccounts[0].publishers.filter(
@@ -804,7 +826,7 @@ const General = ({ proposerServerUrl }: { proposerServerUrl: string }) => {
     if (connected && squads) {
       const provider = new AnchorProvider(
         connection,
-        squads.wallet,
+        squads.wallet as Wallet,
         AnchorProvider.defaultOptions()
       )
       setPythProgramClient(

+ 4 - 3
governance/xc_admin/packages/xc_admin_frontend/components/tabs/UpdatePermissions.tsx

@@ -4,7 +4,7 @@ import {
   pythOracleProgram,
 } from '@pythnetwork/client'
 import { PythOracle } from '@pythnetwork/client/lib/anchor'
-import { useAnchorWallet, useWallet } from '@solana/wallet-adapter-react'
+import { useWallet } from '@solana/wallet-adapter-react'
 import { WalletModalButton } from '@solana/wallet-adapter-react-ui'
 import { PublicKey } from '@solana/web3.js'
 import {
@@ -35,6 +35,7 @@ import Modal from '../common/Modal'
 import Spinner from '../common/Spinner'
 import EditButton from '../EditButton'
 import Loadbar from '../loaders/Loadbar'
+import { Wallet } from '@coral-xyz/anchor/dist/cjs/provider'
 
 interface UpdatePermissionsProps {
   account: PermissionAccount
@@ -267,7 +268,7 @@ const UpdatePermissions = () => {
             setIsSendProposalButtonLoading(true)
             try {
               const vault = new MultisigVault(
-                squads.wallet,
+                squads.wallet as Wallet,
                 getMultisigCluster(cluster),
                 squads,
                 UPGRADE_MULTISIG[getMultisigCluster(cluster)]
@@ -338,7 +339,7 @@ const UpdatePermissions = () => {
     if (connected && squads) {
       const provider = new AnchorProvider(
         connection,
-        squads.wallet,
+        squads.wallet as Wallet,
         AnchorProvider.defaultOptions()
       )
       setPythProgramClient(

+ 2 - 0
governance/xc_admin/packages/xc_admin_frontend/hooks/usePyth.ts

@@ -43,6 +43,7 @@ export type PriceRawConfig = {
   address: PublicKey
   expo: number
   minPub: number
+  maxLatency: number
   publishers: PublicKey[]
 }
 
@@ -97,6 +98,7 @@ const usePyth = (): PythHookData => {
                 }),
                 expo: parsed.exponent,
                 minPub: parsed.minPublishers,
+                maxLatency: parsed.maxLatency,
               }
               allPythAccounts[i] = allPythAccounts[allPythAccounts.length - 1]
               allPythAccounts.pop()

+ 2 - 2
governance/xc_admin/packages/xc_admin_frontend/package.json

@@ -9,9 +9,9 @@
     "lint": "next lint"
   },
   "dependencies": {
-    "@coral-xyz/anchor": "^0.26.0",
+    "@coral-xyz/anchor": "^0.29.0",
     "@headlessui/react": "^1.7.7",
-    "@pythnetwork/client": "^2.15.0",
+    "@pythnetwork/client": "^2.21.0",
     "@radix-ui/react-label": "^2.0.0",
     "@radix-ui/react-tooltip": "^1.0.3",
     "@solana/spl-token": "^0.3.7",

+ 64 - 240
package-lock.json

@@ -43,6 +43,7 @@
       "license": "Apache-2.0",
       "dependencies": {
         "@certusone/wormhole-sdk": "^0.9.8",
+        "@coral-xyz/anchor": "^0.29.0",
         "@injectivelabs/networks": "1.0.68",
         "@mysten/sui.js": "^0.49.1",
         "@pythnetwork/cosmwasm-deploy-tools": "*",
@@ -3257,7 +3258,7 @@
       "license": "ISC",
       "dependencies": {
         "@certusone/wormhole-sdk": "^0.9.9",
-        "@coral-xyz/anchor": "^0.26.0",
+        "@coral-xyz/anchor": "^0.29.0",
         "@pythnetwork/client": "^2.9.0",
         "@solana/web3.js": "^1.73.0",
         "@sqds/mesh": "^1.0.6",
@@ -3305,7 +3306,7 @@
       "license": "ISC",
       "dependencies": {
         "@certusone/wormhole-sdk": "^0.9.9",
-        "@coral-xyz/anchor": "^0.26.0",
+        "@coral-xyz/anchor": "^0.29.0",
         "@pythnetwork/client": "^2.9.0",
         "@solana/web3.js": "^1.73.0",
         "@sqds/mesh": "^1.0.6",
@@ -3352,7 +3353,7 @@
       "version": "0.0.0",
       "license": "ISC",
       "dependencies": {
-        "@coral-xyz/anchor": "^0.27.0",
+        "@coral-xyz/anchor": "^0.29.0",
         "@pythnetwork/client": "^2.17.0",
         "@solana/web3.js": "^1.76.0",
         "@sqds/mesh": "^1.0.6",
@@ -3362,62 +3363,11 @@
         "xc_admin_common": "*"
       }
     },
-    "governance/xc_admin/packages/proposer_server/node_modules/@coral-xyz/anchor": {
-      "version": "0.27.0",
-      "resolved": "https://registry.npmjs.org/@coral-xyz/anchor/-/anchor-0.27.0.tgz",
-      "integrity": "sha512-+P/vPdORawvg3A9Wj02iquxb4T0C5m4P6aZBVYysKl4Amk+r6aMPZkUhilBkD6E4Nuxnoajv3CFykUfkGE0n5g==",
-      "dependencies": {
-        "@coral-xyz/borsh": "^0.27.0",
-        "@solana/web3.js": "^1.68.0",
-        "base64-js": "^1.5.1",
-        "bn.js": "^5.1.2",
-        "bs58": "^4.0.1",
-        "buffer-layout": "^1.2.2",
-        "camelcase": "^6.3.0",
-        "cross-fetch": "^3.1.5",
-        "crypto-hash": "^1.3.0",
-        "eventemitter3": "^4.0.7",
-        "js-sha256": "^0.9.0",
-        "pako": "^2.0.3",
-        "snake-case": "^3.0.4",
-        "superstruct": "^0.15.4",
-        "toml": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=11"
-      }
-    },
-    "governance/xc_admin/packages/proposer_server/node_modules/@coral-xyz/borsh": {
-      "version": "0.27.0",
-      "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.27.0.tgz",
-      "integrity": "sha512-tJKzhLukghTWPLy+n8K8iJKgBq1yLT/AxaNd10yJrX8mI56ao5+OFAKAqW/h0i79KCvb4BK0VGO5ECmmolFz9A==",
-      "dependencies": {
-        "bn.js": "^5.1.2",
-        "buffer-layout": "^1.2.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "peerDependencies": {
-        "@solana/web3.js": "^1.68.0"
-      }
-    },
-    "governance/xc_admin/packages/proposer_server/node_modules/camelcase": {
-      "version": "6.3.0",
-      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
-      "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
     "governance/xc_admin/packages/xc_admin_cli": {
       "version": "0.0.0",
       "license": "ISC",
       "dependencies": {
-        "@coral-xyz/anchor": "^0.26.0",
+        "@coral-xyz/anchor": "^0.29.0",
         "@ledgerhq/hw-transport": "^6.27.10",
         "@ledgerhq/hw-transport-node-hid": "^6.27.10",
         "@pythnetwork/client": "^2.9.0",
@@ -3441,7 +3391,7 @@
       "license": "ISC",
       "dependencies": {
         "@certusone/wormhole-sdk": "^0.9.22",
-        "@coral-xyz/anchor": "^0.26.0",
+        "@coral-xyz/anchor": "^0.29.0",
         "@pythnetwork/client": "^2.17.0",
         "@pythnetwork/solana-utils": "*",
         "@solana/buffer-layout": "^4.0.1",
@@ -3957,9 +3907,9 @@
     "governance/xc_admin/packages/xc_admin_frontend": {
       "version": "0.1.0",
       "dependencies": {
-        "@coral-xyz/anchor": "^0.26.0",
+        "@coral-xyz/anchor": "^0.29.0",
         "@headlessui/react": "^1.7.7",
-        "@pythnetwork/client": "^2.15.0",
+        "@pythnetwork/client": "^2.21.0",
         "@radix-ui/react-label": "^2.0.0",
         "@radix-ui/react-tooltip": "^1.0.3",
         "@solana/spl-token": "^0.3.7",
@@ -6857,13 +6807,13 @@
       }
     },
     "node_modules/@coral-xyz/anchor": {
-      "version": "0.26.0",
-      "resolved": "https://registry.npmjs.org/@coral-xyz/anchor/-/anchor-0.26.0.tgz",
-      "integrity": "sha512-PxRl+wu5YyptWiR9F2MBHOLLibm87Z4IMUBPreX+DYBtPM+xggvcPi0KAN7+kIL4IrIhXI8ma5V0MCXxSN1pHg==",
+      "version": "0.29.0",
+      "resolved": "https://registry.npmjs.org/@coral-xyz/anchor/-/anchor-0.29.0.tgz",
+      "integrity": "sha512-eny6QNG0WOwqV0zQ7cs/b1tIuzZGmP7U7EcH+ogt4Gdbl8HDmIYVMh/9aTmYZPaFWjtUaI8qSn73uYEXWfATdA==",
       "dependencies": {
-        "@coral-xyz/borsh": "^0.26.0",
+        "@coral-xyz/borsh": "^0.29.0",
+        "@noble/hashes": "^1.3.1",
         "@solana/web3.js": "^1.68.0",
-        "base64-js": "^1.5.1",
         "bn.js": "^5.1.2",
         "bs58": "^4.0.1",
         "buffer-layout": "^1.2.2",
@@ -6871,7 +6821,6 @@
         "cross-fetch": "^3.1.5",
         "crypto-hash": "^1.3.0",
         "eventemitter3": "^4.0.7",
-        "js-sha256": "^0.9.0",
         "pako": "^2.0.3",
         "snake-case": "^3.0.4",
         "superstruct": "^0.15.4",
@@ -6882,9 +6831,9 @@
       }
     },
     "node_modules/@coral-xyz/anchor/node_modules/@coral-xyz/borsh": {
-      "version": "0.26.0",
-      "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.26.0.tgz",
-      "integrity": "sha512-uCZ0xus0CszQPHYfWAqKS5swS1UxvePu83oOF+TWpUkedsNlg6p2p4azxZNSSqwXb9uXMFgxhuMBX9r3Xoi0vQ==",
+      "version": "0.29.0",
+      "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.29.0.tgz",
+      "integrity": "sha512-s7VFVa3a0oqpkuRloWVPdCK7hMbAMY270geZOGfCnaqexrP5dTIpbEHL33req6IYPPJ0hYa71cdvJ1h6V55/oQ==",
       "dependencies": {
         "bn.js": "^5.1.2",
         "buffer-layout": "^1.2.0"
@@ -6896,6 +6845,17 @@
         "@solana/web3.js": "^1.68.0"
       }
     },
+    "node_modules/@coral-xyz/anchor/node_modules/@noble/hashes": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz",
+      "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==",
+      "engines": {
+        "node": ">= 16"
+      },
+      "funding": {
+        "url": "https://paulmillr.com/funding/"
+      }
+    },
     "node_modules/@coral-xyz/anchor/node_modules/camelcase": {
       "version": "6.3.0",
       "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
@@ -13565,12 +13525,12 @@
       "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
     },
     "node_modules/@pythnetwork/client": {
-      "version": "2.17.0",
-      "resolved": "https://registry.npmjs.org/@pythnetwork/client/-/client-2.17.0.tgz",
-      "integrity": "sha512-hv285vehmLH6N762Z4jqvPTM+hCYnXQaUp6DMgLUpDHvE0mTbwW9PvlxYoUJZGtyeCDkgn9HrTWXPtnaXTRr+Q==",
+      "version": "2.21.0",
+      "resolved": "https://registry.npmjs.org/@pythnetwork/client/-/client-2.21.0.tgz",
+      "integrity": "sha512-jqUuPLuVKRNUsZfwLuvK/MwnJ3LIrIxBNoz43xt0fjvVuH5QyTlz51ek76CkeKfCbomGKe41Vq7bvn8aqWVOGA==",
       "dependencies": {
-        "@coral-xyz/anchor": "^0.26.0",
-        "@coral-xyz/borsh": "^0.26.0",
+        "@coral-xyz/anchor": "^0.29.0",
+        "@coral-xyz/borsh": "^0.28.0",
         "buffer": "^6.0.1"
       },
       "peerDependencies": {
@@ -13578,9 +13538,9 @@
       }
     },
     "node_modules/@pythnetwork/client/node_modules/@coral-xyz/borsh": {
-      "version": "0.26.0",
-      "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.26.0.tgz",
-      "integrity": "sha512-uCZ0xus0CszQPHYfWAqKS5swS1UxvePu83oOF+TWpUkedsNlg6p2p4azxZNSSqwXb9uXMFgxhuMBX9r3Xoi0vQ==",
+      "version": "0.28.0",
+      "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.28.0.tgz",
+      "integrity": "sha512-/u1VTzw7XooK7rqeD7JLUSwOyRSesPUk0U37BV9zK0axJc1q0nRbKFGFLYCQ16OtdOJTTwGfGp11Lx9B45bRCQ==",
       "dependencies": {
         "bn.js": "^5.1.2",
         "buffer-layout": "^1.2.0"
@@ -59352,67 +59312,6 @@
         "typescript": "^4.6.3"
       }
     },
-    "target_chains/solana/sdk/js/pyth_solana_receiver/node_modules/@coral-xyz/anchor": {
-      "version": "0.29.0",
-      "resolved": "https://registry.npmjs.org/@coral-xyz/anchor/-/anchor-0.29.0.tgz",
-      "integrity": "sha512-eny6QNG0WOwqV0zQ7cs/b1tIuzZGmP7U7EcH+ogt4Gdbl8HDmIYVMh/9aTmYZPaFWjtUaI8qSn73uYEXWfATdA==",
-      "dependencies": {
-        "@coral-xyz/borsh": "^0.29.0",
-        "@noble/hashes": "^1.3.1",
-        "@solana/web3.js": "^1.68.0",
-        "bn.js": "^5.1.2",
-        "bs58": "^4.0.1",
-        "buffer-layout": "^1.2.2",
-        "camelcase": "^6.3.0",
-        "cross-fetch": "^3.1.5",
-        "crypto-hash": "^1.3.0",
-        "eventemitter3": "^4.0.7",
-        "pako": "^2.0.3",
-        "snake-case": "^3.0.4",
-        "superstruct": "^0.15.4",
-        "toml": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=11"
-      }
-    },
-    "target_chains/solana/sdk/js/pyth_solana_receiver/node_modules/@coral-xyz/borsh": {
-      "version": "0.29.0",
-      "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.29.0.tgz",
-      "integrity": "sha512-s7VFVa3a0oqpkuRloWVPdCK7hMbAMY270geZOGfCnaqexrP5dTIpbEHL33req6IYPPJ0hYa71cdvJ1h6V55/oQ==",
-      "dependencies": {
-        "bn.js": "^5.1.2",
-        "buffer-layout": "^1.2.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "peerDependencies": {
-        "@solana/web3.js": "^1.68.0"
-      }
-    },
-    "target_chains/solana/sdk/js/pyth_solana_receiver/node_modules/@noble/hashes": {
-      "version": "1.3.3",
-      "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz",
-      "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==",
-      "engines": {
-        "node": ">= 16"
-      },
-      "funding": {
-        "url": "https://paulmillr.com/funding/"
-      }
-    },
-    "target_chains/solana/sdk/js/pyth_solana_receiver/node_modules/camelcase": {
-      "version": "6.3.0",
-      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
-      "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
     "target_chains/solana/sdk/js/solana_utils": {
       "name": "@pythnetwork/solana-utils",
       "version": "0.1.0",
@@ -62003,13 +61902,13 @@
       }
     },
     "@coral-xyz/anchor": {
-      "version": "0.26.0",
-      "resolved": "https://registry.npmjs.org/@coral-xyz/anchor/-/anchor-0.26.0.tgz",
-      "integrity": "sha512-PxRl+wu5YyptWiR9F2MBHOLLibm87Z4IMUBPreX+DYBtPM+xggvcPi0KAN7+kIL4IrIhXI8ma5V0MCXxSN1pHg==",
+      "version": "0.29.0",
+      "resolved": "https://registry.npmjs.org/@coral-xyz/anchor/-/anchor-0.29.0.tgz",
+      "integrity": "sha512-eny6QNG0WOwqV0zQ7cs/b1tIuzZGmP7U7EcH+ogt4Gdbl8HDmIYVMh/9aTmYZPaFWjtUaI8qSn73uYEXWfATdA==",
       "requires": {
-        "@coral-xyz/borsh": "^0.26.0",
+        "@coral-xyz/borsh": "^0.29.0",
+        "@noble/hashes": "^1.3.1",
         "@solana/web3.js": "^1.68.0",
-        "base64-js": "^1.5.1",
         "bn.js": "^5.1.2",
         "bs58": "^4.0.1",
         "buffer-layout": "^1.2.2",
@@ -62017,7 +61916,6 @@
         "cross-fetch": "^3.1.5",
         "crypto-hash": "^1.3.0",
         "eventemitter3": "^4.0.7",
-        "js-sha256": "^0.9.0",
         "pako": "^2.0.3",
         "snake-case": "^3.0.4",
         "superstruct": "^0.15.4",
@@ -62025,14 +61923,19 @@
       },
       "dependencies": {
         "@coral-xyz/borsh": {
-          "version": "0.26.0",
-          "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.26.0.tgz",
-          "integrity": "sha512-uCZ0xus0CszQPHYfWAqKS5swS1UxvePu83oOF+TWpUkedsNlg6p2p4azxZNSSqwXb9uXMFgxhuMBX9r3Xoi0vQ==",
+          "version": "0.29.0",
+          "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.29.0.tgz",
+          "integrity": "sha512-s7VFVa3a0oqpkuRloWVPdCK7hMbAMY270geZOGfCnaqexrP5dTIpbEHL33req6IYPPJ0hYa71cdvJ1h6V55/oQ==",
           "requires": {
             "bn.js": "^5.1.2",
             "buffer-layout": "^1.2.0"
           }
         },
+        "@noble/hashes": {
+          "version": "1.3.3",
+          "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz",
+          "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA=="
+        },
         "camelcase": {
           "version": "6.3.0",
           "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
@@ -67227,19 +67130,19 @@
       "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
     },
     "@pythnetwork/client": {
-      "version": "2.17.0",
-      "resolved": "https://registry.npmjs.org/@pythnetwork/client/-/client-2.17.0.tgz",
-      "integrity": "sha512-hv285vehmLH6N762Z4jqvPTM+hCYnXQaUp6DMgLUpDHvE0mTbwW9PvlxYoUJZGtyeCDkgn9HrTWXPtnaXTRr+Q==",
+      "version": "2.21.0",
+      "resolved": "https://registry.npmjs.org/@pythnetwork/client/-/client-2.21.0.tgz",
+      "integrity": "sha512-jqUuPLuVKRNUsZfwLuvK/MwnJ3LIrIxBNoz43xt0fjvVuH5QyTlz51ek76CkeKfCbomGKe41Vq7bvn8aqWVOGA==",
       "requires": {
-        "@coral-xyz/anchor": "^0.26.0",
-        "@coral-xyz/borsh": "^0.26.0",
+        "@coral-xyz/anchor": "^0.29.0",
+        "@coral-xyz/borsh": "^0.28.0",
         "buffer": "^6.0.1"
       },
       "dependencies": {
         "@coral-xyz/borsh": {
-          "version": "0.26.0",
-          "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.26.0.tgz",
-          "integrity": "sha512-uCZ0xus0CszQPHYfWAqKS5swS1UxvePu83oOF+TWpUkedsNlg6p2p4azxZNSSqwXb9uXMFgxhuMBX9r3Xoi0vQ==",
+          "version": "0.28.0",
+          "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.28.0.tgz",
+          "integrity": "sha512-/u1VTzw7XooK7rqeD7JLUSwOyRSesPUk0U37BV9zK0axJc1q0nRbKFGFLYCQ16OtdOJTTwGfGp11Lx9B45bRCQ==",
           "requires": {
             "bn.js": "^5.1.2",
             "buffer-layout": "^1.2.0"
@@ -71152,48 +71055,6 @@
         "quicktype": "^23.0.76",
         "ts-jest": "^29.0.5",
         "typescript": "^4.6.3"
-      },
-      "dependencies": {
-        "@coral-xyz/anchor": {
-          "version": "0.29.0",
-          "resolved": "https://registry.npmjs.org/@coral-xyz/anchor/-/anchor-0.29.0.tgz",
-          "integrity": "sha512-eny6QNG0WOwqV0zQ7cs/b1tIuzZGmP7U7EcH+ogt4Gdbl8HDmIYVMh/9aTmYZPaFWjtUaI8qSn73uYEXWfATdA==",
-          "requires": {
-            "@coral-xyz/borsh": "^0.29.0",
-            "@noble/hashes": "^1.3.1",
-            "@solana/web3.js": "^1.68.0",
-            "bn.js": "^5.1.2",
-            "bs58": "^4.0.1",
-            "buffer-layout": "^1.2.2",
-            "camelcase": "^6.3.0",
-            "cross-fetch": "^3.1.5",
-            "crypto-hash": "^1.3.0",
-            "eventemitter3": "^4.0.7",
-            "pako": "^2.0.3",
-            "snake-case": "^3.0.4",
-            "superstruct": "^0.15.4",
-            "toml": "^3.0.0"
-          }
-        },
-        "@coral-xyz/borsh": {
-          "version": "0.29.0",
-          "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.29.0.tgz",
-          "integrity": "sha512-s7VFVa3a0oqpkuRloWVPdCK7hMbAMY270geZOGfCnaqexrP5dTIpbEHL33req6IYPPJ0hYa71cdvJ1h6V55/oQ==",
-          "requires": {
-            "bn.js": "^5.1.2",
-            "buffer-layout": "^1.2.0"
-          }
-        },
-        "@noble/hashes": {
-          "version": "1.3.3",
-          "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz",
-          "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA=="
-        },
-        "camelcase": {
-          "version": "6.3.0",
-          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
-          "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA=="
-        }
       }
     },
     "@pythnetwork/pyth-sui-js": {
@@ -81233,6 +81094,7 @@
       "version": "file:contract_manager",
       "requires": {
         "@certusone/wormhole-sdk": "^0.9.8",
+        "@coral-xyz/anchor": "^0.29.0",
         "@injectivelabs/networks": "1.0.68",
         "@mysten/sui.js": "^0.49.1",
         "@pythnetwork/cosmwasm-deploy-tools": "*",
@@ -82167,7 +82029,7 @@
       "version": "file:governance/xc_admin/packages/crank_executor",
       "requires": {
         "@certusone/wormhole-sdk": "^0.9.9",
-        "@coral-xyz/anchor": "^0.26.0",
+        "@coral-xyz/anchor": "^0.29.0",
         "@pythnetwork/client": "^2.9.0",
         "@solana/web3.js": "^1.73.0",
         "@sqds/mesh": "^1.0.6",
@@ -82216,7 +82078,7 @@
       "version": "file:governance/xc_admin/packages/crank_pythnet_relayer",
       "requires": {
         "@certusone/wormhole-sdk": "^0.9.9",
-        "@coral-xyz/anchor": "^0.26.0",
+        "@coral-xyz/anchor": "^0.29.0",
         "@pythnetwork/client": "^2.9.0",
         "@solana/web3.js": "^1.73.0",
         "@sqds/mesh": "^1.0.6",
@@ -96395,7 +96257,7 @@
     "proposer_server": {
       "version": "file:governance/xc_admin/packages/proposer_server",
       "requires": {
-        "@coral-xyz/anchor": "^0.27.0",
+        "@coral-xyz/anchor": "^0.29.0",
         "@pythnetwork/client": "^2.17.0",
         "@solana/web3.js": "^1.76.0",
         "@sqds/mesh": "^1.0.6",
@@ -96403,44 +96265,6 @@
         "cors": "^2.8.5",
         "ts-node": "^10.9.1",
         "xc_admin_common": "*"
-      },
-      "dependencies": {
-        "@coral-xyz/anchor": {
-          "version": "0.27.0",
-          "resolved": "https://registry.npmjs.org/@coral-xyz/anchor/-/anchor-0.27.0.tgz",
-          "integrity": "sha512-+P/vPdORawvg3A9Wj02iquxb4T0C5m4P6aZBVYysKl4Amk+r6aMPZkUhilBkD6E4Nuxnoajv3CFykUfkGE0n5g==",
-          "requires": {
-            "@coral-xyz/borsh": "^0.27.0",
-            "@solana/web3.js": "^1.68.0",
-            "base64-js": "^1.5.1",
-            "bn.js": "^5.1.2",
-            "bs58": "^4.0.1",
-            "buffer-layout": "^1.2.2",
-            "camelcase": "^6.3.0",
-            "cross-fetch": "^3.1.5",
-            "crypto-hash": "^1.3.0",
-            "eventemitter3": "^4.0.7",
-            "js-sha256": "^0.9.0",
-            "pako": "^2.0.3",
-            "snake-case": "^3.0.4",
-            "superstruct": "^0.15.4",
-            "toml": "^3.0.0"
-          }
-        },
-        "@coral-xyz/borsh": {
-          "version": "0.27.0",
-          "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.27.0.tgz",
-          "integrity": "sha512-tJKzhLukghTWPLy+n8K8iJKgBq1yLT/AxaNd10yJrX8mI56ao5+OFAKAqW/h0i79KCvb4BK0VGO5ECmmolFz9A==",
-          "requires": {
-            "bn.js": "^5.1.2",
-            "buffer-layout": "^1.2.0"
-          }
-        },
-        "camelcase": {
-          "version": "6.3.0",
-          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
-          "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA=="
-        }
       }
     },
     "proto-list": {
@@ -105726,7 +105550,7 @@
     "xc_admin_cli": {
       "version": "file:governance/xc_admin/packages/xc_admin_cli",
       "requires": {
-        "@coral-xyz/anchor": "^0.26.0",
+        "@coral-xyz/anchor": "^0.29.0",
         "@ledgerhq/hw-transport": "^6.27.10",
         "@ledgerhq/hw-transport-node-hid": "^6.27.10",
         "@pythnetwork/client": "^2.9.0",
@@ -105748,7 +105572,7 @@
       "version": "file:governance/xc_admin/packages/xc_admin_common",
       "requires": {
         "@certusone/wormhole-sdk": "^0.9.22",
-        "@coral-xyz/anchor": "^0.26.0",
+        "@coral-xyz/anchor": "^0.29.0",
         "@pythnetwork/client": "^2.17.0",
         "@pythnetwork/solana-utils": "*",
         "@solana/buffer-layout": "^4.0.1",
@@ -106191,9 +106015,9 @@
     "xc_admin_frontend": {
       "version": "file:governance/xc_admin/packages/xc_admin_frontend",
       "requires": {
-        "@coral-xyz/anchor": "^0.26.0",
+        "@coral-xyz/anchor": "^0.29.0",
         "@headlessui/react": "^1.7.7",
-        "@pythnetwork/client": "^2.15.0",
+        "@pythnetwork/client": "^2.21.0",
         "@radix-ui/react-label": "^2.0.0",
         "@radix-ui/react-tooltip": "^1.0.3",
         "@solana/spl-token": "^0.3.7",