use std::time::Duration; use foreign_chain_inspector::{ ForeignChainInspector, sui::{ SuiExtractedValue, SuiTransactionDigest, inspector::{SuiExtractor, SuiFinality, SuiInspector}, }, }; use foreign_chain_rpc_interfaces::sui::GrpcSuiClient; use near_mpc_contract_interface::types::SuiAddress; /// The Sui Foundation archive retains full history; regular fullnodes prune the gRPC read /// path after a few weeks, which would age a fixed reference digest out. const PUBLIC_ARCHIVE_URL: &str = "https://archive.mainnet.sui.io"; /// The first epoch-change transaction on Sui mainnet (checkpoint 9769), whose first event /// is `0x3::validator_set::ValidatorEpochInfoEventV2` emitted by the system package `0x3`. /// const CHECKPOINTED_TX_DIGEST: &str = "8eBMXpC8Np7RNDwwiGwSmeev1cSoc7w3fPXdikhH7RZo"; const EXPECTED_EVENT_MODULE: &str = "sui_system"; #[ignore = "manual test: extract an event against the live mainnet RPC provider"] #[tokio::test] async fn inspector_extracts_event_against_live_rpc_provider() { // given let client = GrpcSuiClient::new( PUBLIC_ARCHIVE_URL.to_string(), None, Duration::from_secs(10), ) .unwrap(); let inspector = SuiInspector::new(client); let tx_id = parse_tx_digest(CHECKPOINTED_TX_DIGEST); // when let extracted_values = inspector .extract( tx_id, SuiFinality::Checkpointed, vec![SuiExtractor::Event { event_index: 0 }], ) .await .expect("extract should succeed"); // then assert_eq!(extracted_values.len(), 1); let SuiExtractedValue::Event(event) = &extracted_values[0]; assert_eq!( event.type_tag, format!( "0x{}3::validator_set::ValidatorEpochInfoEventV2", "0".repeat(63) ) ); assert_eq!(event.transaction_module, EXPECTED_EVENT_MODULE); let mut system_package = [0u8; 32]; system_package[31] = 3; assert_eq!(event.package_id, SuiAddress(system_package)); assert_eq!(event.sender, SuiAddress([0u8; 32])); assert!( !event.bcs.is_empty(), "event bcs payload should carry the epoch metrics" ); } fn parse_tx_digest(digest: &str) -> SuiTransactionDigest { let bytes = bs58::decode(digest) .into_vec() .expect("transaction digest should be valid base58"); let array: [u8; 32] = bytes .try_into() .expect("transaction digest should be 32 bytes"); SuiTransactionDigest::from(array) }