Skip to content

feat(contract_manager): add support for near contract upgrade #2393

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import yargs from "yargs";
import { hideBin } from "yargs/helpers";
import { DefaultStore, loadHotWallet } from "../src";
import { NearChain } from "../src/chains";

const parser = yargs(hideBin(process.argv))
.usage(
"Creates a governance proposal to upgrade the price feeds contract on Near.\n" +
"Usage: $0 --network <mainnet|testnet> --code-hash <hash> --ops-key-path <ops_key_path>\n"
)
.options({
network: {
type: "string",
choices: ["mainnet", "testnet"],
description: "Network to deploy to",
demandOption: true,
},
"code-hash": {
type: "string",
description: "Sha-256 HEX of the wasm file",
demandOption: true,
},
"ops-key-path": {
type: "string",
description: "Path to operations key file",
demandOption: true,
},
});

async function main() {
const argv = await parser.argv;

// Near wormhole contracts have the same id on testnet and mainnet.
const chain = DefaultStore.chains.near;
if (!(chain instanceof NearChain)) {
throw new Error("Near chain is missing");
}

const vault =
DefaultStore.vaults[
argv.network === "mainnet"
? "mainnet-beta_FVQyHcooAtThJ83XFrNnv74BcinbRH3bRmfFamAHBfuj"
: "devnet_6baWtW1zTUVMSJHJQVxDUXWzqrQeYBr6mu31j3bTKwY3"
];

const codeHash = argv["code-hash"];
if (Buffer.from(codeHash, "hex").length != 32) {
throw new Error("invalid code hash format");
}
console.log(
`Upgrading contract on Near ${argv.network} to code hash: ${codeHash}`
);

// Generate governance payload for the upgrade
const payload = chain.generateGovernanceUpgradePayload(codeHash);
console.log("Governance payload:", payload);

// Create and submit governance proposal
console.log("Using vault for proposal:", vault.getId());
const keypair = await loadHotWallet(argv["ops-key-path"] as string);
console.log("Using wallet:", keypair.publicKey.toBase58());
vault.connect(keypair);
const proposal = await vault.proposeWormholeMessage([payload]);
console.log("Proposal address:", proposal.address.toBase58());
}

main().catch((error) => {
console.error("Error during upgrade:", error);
process.exit(1);
});
42 changes: 31 additions & 11 deletions contract_manager/src/contracts/near.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,12 @@ export class NearWormholeContract extends WormholeContract {
export class NearPriceFeedContract extends PriceFeedContract {
public static type = "NearPriceFeedContract";

constructor(public chain: NearChain, public address: string) {
constructor(
public chain: NearChain,
public address: string,
public governanceDataSource: DataSource,
public lastExecutedGovernanceSequence: number
) {
super();
}

Expand All @@ -108,21 +113,38 @@ export class NearPriceFeedContract extends PriceFeedContract {
return {
chain: this.chain.getId(),
address: this.address,
governanceDataSourceChain: this.governanceDataSource.emitterChain,
governanceDataSourceAddress: this.governanceDataSource.emitterAddress,
lastExecutedGovernanceSequence: this.lastExecutedGovernanceSequence,
type: NearPriceFeedContract.type,
};
}

static fromJson(
chain: Chain,
parsed: { type: string; address: string }
parsed: {
type: string;
address: string;
governanceDataSourceAddress: string;
governanceDataSourceChain: number;
lastExecutedGovernanceSequence: number;
Comment on lines +128 to +130
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder where you are using these 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are used in the corresponding methods of NearPriceFeedContract.

}
): NearPriceFeedContract {
if (parsed.type !== NearPriceFeedContract.type) {
throw new Error("Invalid type");
}
if (!(chain instanceof NearChain)) {
throw new Error(`Wrong chain type ${chain}`);
}
return new NearPriceFeedContract(chain, parsed.address);
return new NearPriceFeedContract(
chain,
parsed.address,
{
emitterAddress: parsed.governanceDataSourceAddress,
emitterChain: parsed.governanceDataSourceChain,
},
parsed.lastExecutedGovernanceSequence
);
}

async getContractNearAccount(
Expand Down Expand Up @@ -251,14 +273,12 @@ export class NearPriceFeedContract extends PriceFeedContract {
getBaseUpdateFee(): Promise<{ amount: string; denom?: string }> {
throw new Error("near contract doesn't implement getBaseUpdateFee method");
}
getLastExecutedGovernanceSequence(): Promise<number> {
throw new Error(
"near contract doesn't implement getLastExecutedGovernanceSequence method"
);
async getLastExecutedGovernanceSequence(): Promise<number> {
// near contract doesn't implement getLastExecutedGovernanceSequence method
return this.lastExecutedGovernanceSequence;
}
getGovernanceDataSource(): Promise<DataSource> {
throw new Error(
"near contract doesn't implement getGovernanceDataSource method"
);
async getGovernanceDataSource(): Promise<DataSource> {
// near contract doesn't implement getGovernanceDataSource method
return this.governanceDataSource;
}
}
6 changes: 6 additions & 0 deletions contract_manager/store/contracts/NearPriceFeedContracts.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
- chain: near
address: pyth-oracle.near
type: NearPriceFeedContract
governanceDataSourceChain: 1
governanceDataSourceAddress: 5635979a221c34931e32620b9293a463065555ea71fe97cd6237ade875b12e9e
lastExecutedGovernanceSequence: 0
- chain: near_testnet
address: pyth-oracle.testnet
type: NearPriceFeedContract
governanceDataSourceChain: 1
governanceDataSourceAddress: 63278d271099bfd491951b3e648f08b1c71631e4a53674ad43e8f9f98068c385
lastExecutedGovernanceSequence: 100
3 changes: 0 additions & 3 deletions governance/xc_admin/packages/xc_admin_common/src/chains.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ import { CHAINS as WORMHOLE_CHAINS } from "@certusone/wormhole-sdk";
export const RECEIVER_CHAINS = {
unset: 0, // The global chain id. For messages that are not chain specific.

// On the following networks we use Wormhole's contract
near: 15,

// On the following networks we use our own version of Wormhole receiver contract
ethereum: 2,
bsc: 4,
Expand Down
Loading