From 8e7c9548307f560f5d77fc97905125263c67d4bf Mon Sep 17 00:00:00 2001 From: Matej Date: Tue, 26 May 2026 13:57:40 +0200 Subject: [PATCH] contract_manager: @certusone/wormhole-sdk -> @wormhole-foundation/sdk The certusone SDK is deprecated for a long time already, and proto-web sub-package imports `long` without declaring it as a dependency, causing a MODULE_NOT_FOUND crash under pnpm's strict package isolation. If things go well, we can follow suit with xc_admin packages. - governance.ts: swap certusone Solana PDA helpers for the identical functions from @wormhole-foundation/sdk-solana-core (utils namespace) - executor.ts, sui.ts, scripts: replace parseVaa with deserialize("Uint8Array", ...) from @wormhole-foundation/sdk-definitions - executor.ts: use chainToChainId from @wormhole-foundation/sdk-base for the emitterChain numeric comparison; use BigInt() for sequence comparison to avoid precision loss - sui.ts, iota.ts: inline uint8ArrayToBCS using @mysten/sui/bcs and @iota/iota-sdk/bcs respectively - remove preserve-native-fetch.ts: the workaround for near-api-js@1.x clobbering globalThis.fetch is no longer needed; near-api-js@3.x (direct dep) uses a nullish-coalescing fallback and never overwrites it --- contract_manager/package.json | 15 ++----- contract_manager/scripts/execute_vaas.ts | 25 ++++++----- .../scripts/manage_cardano_governance.ts | 5 ++- .../scripts/sync_governance_vaas.ts | 24 ++++++----- contract_manager/src/core/contracts/iota.ts | 37 ++++++----------- contract_manager/src/core/contracts/sui.ts | 41 +++++++------------ contract_manager/src/node/utils/executor.ts | 18 ++++---- contract_manager/src/node/utils/governance.ts | 27 +++--------- .../src/node/utils/preserve-native-fetch.ts | 21 ---------- contract_manager/src/node/utils/store.ts | 10 ----- pnpm-lock.yaml | 11 +++-- 11 files changed, 79 insertions(+), 155 deletions(-) delete mode 100644 contract_manager/src/node/utils/preserve-native-fetch.ts diff --git a/contract_manager/package.json b/contract_manager/package.json index 1b23ca5a47..3a0ff4fc03 100644 --- a/contract_manager/package.json +++ b/contract_manager/package.json @@ -1,7 +1,6 @@ { "author": "", "dependencies": { - "@certusone/wormhole-sdk": "^0.9.8", "@coral-xyz/anchor": "^0.29.0", "@cosmjs/cosmwasm-stargate": "^0.32.3", "@cosmjs/stargate": "^0.32.3", @@ -31,7 +30,9 @@ "@ton/crypto": "^3.3.0", "@ton/ton": "^15.1.0", "@types/yargs": "catalog:", - "@wormhole-foundation/sdk-solana-core": "^4.18.0", + "@wormhole-foundation/sdk-base": "^4.19.0", + "@wormhole-foundation/sdk-definitions": "^4.19.0", + "@wormhole-foundation/sdk-solana-core": "^4.19.0", "aptos": "^1.5.0", "axios": "^0.24.0", "bs58": "^5.0.0", @@ -241,16 +242,6 @@ "types": "./dist/cjs/node/utils/governance.d.ts" } }, - "./node/utils/preserve-native-fetch": { - "import": { - "default": "./dist/esm/node/utils/preserve-native-fetch.mjs", - "types": "./dist/esm/node/utils/preserve-native-fetch.d.ts" - }, - "require": { - "default": "./dist/cjs/node/utils/preserve-native-fetch.cjs", - "types": "./dist/cjs/node/utils/preserve-native-fetch.d.ts" - } - }, "./node/utils/shell": { "import": { "default": "./dist/esm/node/utils/shell.mjs", diff --git a/contract_manager/scripts/execute_vaas.ts b/contract_manager/scripts/execute_vaas.ts index de1cc16454..bf921cbe56 100644 --- a/contract_manager/scripts/execute_vaas.ts +++ b/contract_manager/scripts/execute_vaas.ts @@ -1,13 +1,6 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ -/* eslint-disable @typescript-eslint/no-floating-promises */ - -/* eslint-disable unicorn/prefer-top-level-await */ - -/* eslint-disable @typescript-eslint/restrict-template-expressions */ -/* eslint-disable no-console */ - -import { parseVaa } from "@certusone/wormhole-sdk"; +/** biome-ignore-all lint/suspicious/noConsole: CLI script */ import { decodeGovernancePayload } from "@pythnetwork/xc-admin-common"; +import { deserialize } from "@wormhole-foundation/sdk-definitions"; import yargs from "yargs"; import { hideBin } from "yargs/helpers"; import { toPrivateKey } from "../src/core/base"; @@ -61,7 +54,12 @@ async function main() { "mainnet-beta_FVQyHcooAtThJ83XFrNnv74BcinbRH3bRmfFamAHBfuj" ] : DefaultStore.vaults.devnet_6baWtW1zTUVMSJHJQVxDUXWzqrQeYBr6mu31j3bTKwY3; - console.log("Executing VAAs for vault", vault?.getId()); + + if (!vault) { + throw new Error(`Could not retrieve vault '${argv.vault}'`); + } + + console.log("Executing VAAs for vault", vault.getId()); console.log( "Executing VAAs for emitter", // eslint-disable-next-line unicorn/no-await-expression-member @@ -93,12 +91,13 @@ async function main() { seqNumber++ ) { const submittedWormholeMessage = new SubmittedWormholeMessage( - await vault!.getEmitter(), + await vault.getEmitter(), seqNumber, - vault!.cluster, + vault.cluster, ); const vaa = await submittedWormholeMessage.fetchVaa(); - const decodedAction = decodeGovernancePayload(parseVaa(vaa).payload); + const { payload } = deserialize("Uint8Array", new Uint8Array(vaa)); + const decodedAction = decodeGovernancePayload(Buffer.from(payload)); if (!decodedAction) { console.log("Skipping unknown action for vaa", seqNumber); continue; diff --git a/contract_manager/scripts/manage_cardano_governance.ts b/contract_manager/scripts/manage_cardano_governance.ts index 5a40916a96..419667c65c 100644 --- a/contract_manager/scripts/manage_cardano_governance.ts +++ b/contract_manager/scripts/manage_cardano_governance.ts @@ -1,6 +1,5 @@ /** biome-ignore-all lint/suspicious/noConsole: this is a CLI script */ -import { parseVaa } from "@certusone/wormhole-sdk"; import type { Wallet } from "@coral-xyz/anchor"; import type { PythCluster } from "@pythnetwork/client"; import { @@ -9,6 +8,7 @@ import { UpgradeCardanoSpendScript, UpgradeCardanoWithdrawScript, } from "@pythnetwork/xc-admin-common"; +import { deserialize } from "@wormhole-foundation/sdk-definitions"; import type { Options } from "yargs"; import yargs from "yargs"; import { hideBin } from "yargs/helpers"; @@ -287,7 +287,8 @@ parser.command( process.stderr.write(`Sequence ${seq}: not found, skipping\n`); continue; } - const action = decodeGovernancePayload(parseVaa(vaa).payload); + const { payload } = deserialize("Uint8Array", new Uint8Array(vaa)); + const action = decodeGovernancePayload(Buffer.from(payload)); if (!action || action.targetChainId !== chain) { process.stderr.write( `Sequence ${seq}: could not decode as action for this chain, skipping\n`, diff --git a/contract_manager/scripts/sync_governance_vaas.ts b/contract_manager/scripts/sync_governance_vaas.ts index e44ad76c0a..a54ab830a0 100644 --- a/contract_manager/scripts/sync_governance_vaas.ts +++ b/contract_manager/scripts/sync_governance_vaas.ts @@ -1,8 +1,6 @@ -/* eslint-disable no-console */ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ -/* eslint-disable unicorn/no-await-expression-member */ -import { parseVaa } from "@certusone/wormhole-sdk"; +/** biome-ignore-all lint/suspicious/noConsole: CLI script */ import { decodeGovernancePayload } from "@pythnetwork/xc-admin-common"; +import { deserialize } from "@wormhole-foundation/sdk-definitions"; import yargs from "yargs"; import { hideBin } from "yargs/helpers"; @@ -44,9 +42,17 @@ async function main() { const mainnetVault = DefaultStore.vaults[ "mainnet-beta_FVQyHcooAtThJ83XFrNnv74BcinbRH3bRmfFamAHBfuj" - ]!; + ]; + if (!mainnetVault) { + throw new Error("could not find mainnet vault"); + } + const devnetVault = - DefaultStore.vaults.devnet_6baWtW1zTUVMSJHJQVxDUXWzqrQeYBr6mu31j3bTKwY3!; + DefaultStore.vaults.devnet_6baWtW1zTUVMSJHJQVxDUXWzqrQeYBr6mu31j3bTKwY3; + if (!devnetVault) { + throw new Error("could not find devnet vault"); + } + let matchedVault: Vault; if ( (await devnetVault.getEmitter()).toBuffer().toString("hex") === @@ -73,7 +79,6 @@ async function main() { } console.log("Starting from sequence number", lastExecuted); - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition while (true) { const submittedWormholeMessage = new SubmittedWormholeMessage( await matchedVault.getEmitter(), @@ -88,8 +93,8 @@ async function main() { console.log("no vaa found for sequence", lastExecuted + 1); break; } - const parsedVaa = parseVaa(vaa); - const action = decodeGovernancePayload(parsedVaa.payload); + const { payload } = deserialize("Uint8Array", new Uint8Array(vaa)); + const action = decodeGovernancePayload(Buffer.from(payload)); if (!action) { console.log("can not decode vaa, skipping"); } else if ( @@ -112,5 +117,4 @@ async function main() { } } -// eslint-disable-next-line @typescript-eslint/no-floating-promises, unicorn/prefer-top-level-await main(); diff --git a/contract_manager/src/core/contracts/iota.ts b/contract_manager/src/core/contracts/iota.ts index 93fca070c3..c41fad34bc 100644 --- a/contract_manager/src/core/contracts/iota.ts +++ b/contract_manager/src/core/contracts/iota.ts @@ -1,13 +1,8 @@ -/* eslint-disable @typescript-eslint/no-unsafe-return */ -/* eslint-disable @typescript-eslint/no-unsafe-call */ -/* eslint-disable @typescript-eslint/no-unsafe-assignment */ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ -/* eslint-disable @typescript-eslint/no-unsafe-member-access */ -/* eslint-disable @typescript-eslint/no-unsafe-argument */ -/* eslint-disable @typescript-eslint/require-await */ -/* eslint-disable @typescript-eslint/restrict-template-expressions */ -/* eslint-disable @typescript-eslint/no-base-to-string */ -import { uint8ArrayToBCS } from "@certusone/wormhole-sdk/lib/cjs/sui"; +import { bcs } from "@iota/iota-sdk/bcs"; + +const uint8ArrayToBCS = (arr: Uint8Array): Uint8Array => + bcs.vector(bcs.u8()).serialize(arr).toBytes(); + import { Ed25519Keypair } from "@iota/iota-sdk/keypairs/ed25519"; import { Transaction } from "@iota/iota-sdk/transactions"; import { IOTA_CLOCK_OBJECT_ID } from "@iota/iota-sdk/utils"; @@ -84,7 +79,7 @@ export class IotaPriceFeedContract extends PriceFeedContract { * @param objectId - the object id to get */ async getPackageId(objectId: ObjectId): Promise { - return this.client.getPackageId(objectId); + return await this.client.getPackageId(objectId); } async getPythPackageId(): Promise { @@ -99,7 +94,7 @@ export class IotaPriceFeedContract extends PriceFeedContract { return `${this.chain.getId()}_${this.stateId}`; } - private async parsePrice(priceInfo: { + private parsePrice(priceInfo: { type: string; fields: { expo: { fields: { magnitude: string; negative: boolean } }; @@ -139,14 +134,12 @@ export class IotaPriceFeedContract extends PriceFeedContract { ); } return { - emaPrice: await this.parsePrice( - // eslint-disable-next-line @typescript-eslint/ban-ts-comment + emaPrice: this.parsePrice( // @ts-ignore priceInfo.data.content.fields.price_info.fields.price_feed.fields .ema_price, ), - price: await this.parsePrice( - // eslint-disable-next-line @typescript-eslint/ban-ts-comment + price: this.parsePrice( // @ts-ignore priceInfo.data.content.fields.price_info.fields.price_feed.fields.price, ), @@ -176,7 +169,7 @@ export class IotaPriceFeedContract extends PriceFeedContract { return this.executeTransaction(tx, keypair); } - async executeUpdatePriceFeed(): Promise { + executeUpdatePriceFeed(): Promise { // We need the feed ids to be able to execute the transaction // it may be possible to get them from the VAA but in batch transactions, // it is also possible to hava fewer feeds that user wants to update compared to @@ -324,7 +317,6 @@ export class IotaPriceFeedContract extends PriceFeedContract { async getValidTimePeriod() { const fields = await this.getStateFields(); - // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore return Number(fields.stale_price_threshold); } @@ -346,7 +338,6 @@ export class IotaPriceFeedContract extends PriceFeedContract { if (result.data.content.dataType !== "moveObject") { throw new Error("Data Sources type mismatch"); } - // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore return result.data.content.fields.value.fields.keys.map( ({ @@ -369,7 +360,6 @@ export class IotaPriceFeedContract extends PriceFeedContract { async getGovernanceDataSource(): Promise { const fields = await this.getStateFields(); - // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore const governanceFields = fields.governance_data_source.fields; const chainId = governanceFields.emitter_chain; @@ -383,14 +373,12 @@ export class IotaPriceFeedContract extends PriceFeedContract { async getBaseUpdateFee() { const fields = await this.getStateFields(); - // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore return { amount: fields.base_update_fee }; } async getLastExecutedGovernanceSequence() { const fields = await this.getStateFields(); - // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore return Number(fields.last_executed_governance_sequence); } @@ -471,8 +459,8 @@ export class IotaWormholeContract extends WormholeContract { // via a Iota transaction due to the linear nature of the language, this is // enforced at the TransactionBlock level by only allowing you to receive // receipts. - async getChainId(): Promise { - return this.chain.getWormholeChainId(); + getChainId(): Promise { + return Promise.resolve(this.chain.getWormholeChainId()); } // NOTE: There's no way to getChain() on the main interface, should update @@ -532,7 +520,6 @@ export class IotaWormholeContract extends WormholeContract { return { id: result.digest, info: result }; } - // eslint-disable-next-line @typescript-eslint/no-explicit-any private async getStateFields(): Promise { const provider = this.chain.getProvider(); const result = await provider.getObject({ diff --git a/contract_manager/src/core/contracts/sui.ts b/contract_manager/src/core/contracts/sui.ts index b751f35307..47748dbeb3 100644 --- a/contract_manager/src/core/contracts/sui.ts +++ b/contract_manager/src/core/contracts/sui.ts @@ -1,14 +1,4 @@ -/* eslint-disable @typescript-eslint/no-unsafe-return */ -/* eslint-disable @typescript-eslint/no-unsafe-call */ -/* eslint-disable @typescript-eslint/no-unsafe-assignment */ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ -/* eslint-disable @typescript-eslint/no-unsafe-member-access */ -/* eslint-disable @typescript-eslint/no-unsafe-argument */ -/* eslint-disable @typescript-eslint/require-await */ -/* eslint-disable @typescript-eslint/restrict-template-expressions */ -/* eslint-disable @typescript-eslint/no-base-to-string */ -import { parseVaa } from "@certusone/wormhole-sdk"; -import { uint8ArrayToBCS } from "@certusone/wormhole-sdk/lib/cjs/sui"; +import { bcs } from "@mysten/sui/bcs"; import { Ed25519Keypair } from "@mysten/sui/keypairs/ed25519"; import { Transaction } from "@mysten/sui/transactions"; import { SUI_CLOCK_OBJECT_ID } from "@mysten/sui/utils"; @@ -19,6 +9,7 @@ import { UpdateTrustedSigner264Bit, UpgradeSuiLazerContract, } from "@pythnetwork/xc-admin-common"; +import { deserialize } from "@wormhole-foundation/sdk-definitions"; import type { Vault } from "../../node/utils/governance"; import { SubmittedWormholeMessage } from "../../node/utils/governance"; import type { DeploymentType, PrivateKey, TxResult } from "../base"; @@ -27,6 +18,9 @@ import type { Chain, SuiLazerMeta } from "../chains"; import { SuiChain } from "../chains"; import { WormholeContract } from "./wormhole"; +const uint8ArrayToBCS = (arr: Uint8Array): Uint8Array => + bcs.vector(bcs.u8()).serialize(arr).toBytes(); + type ObjectId = string; export class SuiPriceFeedContract extends PriceFeedContract { @@ -99,7 +93,7 @@ export class SuiPriceFeedContract extends PriceFeedContract { * @param objectId - the object id to get */ async getPackageId(objectId: ObjectId): Promise { - return this.client.getPackageId(objectId); + return await this.client.getPackageId(objectId); } async getPythPackageId(): Promise { @@ -114,7 +108,7 @@ export class SuiPriceFeedContract extends PriceFeedContract { return `${this.chain.getId()}_${this.stateId}`; } - private async parsePrice(priceInfo: { + private parsePrice(priceInfo: { type: string; fields: { expo: { fields: { magnitude: string; negative: boolean } }; @@ -154,14 +148,12 @@ export class SuiPriceFeedContract extends PriceFeedContract { ); } return { - emaPrice: await this.parsePrice( - // eslint-disable-next-line @typescript-eslint/ban-ts-comment + emaPrice: this.parsePrice( // @ts-ignore priceInfo.data.content.fields.price_info.fields.price_feed.fields .ema_price, ), - price: await this.parsePrice( - // eslint-disable-next-line @typescript-eslint/ban-ts-comment + price: this.parsePrice( // @ts-ignore priceInfo.data.content.fields.price_info.fields.price_feed.fields.price, ), @@ -191,7 +183,7 @@ export class SuiPriceFeedContract extends PriceFeedContract { return this.executeTransaction(tx, keypair); } - async executeUpdatePriceFeed(): Promise { + executeUpdatePriceFeed(): Promise { // We need the feed ids to be able to execute the transaction // it may be possible to get them from the VAA but in batch transactions, // it is also possible to hava fewer feeds that user wants to update compared to @@ -339,7 +331,6 @@ export class SuiPriceFeedContract extends PriceFeedContract { async getValidTimePeriod() { const fields = await this.getStateFields(); - // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore return Number(fields.stale_price_threshold); } @@ -361,7 +352,6 @@ export class SuiPriceFeedContract extends PriceFeedContract { if (result.data.content.dataType !== "moveObject") { throw new Error("Data Sources type mismatch"); } - // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore return result.data.content.fields.value.fields.keys.map( ({ @@ -384,7 +374,6 @@ export class SuiPriceFeedContract extends PriceFeedContract { async getGovernanceDataSource(): Promise { const fields = await this.getStateFields(); - // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore const governanceFields = fields.governance_data_source.fields; const chainId = governanceFields.emitter_chain; @@ -398,14 +387,12 @@ export class SuiPriceFeedContract extends PriceFeedContract { async getBaseUpdateFee() { const fields = await this.getStateFields(); - // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore return { amount: fields.base_update_fee }; } async getLastExecutedGovernanceSequence() { const fields = await this.getStateFields(); - // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore return Number(fields.last_executed_governance_sequence); } @@ -492,8 +479,8 @@ export class SuiWormholeContract extends WormholeContract { // via a Sui transaction due to the linear nature of the language, this is // enforced at the TransactionBlock level by only allowing you to receive // receipts. - async getChainId(): Promise { - return this.chain.getWormholeChainId(); + getChainId(): Promise { + return Promise.resolve(this.chain.getWormholeChainId()); } // NOTE: There's no way to getChain() on the main interface, should update @@ -553,7 +540,6 @@ export class SuiWormholeContract extends WormholeContract { return { id: result.digest, info: result }; } - // eslint-disable-next-line @typescript-eslint/no-explicit-any private async getStateFields(): Promise { const provider = this.chain.getProvider(); const result = await provider.getObject({ @@ -667,7 +653,8 @@ export class SuiLazerContract extends Storable { console_.warn(`Could not find VAA #${i.toString()}, ending.`); break; } - const action = decodeGovernancePayload(parseVaa(vaa).payload); + const { payload } = deserialize("Uint8Array", new Uint8Array(vaa)); + const action = decodeGovernancePayload(Buffer.from(payload)); if (!action) { console_.warn( `Could not parse VAA #${i.toString()} action, skipping...`, diff --git a/contract_manager/src/node/utils/executor.ts b/contract_manager/src/node/utils/executor.ts index 22d45610e4..e1cb73eecb 100644 --- a/contract_manager/src/node/utils/executor.ts +++ b/contract_manager/src/node/utils/executor.ts @@ -1,10 +1,11 @@ -/* eslint-disable no-console */ -import { parseVaa } from "@certusone/wormhole-sdk"; +/** biome-ignore-all lint/suspicious/noConsole: CLI helpers */ import type { DataSource } from "@pythnetwork/xc-admin-common"; import { decodeGovernancePayload, EvmExecute, } from "@pythnetwork/xc-admin-common"; +import { chainToChainId } from "@wormhole-foundation/sdk-base"; +import { deserialize } from "@wormhole-foundation/sdk-definitions"; import type { PrivateKey, TxResult } from "../../core/base.js"; import { EvmChain } from "../../core/chains.js"; import { EvmExecutorContract } from "../../core/contracts/evm.js"; @@ -27,16 +28,15 @@ async function executeForGovernanceContract( vaa: Buffer, senderPrivateKey: PrivateKey, ) { - const parsedVaa = parseVaa(vaa); + const parsedVaa = deserialize("Uint8Array", new Uint8Array(vaa)); const governanceSource = await contract.getGovernanceDataSource(); if ( - governanceSource.emitterAddress === - parsedVaa.emitterAddress.toString("hex") && - governanceSource.emitterChain === parsedVaa.emitterChain + governanceSource.emitterAddress === parsedVaa.emitterAddress.toString() && + governanceSource.emitterChain === chainToChainId(parsedVaa.emitterChain) ) { const lastExecutedSequence = await contract.getLastExecutedGovernanceSequence(); - if (lastExecutedSequence >= parsedVaa.sequence) { + if (BigInt(lastExecutedSequence) >= parsedVaa.sequence) { console.log( `Skipping on contract ${contract.getId()} as it was already executed`, ); @@ -56,8 +56,8 @@ async function executeForGovernanceContract( * @param vaa - src/node/utils/executor.tsthe VAA to execute */ export async function executeVaa(senderPrivateKey: PrivateKey, vaa: Buffer) { - const parsedVaa = parseVaa(vaa); - const action = decodeGovernancePayload(parsedVaa.payload); + const { payload } = deserialize("Uint8Array", new Uint8Array(vaa)); + const action = decodeGovernancePayload(Buffer.from(payload)); if (!action) return; //TODO: handle other actions if (action instanceof EvmExecute) { diff --git a/contract_manager/src/node/utils/governance.ts b/contract_manager/src/node/utils/governance.ts index c892b6fe73..69e8403681 100644 --- a/contract_manager/src/node/utils/governance.ts +++ b/contract_manager/src/node/utils/governance.ts @@ -1,16 +1,4 @@ -/* eslint-disable @typescript-eslint/no-unsafe-argument */ -/* eslint-disable @typescript-eslint/no-explicit-any */ -/* eslint-disable @typescript-eslint/no-unsafe-member-access */ -/* eslint-disable @typescript-eslint/no-unsafe-return */ -/* eslint-disable @typescript-eslint/restrict-template-expressions */ import { readFileSync } from "node:fs"; - -import { - createWormholeProgramInterface, - deriveEmitterSequenceKey, - deriveFeeCollectorKey, - deriveWormholeBridgeDataKey, -} from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole/index.js"; import { AnchorProvider, Wallet } from "@coral-xyz/anchor"; import type { PythCluster } from "@pythnetwork/client"; import { getPythClusterApiUrl } from "@pythnetwork/client"; @@ -35,15 +23,12 @@ import { Transaction, } from "@solana/web3.js"; import SquadsMeshClass from "@sqds/mesh"; +import { utils } from "@wormhole-foundation/sdk-solana-core"; import bs58 from "bs58"; import type { KeyValueConfig } from "../../core/base.js"; import { Storable } from "../../core/base.js"; -// TODO: this should be migrated to @wormhole-foundation/dsk -// as such, we cannot publish an ESM variant of the contract_manager -// until we upgrade - class InvalidTransactionError extends Error { constructor(message: string) { super(message); @@ -188,20 +173,20 @@ export class WormholeEmitter { const wormholeAddress = WORMHOLE_ADDRESS[this.cluster]; if (!wormholeAddress) throw new Error(`Invalid cluster ${this.cluster}`); const kp = Keypair.generate(); - const feeCollector = deriveFeeCollectorKey(wormholeAddress); + const feeCollector = utils.deriveFeeCollectorKey(wormholeAddress); const emitter = this.wallet.publicKey; const accounts = { - bridge: deriveWormholeBridgeDataKey(wormholeAddress), + bridge: utils.deriveWormholeBridgeDataKey(wormholeAddress), clock: SYSVAR_CLOCK_PUBKEY, emitter: emitter, feeCollector, message: kp.publicKey, payer: emitter, rent: SYSVAR_RENT_PUBKEY, - sequence: deriveEmitterSequenceKey(emitter, wormholeAddress), + sequence: utils.deriveEmitterSequenceKey(emitter, wormholeAddress), systemProgram: SystemProgram.programId, }; - const wormholeProgram = createWormholeProgramInterface( + const wormholeProgram = utils.createWormholeProgramInterface( wormholeAddress, provider, ); @@ -349,7 +334,6 @@ export class Vault extends Storable { * Gets the emitter address of the vault * @param registry - registry of RPC nodes to use for each solana network. Defaults to the Solana public RPCs if not provided. */ - // eslint-disable-next-line @typescript-eslint/require-await public async getEmitter(registry: SolanaRpcRegistry = getPythClusterApiUrl) { const mesh = getSquadsMesh(); const squad = mesh.endpoint( @@ -410,7 +394,6 @@ export class Vault extends Storable { * This wallet can be used to connect to a vault and submit proposals * @param walletPath - - path to the wallet file */ -// eslint-disable-next-line @typescript-eslint/require-await export async function loadHotWallet(walletPath: string): Promise { return new Wallet( Keypair.fromSecretKey( diff --git a/contract_manager/src/node/utils/preserve-native-fetch.ts b/contract_manager/src/node/utils/preserve-native-fetch.ts deleted file mode 100644 index aaf544375e..0000000000 --- a/contract_manager/src/node/utils/preserve-native-fetch.ts +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Pin `globalThis.fetch` to Node's native fetch. - * - * `near-api-js@1.1.0` (pulled in transitively by `@certusone/wormhole-sdk`) - * unconditionally replaces `globalThis.fetch` with `node-fetch` at module - * load. That breaks libraries that expect a web `Response.body` exposing - * `getReader()` (e.g. `fuels`, which fails with - * `TypeError: responseClone.body?.getReader is not a function`). - * - * Import this module *before* anything that loads the wormhole SDK. Native - * fetch is available on every Node version we support, so the polyfill is - * never actually needed; we just have to stop libraries from clobbering it. - */ -const nativeFetch = globalThis.fetch; -Object.defineProperty(globalThis, "fetch", { - configurable: true, - get: () => nativeFetch, - set: () => { - // Swallow writes from polyfilling libraries; native fetch works fine. - }, -}); diff --git a/contract_manager/src/node/utils/store.ts b/contract_manager/src/node/utils/store.ts index c9d17f9678..b5a67c4e57 100644 --- a/contract_manager/src/node/utils/store.ts +++ b/contract_manager/src/node/utils/store.ts @@ -1,15 +1,5 @@ -/* eslint-disable no-empty */ -/* eslint-disable tsdoc/syntax */ -/* eslint-disable unicorn/no-array-for-each */ -/* eslint-disable unicorn/no-array-push-push */ -/* eslint-disable @typescript-eslint/no-unsafe-argument */ -/* eslint-disable @typescript-eslint/restrict-template-expressions */ -/* eslint-disable @typescript-eslint/no-unsafe-member-access */ -/* eslint-disable @typescript-eslint/no-unsafe-assignment */ /* biome-ignore-all lint/suspicious/noExplicitAny: legacy code */ /* biome-ignore-all lint/style/noNonNullAssertion: legacy code */ -import "./preserve-native-fetch"; - import { readdirSync, readFileSync, statSync, writeFileSync } from "node:fs"; import type { PriceFeedContract, Storable } from "../../core/base"; import type { Chain } from "../../core/chains"; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ef968206f6..6af91bd8fb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1363,9 +1363,6 @@ importers: contract_manager: dependencies: - '@certusone/wormhole-sdk': - specifier: ^0.9.8 - version: 0.9.24(bufferutil@4.0.9)(encoding@0.1.13)(google-protobuf@3.21.4)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10) '@coral-xyz/anchor': specifier: ^0.29.0 version: 0.29.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) @@ -1453,8 +1450,14 @@ importers: '@types/yargs': specifier: 'catalog:' version: 17.0.33 + '@wormhole-foundation/sdk-base': + specifier: ^4.19.0 + version: 4.19.0 + '@wormhole-foundation/sdk-definitions': + specifier: ^4.19.0 + version: 4.19.0 '@wormhole-foundation/sdk-solana-core': - specifier: ^4.18.0 + specifier: ^4.19.0 version: 4.19.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) aptos: specifier: ^1.5.0