Skip to content

Commit 6d806f7

Browse files
authored
[xc-admin] crank relayer needs to create price and product accounts (#589)
* Add code * Revert
1 parent d95c924 commit 6d806f7

File tree

1 file changed

+74
-0
lines changed
  • governance/xc_admin/packages/crank_pythnet_relayer/src

1 file changed

+74
-0
lines changed

governance/xc_admin/packages/crank_pythnet_relayer/src/index.ts

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ import {
66
} from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole";
77
import { AnchorProvider, BN, Program } from "@coral-xyz/anchor";
88
import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet";
9+
import { parseProductData } from "@pythnetwork/client";
910
import {
1011
getPythClusterApiUrl,
12+
getPythProgramKeyForCluster,
1113
PythCluster,
1214
} from "@pythnetwork/client/lib/cluster";
1315
import {
@@ -16,11 +18,15 @@ import {
1618
Connection,
1719
Keypair,
1820
PublicKey,
21+
SystemProgram,
22+
TransactionInstruction,
1923
} from "@solana/web3.js";
2024
import * as fs from "fs";
2125
import {
2226
decodeGovernancePayload,
2327
ExecutePostedVaa,
28+
MultisigParser,
29+
PythMultisigInstruction,
2430
WORMHOLE_ADDRESS,
2531
WORMHOLE_API_ENDPOINT,
2632
} from "xc_admin_common";
@@ -37,6 +43,8 @@ const REMOTE_EXECUTOR_ADDRESS = new PublicKey(
3743
"exe6S3AxPVNmy46L4Nj6HrnnAVQUhwyYzMSNcnRn3qq"
3844
);
3945

46+
const PRODUCT_ACCOUNT_SIZE = 512;
47+
const PRICE_ACCOUNT_SIZE = 3312;
4048
const CLAIM_RECORD_SEED = "CLAIM_RECORD";
4149
const EXECUTOR_KEY_SEED = "EXECUTOR_KEY";
4250
const CLUSTER: PythCluster = envOrErr("CLUSTER") as PythCluster;
@@ -97,6 +105,9 @@ async function run() {
97105
governancePayload instanceof ExecutePostedVaa &&
98106
governancePayload.targetChainId == "pythnet"
99107
) {
108+
const multisigParser = MultisigParser.fromCluster(CLUSTER);
109+
const preInstructions: TransactionInstruction[] = [];
110+
100111
console.log(`Found VAA ${lastSequenceNumber}, relaying ...`);
101112
await postVaaSolana(
102113
provider.connection,
@@ -110,6 +121,7 @@ async function run() {
110121
let extraAccountMetas: AccountMeta[] = [
111122
{ pubkey: executorKey, isSigner: false, isWritable: true },
112123
];
124+
113125
for (const ix of governancePayload.instructions) {
114126
extraAccountMetas.push({
115127
pubkey: ix.programId,
@@ -121,6 +133,67 @@ async function run() {
121133
return !acc.pubkey.equals(executorKey);
122134
})
123135
);
136+
137+
const parsedInstruction = multisigParser.parseInstruction(ix);
138+
if (
139+
parsedInstruction instanceof PythMultisigInstruction &&
140+
parsedInstruction.name == "addProduct"
141+
) {
142+
const productSeed = "product:" + parsedInstruction.args.symbol;
143+
const productAddress = await PublicKey.createWithSeed(
144+
provider.wallet.publicKey,
145+
productSeed,
146+
getPythProgramKeyForCluster(CLUSTER as PythCluster)
147+
);
148+
preInstructions.push(
149+
SystemProgram.createAccountWithSeed({
150+
fromPubkey: provider.wallet.publicKey,
151+
basePubkey: provider.wallet.publicKey,
152+
newAccountPubkey: productAddress,
153+
seed: productSeed,
154+
space: PRODUCT_ACCOUNT_SIZE,
155+
lamports:
156+
await provider.connection.getMinimumBalanceForRentExemption(
157+
PRODUCT_ACCOUNT_SIZE
158+
),
159+
programId: getPythProgramKeyForCluster(CLUSTER as PythCluster),
160+
})
161+
);
162+
} else if (
163+
parsedInstruction instanceof PythMultisigInstruction &&
164+
parsedInstruction.name == "addPrice"
165+
) {
166+
const productAccount = await provider.connection.getAccountInfo(
167+
parsedInstruction.accounts.named.productAccount.pubkey
168+
);
169+
if (productAccount) {
170+
const priceSeed =
171+
"price:" + parseProductData(productAccount.data).product.symbol;
172+
const priceAddress = await PublicKey.createWithSeed(
173+
provider.wallet.publicKey,
174+
priceSeed,
175+
getPythProgramKeyForCluster(CLUSTER as PythCluster)
176+
);
177+
preInstructions.push(
178+
SystemProgram.createAccountWithSeed({
179+
fromPubkey: provider.wallet.publicKey,
180+
basePubkey: provider.wallet.publicKey,
181+
newAccountPubkey: priceAddress,
182+
seed: priceSeed,
183+
space: PRICE_ACCOUNT_SIZE,
184+
lamports:
185+
await provider.connection.getMinimumBalanceForRentExemption(
186+
PRICE_ACCOUNT_SIZE
187+
),
188+
programId: getPythProgramKeyForCluster(
189+
CLUSTER as PythCluster
190+
),
191+
})
192+
);
193+
} else {
194+
throw Error("Product account not found");
195+
}
196+
}
124197
}
125198

126199
await remoteExecutor.methods
@@ -130,6 +203,7 @@ async function run() {
130203
postedVaa: derivePostedVaaKey(WORMHOLE_ADDRESS[CLUSTER]!, vaa.hash),
131204
})
132205
.remainingAccounts(extraAccountMetas)
206+
.preInstructions(preInstructions)
133207
.rpc();
134208
}
135209
} else if (response.code == 5) {

0 commit comments

Comments
 (0)