1- import { ParsedVaa , parseVaa , postVaaSolana } from "@certusone/wormhole-sdk" ;
1+ import { parseVaa , postVaaSolana } from "@certusone/wormhole-sdk" ;
22import { signTransactionFactory } from "@certusone/wormhole-sdk/lib/cjs/solana" ;
3- import {
4- derivePostedVaaKey ,
5- getPostedVaa ,
6- } from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole" ;
3+ import { derivePostedVaaKey } from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole" ;
74import { AnchorProvider , BN , Program } from "@coral-xyz/anchor" ;
85import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet" ;
9- import { parseProductData } from "@pythnetwork/client" ;
6+ import { AccountType , parseProductData } from "@pythnetwork/client" ;
107import {
118 getPythClusterApiUrl ,
12- getPythProgramKeyForCluster ,
139 PythCluster ,
1410} from "@pythnetwork/client/lib/cluster" ;
1511import {
@@ -18,43 +14,31 @@ import {
1814 Connection ,
1915 Keypair ,
2016 PublicKey ,
21- SystemProgram ,
2217 TransactionInstruction ,
2318} from "@solana/web3.js" ;
2419import * as fs from "fs" ;
2520import {
2621 decodeGovernancePayload ,
2722 ExecutePostedVaa ,
23+ getCreateAccountWithSeedInstruction ,
2824 MultisigParser ,
2925 PythMultisigInstruction ,
3026 WORMHOLE_ADDRESS ,
3127 WORMHOLE_API_ENDPOINT ,
28+ CLAIM_RECORD_SEED ,
29+ mapKey ,
30+ REMOTE_EXECUTOR_ADDRESS ,
31+ envOrErr ,
3232} from "xc_admin_common" ;
3333
34- export function envOrErr ( env : string ) : string {
35- const val = process . env [ env ] ;
36- if ( ! val ) {
37- throw new Error ( `environment variable "${ env } " must be set` ) ;
38- }
39- return String ( process . env [ env ] ) ;
40- }
41-
42- const REMOTE_EXECUTOR_ADDRESS = new PublicKey (
43- "exe6S3AxPVNmy46L4Nj6HrnnAVQUhwyYzMSNcnRn3qq"
44- ) ;
45-
46- const PRODUCT_ACCOUNT_SIZE = 512 ;
47- const PRICE_ACCOUNT_SIZE = 3312 ;
48- const CLAIM_RECORD_SEED = "CLAIM_RECORD" ;
49- const EXECUTOR_KEY_SEED = "EXECUTOR_KEY" ;
5034const CLUSTER : PythCluster = envOrErr ( "CLUSTER" ) as PythCluster ;
51- const COMMITMENT : Commitment =
52- ( process . env . COMMITMENT as Commitment ) ?? "confirmed" ;
53- const OFFSET : number = Number ( process . env . OFFSET ?? "-1" ) ;
5435const EMITTER : PublicKey = new PublicKey ( envOrErr ( "EMITTER" ) ) ;
5536const KEYPAIR : Keypair = Keypair . fromSecretKey (
5637 Uint8Array . from ( JSON . parse ( fs . readFileSync ( envOrErr ( "WALLET" ) , "ascii" ) ) )
5738) ;
39+ const OFFSET : number = Number ( process . env . OFFSET ?? "-1" ) ;
40+ const COMMITMENT : Commitment =
41+ ( process . env . COMMITMENT as Commitment ) ?? "confirmed" ;
5842
5943async function run ( ) {
6044 const provider = new AnchorProvider (
@@ -65,17 +49,15 @@ async function run() {
6549 preflightCommitment : COMMITMENT ,
6650 }
6751 ) ;
52+ const multisigParser = MultisigParser . fromCluster ( CLUSTER ) ;
6853
6954 const remoteExecutor = await Program . at ( REMOTE_EXECUTOR_ADDRESS , provider ) ;
7055
7156 const claimRecordAddress : PublicKey = PublicKey . findProgramAddressSync (
7257 [ Buffer . from ( CLAIM_RECORD_SEED ) , EMITTER . toBuffer ( ) ] ,
7358 remoteExecutor . programId
7459 ) [ 0 ] ;
75- const executorKey : PublicKey = PublicKey . findProgramAddressSync (
76- [ Buffer . from ( EXECUTOR_KEY_SEED ) , EMITTER . toBuffer ( ) ] ,
77- remoteExecutor . programId
78- ) [ 0 ] ;
60+ const executorKey : PublicKey = mapKey ( EMITTER ) ;
7961 const claimRecord = await remoteExecutor . account . claimRecord . fetchNullable (
8062 claimRecordAddress
8163 ) ;
@@ -105,7 +87,6 @@ async function run() {
10587 governancePayload instanceof ExecutePostedVaa &&
10688 governancePayload . targetChainId == "pythnet"
10789 ) {
108- const multisigParser = MultisigParser . fromCluster ( CLUSTER ) ;
10990 const preInstructions : TransactionInstruction [ ] = [ ] ;
11091
11192 console . log ( `Found VAA ${ lastSequenceNumber } , relaying ...` ) ;
@@ -139,25 +120,14 @@ async function run() {
139120 parsedInstruction instanceof PythMultisigInstruction &&
140121 parsedInstruction . name == "addProduct"
141122 ) {
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- ) ;
148123 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- } )
124+ await getCreateAccountWithSeedInstruction (
125+ provider . connection ,
126+ CLUSTER ,
127+ provider . wallet . publicKey ,
128+ parsedInstruction . args . symbol ,
129+ AccountType . Product
130+ )
161131 ) ;
162132 } else if (
163133 parsedInstruction instanceof PythMultisigInstruction &&
@@ -167,28 +137,14 @@ async function run() {
167137 parsedInstruction . accounts . named . productAccount . pubkey
168138 ) ;
169139 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- ) ;
177140 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- } )
141+ await getCreateAccountWithSeedInstruction (
142+ provider . connection ,
143+ CLUSTER ,
144+ provider . wallet . publicKey ,
145+ parseProductData ( productAccount . data ) . product . symbol ,
146+ AccountType . Price
147+ )
192148 ) ;
193149 } else {
194150 throw Error ( "Product account not found" ) ;
@@ -204,22 +160,25 @@ async function run() {
204160 } )
205161 . remainingAccounts ( extraAccountMetas )
206162 . preInstructions ( preInstructions )
207- . rpc ( ) ;
163+ . rpc ( { skipPreflight : true } ) ;
208164 }
209165 } else if ( response . code == 5 ) {
210- console . log ( `Wormhole API failure` ) ;
211- console . log (
212- `${ wormholeApi } /v1/signed_vaa/1/${ EMITTER . toBuffer ( ) . toString (
166+ throw new Error (
167+ `Wormhole API failure :${ wormholeApi } /v1/signed_vaa/1/${ EMITTER . toBuffer ( ) . toString (
213168 "hex"
214169 ) } /${ lastSequenceNumber } `
215170 ) ;
216- break ;
217171 } else {
218172 throw new Error ( "Could not connect to wormhole api" ) ;
219173 }
220174 }
221175}
222176
223177( async ( ) => {
224- await run ( ) ;
178+ try {
179+ await run ( ) ;
180+ } catch ( err ) {
181+ console . error ( err ) ;
182+ throw new Error ( ) ;
183+ }
225184} ) ( ) ;
0 commit comments