Skip to content

Commit 747886a

Browse files
authored
Xc admin/crank for creating accounts (#568)
* Crank can create accounts * Cleanup * Cleanup * Cleanup * Comment * Done
1 parent d331393 commit 747886a

File tree

1 file changed

+97
-15
lines changed
  • governance/xc_admin/packages/crank_executor/src

1 file changed

+97
-15
lines changed

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

Lines changed: 97 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import {
44
Connection,
55
Keypair,
66
PublicKey,
7-
SendTransactionError,
87
SystemProgram,
98
Transaction,
109
} from "@solana/web3.js";
@@ -14,18 +13,21 @@ import NodeWallet from "@project-serum/anchor/dist/cjs/nodewallet";
1413
import {
1514
getProposals,
1615
MultisigParser,
16+
PythMultisigInstruction,
1717
WormholeMultisigInstruction,
1818
} from "xc_admin_common";
1919
import BN from "bn.js";
2020
import { AnchorProvider } from "@project-serum/anchor";
2121
import {
2222
getPythClusterApiUrl,
23+
getPythProgramKeyForCluster,
2324
PythCluster,
2425
} from "@pythnetwork/client/lib/cluster";
2526
import {
2627
deriveFeeCollectorKey,
2728
getWormholeBridgeData,
2829
} from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole";
30+
import { parseProductData } from "@pythnetwork/client";
2931

3032
export function envOrErr(env: string): string {
3133
const val = process.env[env];
@@ -35,6 +37,9 @@ export function envOrErr(env: string): string {
3537
return String(process.env[env]);
3638
}
3739

40+
const PRODUCT_ACCOUNT_SIZE = 512;
41+
const PRICE_ACCOUNT_SIZE = 3312;
42+
3843
const CLUSTER: string = envOrErr("CLUSTER");
3944
const COMMITMENT: Commitment =
4045
(process.env.COMMITMENT as Commitment) ?? "confirmed";
@@ -65,6 +70,7 @@ async function run() {
6570
: 0;
6671

6772
const proposals = await getProposals(squad, VAULT, undefined, "executeReady");
73+
6874
for (const proposal of proposals) {
6975
console.log("Trying to execute: ", proposal.publicKey.toBase58());
7076
// If we have previously cancelled because the proposal was failing, don't attempt
@@ -100,6 +106,92 @@ async function run() {
100106
fromPubkey: squad.wallet.publicKey,
101107
})
102108
);
109+
} else if (
110+
parsedInstruction instanceof PythMultisigInstruction &&
111+
parsedInstruction.name == "addProduct"
112+
) {
113+
/// Add product, fetch the symbol from updProduct to get the address
114+
i += 1;
115+
const nextInstructionPda = getIxPDA(
116+
proposal.publicKey,
117+
new BN(i),
118+
squad.multisigProgramId
119+
)[0];
120+
const nextInstruction = await squad.getInstruction(
121+
nextInstructionPda
122+
);
123+
const nextParsedInstruction = multisigParser.parseInstruction({
124+
programId: nextInstruction.programId,
125+
data: nextInstruction.data as Buffer,
126+
keys: nextInstruction.keys as AccountMeta[],
127+
});
128+
129+
if (
130+
nextParsedInstruction instanceof PythMultisigInstruction &&
131+
nextParsedInstruction.name == "updProduct"
132+
) {
133+
const productSeed = "product:" + nextParsedInstruction.args.symbol;
134+
const productAddress = await PublicKey.createWithSeed(
135+
squad.wallet.publicKey,
136+
productSeed,
137+
getPythProgramKeyForCluster(CLUSTER as PythCluster)
138+
);
139+
transaction.add(
140+
SystemProgram.createAccountWithSeed({
141+
fromPubkey: squad.wallet.publicKey,
142+
basePubkey: squad.wallet.publicKey,
143+
newAccountPubkey: productAddress,
144+
seed: productSeed,
145+
space: PRODUCT_ACCOUNT_SIZE,
146+
lamports:
147+
await squad.connection.getMinimumBalanceForRentExemption(
148+
PRODUCT_ACCOUNT_SIZE
149+
),
150+
programId: getPythProgramKeyForCluster(CLUSTER as PythCluster),
151+
})
152+
);
153+
transaction.add(
154+
await squad.buildExecuteInstruction(
155+
proposal.publicKey,
156+
getIxPDA(
157+
proposal.publicKey,
158+
new BN(i - 1),
159+
squad.multisigProgramId
160+
)[0]
161+
)
162+
);
163+
}
164+
} else if (
165+
parsedInstruction instanceof PythMultisigInstruction &&
166+
parsedInstruction.name == "addPrice"
167+
) {
168+
/// Add price, fetch the symbol from the product account
169+
const productAccount = await squad.connection.getAccountInfo(
170+
parsedInstruction.accounts.named.productAccount.pubkey
171+
);
172+
if (productAccount?.data) {
173+
const priceSeed =
174+
"price:" + parseProductData(productAccount.data).product.symbol;
175+
const priceAddress = await PublicKey.createWithSeed(
176+
squad.wallet.publicKey,
177+
priceSeed,
178+
getPythProgramKeyForCluster(CLUSTER as PythCluster)
179+
);
180+
transaction.add(
181+
SystemProgram.createAccountWithSeed({
182+
fromPubkey: squad.wallet.publicKey,
183+
basePubkey: squad.wallet.publicKey,
184+
newAccountPubkey: priceAddress,
185+
seed: priceSeed,
186+
space: PRICE_ACCOUNT_SIZE,
187+
lamports:
188+
await squad.connection.getMinimumBalanceForRentExemption(
189+
PRICE_ACCOUNT_SIZE
190+
),
191+
programId: getPythProgramKeyForCluster(CLUSTER as PythCluster),
192+
})
193+
);
194+
}
103195
}
104196

105197
transaction.add(
@@ -109,20 +201,10 @@ async function run() {
109201
)
110202
);
111203

112-
try {
113-
await new AnchorProvider(squad.connection, squad.wallet, {
114-
commitment: COMMITMENT,
115-
preflightCommitment: COMMITMENT,
116-
}).sendAndConfirm(transaction, []);
117-
} catch (error) {
118-
// Mark the transaction as cancelled if we failed to run it
119-
if (error instanceof SendTransactionError) {
120-
console.error(error);
121-
await squad.cancelTransaction(proposal.publicKey);
122-
console.log("Cancelled: ", proposal.publicKey.toBase58());
123-
}
124-
break;
125-
}
204+
await new AnchorProvider(squad.connection, squad.wallet, {
205+
commitment: COMMITMENT,
206+
preflightCommitment: COMMITMENT,
207+
}).sendAndConfirm(transaction, [], { skipPreflight: true });
126208
}
127209
} else {
128210
console.log("Skipping: ", proposal.publicKey.toBase58());

0 commit comments

Comments
 (0)