[xc-admin] Add wormhole logic to the crank-executor (#504)
* Add wormhole and fix some bugs * Export WormholeMultisigInstruction * Restore some unrelated parts of the code * Cleanup * Don't change this file
This commit is contained in:
parent
1f64ce52b7
commit
1940a0bb2e
|
@ -1948,7 +1948,8 @@
|
||||||
},
|
},
|
||||||
"node_modules/@certusone/wormhole-sdk": {
|
"node_modules/@certusone/wormhole-sdk": {
|
||||||
"version": "0.9.9",
|
"version": "0.9.9",
|
||||||
"license": "Apache-2.0",
|
"resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk/-/wormhole-sdk-0.9.9.tgz",
|
||||||
|
"integrity": "sha512-seausUXqUIvUN19u4ef0VgMXNvyftQHrq5+A8AHHbsk14oBGRbvQ5JqeI+vgtKUMggK8jCaa/ICR1TnD7MW67Q==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@certusone/wormhole-sdk-proto-web": "0.0.6",
|
"@certusone/wormhole-sdk-proto-web": "0.0.6",
|
||||||
"@certusone/wormhole-sdk-wasm": "^0.0.1",
|
"@certusone/wormhole-sdk-wasm": "^0.0.1",
|
||||||
|
@ -25188,6 +25189,7 @@
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@certusone/wormhole-sdk": "^0.9.9",
|
||||||
"@coral-xyz/anchor": "^0.26.0",
|
"@coral-xyz/anchor": "^0.26.0",
|
||||||
"@pythnetwork/client": "^2.9.0",
|
"@pythnetwork/client": "^2.9.0",
|
||||||
"@solana/web3.js": "^1.73.0",
|
"@solana/web3.js": "^1.73.0",
|
||||||
|
@ -25244,7 +25246,6 @@
|
||||||
"@headlessui/react": "^1.7.7",
|
"@headlessui/react": "^1.7.7",
|
||||||
"@pythnetwork/client": "^2.9.0",
|
"@pythnetwork/client": "^2.9.0",
|
||||||
"@solana/wallet-adapter-base": "^0.9.20",
|
"@solana/wallet-adapter-base": "^0.9.20",
|
||||||
"@solana/wallet-adapter-react": "^0.15.28",
|
|
||||||
"@solana/wallet-adapter-react-ui": "^0.9.27",
|
"@solana/wallet-adapter-react-ui": "^0.9.27",
|
||||||
"@solana/wallet-adapter-wallets": "^0.19.10",
|
"@solana/wallet-adapter-wallets": "^0.19.10",
|
||||||
"@solana/web3.js": "^1.73.0",
|
"@solana/web3.js": "^1.73.0",
|
||||||
|
@ -26402,6 +26403,8 @@
|
||||||
},
|
},
|
||||||
"@certusone/wormhole-sdk": {
|
"@certusone/wormhole-sdk": {
|
||||||
"version": "0.9.9",
|
"version": "0.9.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk/-/wormhole-sdk-0.9.9.tgz",
|
||||||
|
"integrity": "sha512-seausUXqUIvUN19u4ef0VgMXNvyftQHrq5+A8AHHbsk14oBGRbvQ5JqeI+vgtKUMggK8jCaa/ICR1TnD7MW67Q==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@certusone/wormhole-sdk-proto-web": "0.0.6",
|
"@certusone/wormhole-sdk-proto-web": "0.0.6",
|
||||||
"@certusone/wormhole-sdk-wasm": "^0.0.1",
|
"@certusone/wormhole-sdk-wasm": "^0.0.1",
|
||||||
|
@ -33203,6 +33206,7 @@
|
||||||
"crank-executor": {
|
"crank-executor": {
|
||||||
"version": "file:packages/crank-executor",
|
"version": "file:packages/crank-executor",
|
||||||
"requires": {
|
"requires": {
|
||||||
|
"@certusone/wormhole-sdk": "^0.9.9",
|
||||||
"@coral-xyz/anchor": "^0.26.0",
|
"@coral-xyz/anchor": "^0.26.0",
|
||||||
"@pythnetwork/client": "^2.9.0",
|
"@pythnetwork/client": "^2.9.0",
|
||||||
"@solana/web3.js": "^1.73.0",
|
"@solana/web3.js": "^1.73.0",
|
||||||
|
@ -41995,7 +41999,6 @@
|
||||||
"@headlessui/react": "^1.7.7",
|
"@headlessui/react": "^1.7.7",
|
||||||
"@pythnetwork/client": "^2.9.0",
|
"@pythnetwork/client": "^2.9.0",
|
||||||
"@solana/wallet-adapter-base": "^0.9.20",
|
"@solana/wallet-adapter-base": "^0.9.20",
|
||||||
"@solana/wallet-adapter-react": "*",
|
|
||||||
"@solana/wallet-adapter-react-ui": "^0.9.27",
|
"@solana/wallet-adapter-react-ui": "^0.9.27",
|
||||||
"@solana/wallet-adapter-wallets": "^0.19.10",
|
"@solana/wallet-adapter-wallets": "^0.19.10",
|
||||||
"@solana/web3.js": "^1.73.0",
|
"@solana/web3.js": "^1.73.0",
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
"format": "prettier --write \"src/**/*.ts\""
|
"format": "prettier --write \"src/**/*.ts\""
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@certusone/wormhole-sdk": "^0.9.9",
|
||||||
"@coral-xyz/anchor": "^0.26.0",
|
"@coral-xyz/anchor": "^0.26.0",
|
||||||
"@pythnetwork/client": "^2.9.0",
|
"@pythnetwork/client": "^2.9.0",
|
||||||
"@solana/web3.js": "^1.73.0",
|
"@solana/web3.js": "^1.73.0",
|
||||||
|
|
|
@ -1,21 +1,31 @@
|
||||||
import {
|
import {
|
||||||
|
AccountMeta,
|
||||||
Commitment,
|
Commitment,
|
||||||
Connection,
|
Connection,
|
||||||
Keypair,
|
Keypair,
|
||||||
PublicKey,
|
PublicKey,
|
||||||
SendTransactionError,
|
SendTransactionError,
|
||||||
|
SystemProgram,
|
||||||
Transaction,
|
Transaction,
|
||||||
} from "@solana/web3.js";
|
} from "@solana/web3.js";
|
||||||
import SquadsMesh, { DEFAULT_MULTISIG_PROGRAM_ID, getIxPDA } from "@sqds/mesh";
|
import SquadsMesh, { DEFAULT_MULTISIG_PROGRAM_ID, getIxPDA } from "@sqds/mesh";
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import NodeWallet from "@project-serum/anchor/dist/cjs/nodewallet";
|
import NodeWallet from "@project-serum/anchor/dist/cjs/nodewallet";
|
||||||
import { getProposals } from "xc-admin-common";
|
import {
|
||||||
|
getProposals,
|
||||||
|
MultisigParser,
|
||||||
|
WormholeMultisigInstruction,
|
||||||
|
} from "xc-admin-common";
|
||||||
import BN from "bn.js";
|
import BN from "bn.js";
|
||||||
import { AnchorProvider } from "@project-serum/anchor";
|
import { AnchorProvider } from "@project-serum/anchor";
|
||||||
import {
|
import {
|
||||||
getPythClusterApiUrl,
|
getPythClusterApiUrl,
|
||||||
PythCluster,
|
PythCluster,
|
||||||
} from "@pythnetwork/client/lib/cluster";
|
} from "@pythnetwork/client/lib/cluster";
|
||||||
|
import {
|
||||||
|
deriveFeeCollectorKey,
|
||||||
|
getWormholeBridgeData,
|
||||||
|
} from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole";
|
||||||
|
|
||||||
export function envOrErr(env: string): string {
|
export function envOrErr(env: string): string {
|
||||||
const val = process.env[env];
|
const val = process.env[env];
|
||||||
|
@ -42,6 +52,15 @@ async function run() {
|
||||||
wallet: new NodeWallet(KEYPAIR),
|
wallet: new NodeWallet(KEYPAIR),
|
||||||
multisigProgramId: DEFAULT_MULTISIG_PROGRAM_ID,
|
multisigProgramId: DEFAULT_MULTISIG_PROGRAM_ID,
|
||||||
});
|
});
|
||||||
|
const multisigParser = MultisigParser.fromCluster(CLUSTER as PythCluster);
|
||||||
|
const wormholeFee = (
|
||||||
|
await getWormholeBridgeData(
|
||||||
|
squad.connection,
|
||||||
|
multisigParser.wormholeBridgeAddress!,
|
||||||
|
COMMITMENT
|
||||||
|
)
|
||||||
|
).config.fee;
|
||||||
|
|
||||||
const proposals = await getProposals(squad, VAULT, undefined, "executeReady");
|
const proposals = await getProposals(squad, VAULT, undefined, "executeReady");
|
||||||
for (const proposal of proposals) {
|
for (const proposal of proposals) {
|
||||||
// If we have previously cancelled because the proposal was failing, don't attempt
|
// If we have previously cancelled because the proposal was failing, don't attempt
|
||||||
|
@ -51,7 +70,35 @@ async function run() {
|
||||||
i <= proposal.instructionIndex;
|
i <= proposal.instructionIndex;
|
||||||
i++
|
i++
|
||||||
) {
|
) {
|
||||||
const transaction = new Transaction().add(
|
const instructionPda = getIxPDA(
|
||||||
|
proposal.publicKey,
|
||||||
|
new BN(i),
|
||||||
|
squad.multisigProgramId
|
||||||
|
)[0];
|
||||||
|
const instruction = await squad.getInstruction(instructionPda);
|
||||||
|
const parsedInstruction = multisigParser.parseInstruction({
|
||||||
|
programId: instruction.programId,
|
||||||
|
data: instruction.data as Buffer,
|
||||||
|
keys: instruction.keys as AccountMeta[],
|
||||||
|
});
|
||||||
|
const transaction = new Transaction();
|
||||||
|
|
||||||
|
if (
|
||||||
|
parsedInstruction instanceof WormholeMultisigInstruction &&
|
||||||
|
parsedInstruction.name == "postMessage"
|
||||||
|
) {
|
||||||
|
transaction.add(
|
||||||
|
SystemProgram.transfer({
|
||||||
|
lamports: wormholeFee,
|
||||||
|
toPubkey: deriveFeeCollectorKey(
|
||||||
|
multisigParser.wormholeBridgeAddress!
|
||||||
|
),
|
||||||
|
fromPubkey: squad.wallet.publicKey,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
transaction.add(
|
||||||
await squad.buildExecuteInstruction(
|
await squad.buildExecuteInstruction(
|
||||||
proposal.publicKey,
|
proposal.publicKey,
|
||||||
getIxPDA(proposal.publicKey, new BN(i), squad.multisigProgramId)[0]
|
getIxPDA(proposal.publicKey, new BN(i), squad.multisigProgramId)[0]
|
||||||
|
|
|
@ -65,3 +65,6 @@ export class MultisigParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export { WormholeMultisigInstruction } from "./WormholeMultisigInstruction";
|
||||||
|
export { PythMultisigInstruction } from "./PythMultisigInstruction";
|
||||||
|
|
|
@ -3,12 +3,17 @@ import {
|
||||||
PublicKey,
|
PublicKey,
|
||||||
Transaction,
|
Transaction,
|
||||||
TransactionInstruction,
|
TransactionInstruction,
|
||||||
|
SYSVAR_RENT_PUBKEY,
|
||||||
|
SYSVAR_CLOCK_PUBKEY,
|
||||||
|
SystemProgram,
|
||||||
} from "@solana/web3.js";
|
} from "@solana/web3.js";
|
||||||
import { BN } from "bn.js";
|
import { BN } from "bn.js";
|
||||||
import { AnchorProvider } from "@project-serum/anchor";
|
import { AnchorProvider } from "@project-serum/anchor";
|
||||||
import {
|
import {
|
||||||
createWormholeProgramInterface,
|
createWormholeProgramInterface,
|
||||||
getPostMessageAccounts,
|
deriveWormholeBridgeDataKey,
|
||||||
|
deriveEmitterSequenceKey,
|
||||||
|
deriveFeeCollectorKey,
|
||||||
} from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole";
|
} from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole";
|
||||||
import { ExecutePostedVaa } from "./governance_payload/ExecutePostedVaa";
|
import { ExecutePostedVaa } from "./governance_payload/ExecutePostedVaa";
|
||||||
|
|
||||||
|
@ -36,7 +41,6 @@ export async function proposeInstructions(
|
||||||
): Promise<PublicKey> {
|
): Promise<PublicKey> {
|
||||||
const msAccount = await squad.getMultisig(vault);
|
const msAccount = await squad.getMultisig(vault);
|
||||||
let txToSend: Transaction[] = [];
|
let txToSend: Transaction[] = [];
|
||||||
|
|
||||||
const createProposal = new Transaction().add(
|
const createProposal = new Transaction().add(
|
||||||
await squad.buildCreateTransaction(
|
await squad.buildCreateTransaction(
|
||||||
msAccount.publicKey,
|
msAccount.publicKey,
|
||||||
|
@ -61,7 +65,7 @@ export async function proposeInstructions(
|
||||||
vault,
|
vault,
|
||||||
newProposalAddress,
|
newProposalAddress,
|
||||||
instructions[i],
|
instructions[i],
|
||||||
i,
|
i + 1,
|
||||||
wormholeAddress
|
wormholeAddress
|
||||||
);
|
);
|
||||||
txToSend.push(
|
txToSend.push(
|
||||||
|
@ -134,7 +138,7 @@ export async function wrapAsRemoteInstruction(
|
||||||
instructionIndex: number,
|
instructionIndex: number,
|
||||||
wormholeAddress: PublicKey
|
wormholeAddress: PublicKey
|
||||||
): Promise<SquadInstruction> {
|
): Promise<SquadInstruction> {
|
||||||
const emitter = squad.getAuthorityPDA(vault, 0);
|
const emitter = squad.getAuthorityPDA(vault, 1);
|
||||||
|
|
||||||
const [messagePDA, messagePdaBump] = getIxAuthorityPDA(
|
const [messagePDA, messagePdaBump] = getIxAuthorityPDA(
|
||||||
proposalAddress,
|
proposalAddress,
|
||||||
|
@ -156,12 +160,7 @@ export async function wrapAsRemoteInstruction(
|
||||||
instruction,
|
instruction,
|
||||||
]).encode();
|
]).encode();
|
||||||
|
|
||||||
const accounts = getPostMessageAccounts(
|
const accounts = getPostMessageAccounts(wormholeAddress, emitter, messagePDA);
|
||||||
wormholeAddress,
|
|
||||||
emitter,
|
|
||||||
emitter,
|
|
||||||
messagePDA
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
instruction: await wormholeProgram.methods
|
instruction: await wormholeProgram.methods
|
||||||
|
@ -173,3 +172,20 @@ export async function wrapAsRemoteInstruction(
|
||||||
authorityType: "custom",
|
authorityType: "custom",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
function getPostMessageAccounts(
|
||||||
|
wormholeAddress: PublicKey,
|
||||||
|
emitter: PublicKey,
|
||||||
|
message: PublicKey
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
bridge: deriveWormholeBridgeDataKey(wormholeAddress),
|
||||||
|
message,
|
||||||
|
emitter,
|
||||||
|
sequence: deriveEmitterSequenceKey(emitter, wormholeAddress),
|
||||||
|
payer: emitter,
|
||||||
|
feeCollector: deriveFeeCollectorKey(wormholeAddress),
|
||||||
|
clock: SYSVAR_CLOCK_PUBKEY,
|
||||||
|
rent: SYSVAR_RENT_PUBKEY,
|
||||||
|
systemProgram: SystemProgram.programId,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue