@@ -92,7 +92,32 @@ fn main() -> Result<()> {
92
92
& merkle_price_updates[ 0 ] ,
93
93
) ?;
94
94
}
95
+ Action :: PostTwapUpdate {
96
+ start_payload,
97
+ end_payload,
98
+ } => {
99
+ let rpc_client = RpcClient :: new ( url) ;
100
+ let payer =
101
+ read_keypair_file ( & * shellexpand:: tilde ( & keypair) ) . expect ( "Keypair not found" ) ;
95
102
103
+ let start_payload_bytes: Vec < u8 > = base64:: decode ( start_payload) ?;
104
+ let end_payload_bytes: Vec < u8 > = base64:: decode ( end_payload) ?;
105
+
106
+ let ( start_vaa, start_merkle_price_updates) =
107
+ deserialize_accumulator_update_data ( start_payload_bytes) ?;
108
+ let ( end_vaa, end_merkle_price_updates) =
109
+ deserialize_accumulator_update_data ( end_payload_bytes) ?;
110
+
111
+ process_write_encoded_vaa_and_post_twap_update (
112
+ & rpc_client,
113
+ & start_vaa,
114
+ & end_vaa,
115
+ wormhole,
116
+ & payer,
117
+ & start_merkle_price_updates[ 0 ] ,
118
+ & end_merkle_price_updates[ 0 ] ,
119
+ ) ?;
120
+ }
96
121
Action :: InitializeWormholeReceiver { } => {
97
122
let rpc_client = RpcClient :: new ( url) ;
98
123
let payer =
@@ -367,36 +392,174 @@ pub fn process_write_encoded_vaa_and_post_price_update(
367
392
merkle_price_update : & MerklePriceUpdate ,
368
393
) -> Result < Pubkey > {
369
394
let encoded_vaa_keypair = Keypair :: new ( ) ;
395
+
396
+ // Transaction 1: Create and initialize VAA
397
+ let init_instructions = init_encoded_vaa_and_write_initial_data_ixs (
398
+ & payer. pubkey ( ) ,
399
+ vaa,
400
+ & wormhole,
401
+ & encoded_vaa_keypair,
402
+ ) ?;
403
+ process_transaction (
404
+ rpc_client,
405
+ init_instructions,
406
+ & vec ! [ payer, & encoded_vaa_keypair] ,
407
+ ) ?;
408
+
409
+ // Transaction 2: Write remaining VAA data, verify VAA, and post price update
410
+ let price_update_keypair = Keypair :: new ( ) ;
411
+ let mut update_instructions = vec ! [ ComputeBudgetInstruction :: set_compute_unit_limit( 600_000 ) ] ;
412
+
413
+ update_instructions. extend ( write_remaining_data_and_verify_vaa_ixs (
414
+ & payer. pubkey ( ) ,
415
+ vaa,
416
+ & encoded_vaa_keypair. pubkey ( ) ,
417
+ wormhole,
418
+ ) ?) ;
419
+
420
+ update_instructions. push ( pyth_solana_receiver:: instruction:: PostUpdate :: populate (
421
+ payer. pubkey ( ) ,
422
+ payer. pubkey ( ) ,
423
+ encoded_vaa_keypair. pubkey ( ) ,
424
+ price_update_keypair. pubkey ( ) ,
425
+ merkle_price_update. clone ( ) ,
426
+ get_random_treasury_id ( ) ,
427
+ ) ) ;
428
+
429
+ process_transaction (
430
+ rpc_client,
431
+ update_instructions,
432
+ & vec ! [ payer, & price_update_keypair] ,
433
+ ) ?;
434
+
435
+ Ok ( price_update_keypair. pubkey ( ) )
436
+ }
437
+
438
+ /// This function verifies start & end VAAs from Hermes via Wormhole to produce encoded VAAs,
439
+ /// and then posts a TWAP update using the encoded VAAs. Returns the TwapUpdate account pubkey.
440
+ ///
441
+ /// The operation is split up into 4 transactions:
442
+ /// 1. Creates and initializes the start VAA account and writes its first part
443
+ /// 2. Creates and initializes the end VAA account and writes its first part
444
+ /// 3. Writes the remaining data for both VAAs and verifies them
445
+ /// 4. Posts the TWAP update
446
+ pub fn process_write_encoded_vaa_and_post_twap_update (
447
+ rpc_client : & RpcClient ,
448
+ start_vaa : & [ u8 ] ,
449
+ end_vaa : & [ u8 ] ,
450
+ wormhole : Pubkey ,
451
+ payer : & Keypair ,
452
+ start_merkle_price_update : & MerklePriceUpdate ,
453
+ end_merkle_price_update : & MerklePriceUpdate ,
454
+ ) -> Result < Pubkey > {
455
+ // Create keypairs for both encoded VAAs
456
+ let start_encoded_vaa_keypair = Keypair :: new ( ) ;
457
+ let end_encoded_vaa_keypair = Keypair :: new ( ) ;
458
+
459
+ // Transaction 1: Create and initialize start VAA
460
+ let start_init_instructions = init_encoded_vaa_and_write_initial_data_ixs (
461
+ & payer. pubkey ( ) ,
462
+ start_vaa,
463
+ & wormhole,
464
+ & start_encoded_vaa_keypair,
465
+ ) ?;
466
+ process_transaction (
467
+ rpc_client,
468
+ start_init_instructions,
469
+ & vec ! [ payer, & start_encoded_vaa_keypair] ,
470
+ ) ?;
471
+
472
+ // Transaction 2: Create and initialize end VAA
473
+ let end_init_instructions = init_encoded_vaa_and_write_initial_data_ixs (
474
+ & payer. pubkey ( ) ,
475
+ end_vaa,
476
+ & wormhole,
477
+ & end_encoded_vaa_keypair,
478
+ ) ?;
479
+ process_transaction (
480
+ rpc_client,
481
+ end_init_instructions,
482
+ & vec ! [ payer, & end_encoded_vaa_keypair] ,
483
+ ) ?;
484
+
485
+ // Transaction 3: Write remaining VAA data and verify both VAAs
486
+ let mut verify_instructions = vec ! [ ComputeBudgetInstruction :: set_compute_unit_limit( 400_000 ) ] ;
487
+ verify_instructions. extend ( write_remaining_data_and_verify_vaa_ixs (
488
+ & payer. pubkey ( ) ,
489
+ start_vaa,
490
+ & start_encoded_vaa_keypair. pubkey ( ) ,
491
+ wormhole,
492
+ ) ?) ;
493
+ verify_instructions. extend ( write_remaining_data_and_verify_vaa_ixs (
494
+ & payer. pubkey ( ) ,
495
+ end_vaa,
496
+ & end_encoded_vaa_keypair. pubkey ( ) ,
497
+ wormhole,
498
+ ) ?) ;
499
+ process_transaction ( rpc_client, verify_instructions, & vec ! [ payer] ) ?;
500
+
501
+ // Transaction 4: Post TWAP update
502
+ let twap_update_keypair = Keypair :: new ( ) ;
503
+ let post_instructions = vec ! [
504
+ ComputeBudgetInstruction :: set_compute_unit_limit( 400_000 ) ,
505
+ pyth_solana_receiver:: instruction:: PostTwapUpdate :: populate(
506
+ payer. pubkey( ) ,
507
+ payer. pubkey( ) ,
508
+ start_encoded_vaa_keypair. pubkey( ) ,
509
+ end_encoded_vaa_keypair. pubkey( ) ,
510
+ twap_update_keypair. pubkey( ) ,
511
+ start_merkle_price_update. clone( ) ,
512
+ end_merkle_price_update. clone( ) ,
513
+ get_random_treasury_id( ) ,
514
+ ) ,
515
+ ] ;
516
+ process_transaction (
517
+ rpc_client,
518
+ post_instructions,
519
+ & vec ! [ payer, & twap_update_keypair] ,
520
+ ) ?;
521
+
522
+ Ok ( twap_update_keypair. pubkey ( ) )
523
+ }
524
+
525
+ /// Creates instructions to initialize an encoded VAA account and write the first part of the VAA data
526
+ pub fn init_encoded_vaa_and_write_initial_data_ixs (
527
+ payer : & Pubkey ,
528
+ vaa : & [ u8 ] ,
529
+ wormhole : & Pubkey ,
530
+ encoded_vaa_keypair : & Keypair ,
531
+ ) -> Result < Vec < Instruction > > {
370
532
let encoded_vaa_size: usize = vaa. len ( ) + VAA_START ;
371
533
372
534
let create_encoded_vaa = system_instruction:: create_account (
373
- & payer. pubkey ( ) ,
535
+ payer,
374
536
& encoded_vaa_keypair. pubkey ( ) ,
375
537
Rent :: default ( ) . minimum_balance ( encoded_vaa_size) ,
376
538
encoded_vaa_size as u64 ,
377
- & wormhole,
539
+ wormhole,
378
540
) ;
541
+
379
542
let init_encoded_vaa_accounts = wormhole_core_bridge_solana:: accounts:: InitEncodedVaa {
380
- write_authority : payer. pubkey ( ) ,
543
+ write_authority : * payer,
381
544
encoded_vaa : encoded_vaa_keypair. pubkey ( ) ,
382
545
}
383
546
. to_account_metas ( None ) ;
384
547
385
548
let init_encoded_vaa_instruction = Instruction {
386
- program_id : wormhole,
549
+ program_id : * wormhole,
387
550
accounts : init_encoded_vaa_accounts,
388
551
data : wormhole_core_bridge_solana:: instruction:: InitEncodedVaa . data ( ) ,
389
552
} ;
390
553
391
554
let write_encoded_vaa_accounts = wormhole_core_bridge_solana:: accounts:: WriteEncodedVaa {
392
- write_authority : payer. pubkey ( ) ,
555
+ write_authority : * payer,
393
556
draft_vaa : encoded_vaa_keypair. pubkey ( ) ,
394
557
}
395
558
. to_account_metas ( None ) ;
396
559
397
- let write_encoded_vaa_accounts_instruction = Instruction {
398
- program_id : wormhole,
399
- accounts : write_encoded_vaa_accounts. clone ( ) ,
560
+ let write_encoded_vaa_instruction = Instruction {
561
+ program_id : * wormhole,
562
+ accounts : write_encoded_vaa_accounts,
400
563
data : wormhole_core_bridge_solana:: instruction:: WriteEncodedVaa {
401
564
args : WriteEncodedVaaArgs {
402
565
index : 0 ,
@@ -406,18 +569,27 @@ pub fn process_write_encoded_vaa_and_post_price_update(
406
569
. data ( ) ,
407
570
} ;
408
571
409
- // 1st transaction
410
- process_transaction (
411
- rpc_client,
412
- vec ! [
413
- create_encoded_vaa,
414
- init_encoded_vaa_instruction,
415
- write_encoded_vaa_accounts_instruction,
416
- ] ,
417
- & vec ! [ payer, & encoded_vaa_keypair] ,
418
- ) ?;
572
+ Ok ( vec ! [
573
+ create_encoded_vaa,
574
+ init_encoded_vaa_instruction,
575
+ write_encoded_vaa_instruction,
576
+ ] )
577
+ }
578
+
579
+ /// Creates instructions to write remaining VAA data and verify the VAA
580
+ pub fn write_remaining_data_and_verify_vaa_ixs (
581
+ payer : & Pubkey ,
582
+ vaa : & [ u8 ] ,
583
+ encoded_vaa_keypair : & Pubkey ,
584
+ wormhole : Pubkey ,
585
+ ) -> Result < Vec < Instruction > > {
586
+ let write_encoded_vaa_accounts = wormhole_core_bridge_solana:: accounts:: WriteEncodedVaa {
587
+ write_authority : * payer,
588
+ draft_vaa : * encoded_vaa_keypair,
589
+ }
590
+ . to_account_metas ( None ) ;
419
591
420
- let write_encoded_vaa_accounts_instruction_2 = Instruction {
592
+ let write_encoded_vaa_instruction = Instruction {
421
593
program_id : wormhole,
422
594
accounts : write_encoded_vaa_accounts,
423
595
data : wormhole_core_bridge_solana:: instruction:: WriteEncodedVaa {
@@ -432,13 +604,10 @@ pub fn process_write_encoded_vaa_and_post_price_update(
432
604
let ( header, _) : ( Header , Body < & RawMessage > ) = serde_wormhole:: from_slice ( vaa) . unwrap ( ) ;
433
605
let guardian_set = GuardianSet :: key ( & wormhole, header. guardian_set_index ) ;
434
606
435
- let request_compute_units_instruction: Instruction =
436
- ComputeBudgetInstruction :: set_compute_unit_limit ( 600_000 ) ;
437
-
438
607
let verify_encoded_vaa_accounts = wormhole_core_bridge_solana:: accounts:: VerifyEncodedVaaV1 {
439
608
guardian_set,
440
- write_authority : payer. pubkey ( ) ,
441
- draft_vaa : encoded_vaa_keypair. pubkey ( ) ,
609
+ write_authority : * payer,
610
+ draft_vaa : * encoded_vaa_keypair,
442
611
}
443
612
. to_account_metas ( None ) ;
444
613
@@ -448,30 +617,10 @@ pub fn process_write_encoded_vaa_and_post_price_update(
448
617
data : wormhole_core_bridge_solana:: instruction:: VerifyEncodedVaaV1 { } . data ( ) ,
449
618
} ;
450
619
451
- let price_update_keypair = Keypair :: new ( ) ;
452
-
453
- let post_update_instructions = pyth_solana_receiver:: instruction:: PostUpdate :: populate (
454
- payer. pubkey ( ) ,
455
- payer. pubkey ( ) ,
456
- encoded_vaa_keypair. pubkey ( ) ,
457
- price_update_keypair. pubkey ( ) ,
458
- merkle_price_update. clone ( ) ,
459
- get_random_treasury_id ( ) ,
460
- ) ;
461
-
462
- // 2nd transaction
463
- process_transaction (
464
- rpc_client,
465
- vec ! [
466
- request_compute_units_instruction,
467
- write_encoded_vaa_accounts_instruction_2,
468
- verify_encoded_vaa_instruction,
469
- post_update_instructions,
470
- ] ,
471
- & vec ! [ payer, & price_update_keypair] ,
472
- ) ?;
473
-
474
- Ok ( price_update_keypair. pubkey ( ) )
620
+ Ok ( vec ! [
621
+ write_encoded_vaa_instruction,
622
+ verify_encoded_vaa_instruction,
623
+ ] )
475
624
}
476
625
477
626
pub fn process_transaction (
0 commit comments