2023-07-28 07:41:41 -07:00
|
|
|
import yargs from "yargs";
|
|
|
|
import { hideBin } from "yargs/helpers";
|
|
|
|
import { DefaultStore } from "../src/store";
|
|
|
|
import { SubmittedWormholeMessage, Vault } from "../src/governance";
|
|
|
|
import { parseVaa } from "@certusone/wormhole-sdk";
|
|
|
|
import { decodeGovernancePayload } from "xc_admin_common";
|
2023-09-06 23:16:14 -07:00
|
|
|
import { toPrivateKey } from "../src";
|
2023-07-28 07:41:41 -07:00
|
|
|
|
|
|
|
const parser = yargs(hideBin(process.argv))
|
|
|
|
.usage(
|
|
|
|
"Tries to execute all vaas on a contract.\n" +
|
|
|
|
"Useful for recently deployed contracts.\n" +
|
|
|
|
"Usage: $0 --contract <contract_id> --private-key <private-key>"
|
|
|
|
)
|
|
|
|
.options({
|
|
|
|
contract: {
|
|
|
|
type: "string",
|
|
|
|
demandOption: true,
|
|
|
|
desc: "Contract to execute governance vaas for",
|
|
|
|
},
|
|
|
|
"private-key": {
|
|
|
|
type: "string",
|
|
|
|
demandOption: true,
|
|
|
|
desc: "Private key to sign the transactions executing the governance VAAs. Hex format, without 0x prefix.",
|
|
|
|
},
|
|
|
|
offset: {
|
|
|
|
type: "number",
|
|
|
|
desc: "Starting sequence number to use, if not provided will start from contract last executed governance sequence number",
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
async function main() {
|
|
|
|
const argv = await parser.argv;
|
|
|
|
const contract = DefaultStore.contracts[argv.contract];
|
|
|
|
if (!contract) {
|
|
|
|
throw new Error(`Contract ${argv.contract} not found`);
|
|
|
|
}
|
|
|
|
const governanceSource = await contract.getGovernanceDataSource();
|
|
|
|
const mainnetVault =
|
|
|
|
DefaultStore.vaults[
|
|
|
|
"mainnet-beta_FVQyHcooAtThJ83XFrNnv74BcinbRH3bRmfFamAHBfuj"
|
|
|
|
];
|
|
|
|
const devnetVault =
|
|
|
|
DefaultStore.vaults["devnet_6baWtW1zTUVMSJHJQVxDUXWzqrQeYBr6mu31j3bTKwY3"];
|
|
|
|
let matchedVault: Vault;
|
|
|
|
if (
|
|
|
|
(await devnetVault.getEmitter()).toBuffer().toString("hex") ===
|
|
|
|
governanceSource.emitterAddress
|
|
|
|
) {
|
|
|
|
console.log("devnet multisig matches governance source");
|
|
|
|
matchedVault = devnetVault;
|
|
|
|
} else if (
|
|
|
|
(await mainnetVault.getEmitter()).toBuffer().toString("hex") ===
|
|
|
|
governanceSource.emitterAddress
|
|
|
|
) {
|
|
|
|
console.log("mainnet multisig matches governance source");
|
|
|
|
matchedVault = mainnetVault;
|
|
|
|
} else {
|
|
|
|
throw new Error(
|
|
|
|
"can not find a multisig that matches the governance source of the contract"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
let lastExecuted = await contract.getLastExecutedGovernanceSequence();
|
|
|
|
console.log("last executed governance sequence", lastExecuted);
|
|
|
|
if (argv.offset && argv.offset > lastExecuted) {
|
|
|
|
console.log("skipping to offset", argv.offset);
|
|
|
|
lastExecuted = argv.offset - 1;
|
|
|
|
}
|
|
|
|
console.log("Starting from sequence number", lastExecuted);
|
|
|
|
while (true) {
|
|
|
|
const submittedWormholeMessage = new SubmittedWormholeMessage(
|
|
|
|
await matchedVault.getEmitter(),
|
|
|
|
lastExecuted + 1,
|
|
|
|
matchedVault.cluster
|
|
|
|
);
|
|
|
|
let vaa: Buffer;
|
|
|
|
try {
|
|
|
|
vaa = await submittedWormholeMessage.fetchVaa();
|
|
|
|
} catch (e) {
|
|
|
|
console.log(e);
|
|
|
|
console.log("no vaa found for sequence", lastExecuted + 1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
const parsedVaa = parseVaa(vaa);
|
|
|
|
const action = decodeGovernancePayload(parsedVaa.payload);
|
|
|
|
if (!action) {
|
|
|
|
console.log("can not decode vaa, skipping");
|
|
|
|
} else if (
|
|
|
|
action.targetChainId === "unset" ||
|
|
|
|
contract.getChain().wormholeChainName === action.targetChainId
|
|
|
|
) {
|
|
|
|
console.log("executing vaa", lastExecuted + 1);
|
2023-09-06 23:16:14 -07:00
|
|
|
await contract.executeGovernanceInstruction(
|
|
|
|
toPrivateKey(argv["private-key"]),
|
|
|
|
vaa
|
|
|
|
);
|
2023-07-28 07:41:41 -07:00
|
|
|
} else {
|
|
|
|
console.log(
|
|
|
|
`vaa is not for this chain (${
|
|
|
|
contract.getChain().wormholeChainName
|
|
|
|
} != ${action.targetChainId}, skipping`
|
|
|
|
);
|
|
|
|
}
|
|
|
|
lastExecuted++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
main();
|