diff --git a/src/fixtures/curr_simulation_response.json b/src/fixtures/curr_simulation_response.json new file mode 100644 index 0000000..2d23554 --- /dev/null +++ b/src/fixtures/curr_simulation_response.json @@ -0,0 +1,23 @@ +{ + "jsonrpc": "2.0", + "id": 8675309, + "result": { + "transactionData": "AAAAAAAAAAIAAAAGAAAAASxiqIvl5E+k9crKi8h1V87Ud/UtOOfWNftOQUbizvLRAAAAFAAAAAEAAAAHtG6wcUh/yelE4Mo5xb8iCSWybOS5ZuiiNrZ/Ps7wmesAAAAAAGYCGQAAHmwAAAAAAAAAAAABaUc=", + "minResourceFee": "92487", + "events": [ + "AAAAAQAAAAAAAAAAAAAAAgAAAAAAAAADAAAADwAAAAdmbl9jYWxsAAAAAA0AAAAgLGKoi+XkT6T1ysqLyHVXztR39S0459Y1+05BRuLO8tEAAAAPAAAACWdldF9hZG1pbgAAAAAAAAE=", + "AAAAAQAAAAAAAAABLGKoi+XkT6T1ysqLyHVXztR39S0459Y1+05BRuLO8tEAAAACAAAAAAAAAAIAAAAPAAAACWZuX3JldHVybgAAAAAAAA8AAAAJZ2V0X2FkbWluAAAAAAAAEgAAAAAAAAAAZhscwQWxblWcuoqgH9hR7LnJ7IEonYTcPa9GWIRKJrY=" + ], + "results": [ + { + "auth": [], + "xdr": "AAAAEgAAAAAAAAAAZhscwQWxblWcuoqgH9hR7LnJ7IEonYTcPa9GWIRKJrY=" + } + ], + "cost": { + "cpuInsns": "3685209", + "memBytes": "1751351" + }, + "latestLedger": 53795023 + } + } \ No newline at end of file diff --git a/src/fixtures/curr_transaction_response.json b/src/fixtures/curr_transaction_response.json new file mode 100644 index 0000000..4354719 --- /dev/null +++ b/src/fixtures/curr_transaction_response.json @@ -0,0 +1,40 @@ +{ + "jsonrpc": "2.0", + "id": 8675309, + "result": { + "status": "SUCCESS", + "latestLedger": 53794558, + "latestLedgerCloseTime": "1728063258", + "oldestLedger": 53777279, + "oldestLedgerCloseTime": "1727963878", + "applicationOrder": 251, + "envelopeXdr": "AAAAAgAAAABmGxzBBbFuVZy6iqAf2FHsucnsgSidhNw9r0ZYhEomtgAD0HkDDjo/AABLOQAAAAEAAAAAAAAAAAAAAABnACeAAAAAAAAAAAEAAAAAAAAAGAAAAAAAAAABLGKoi+XkT6T1ysqLyHVXztR39S0459Y1+05BRuLO8tEAAAAJc2V0X3ByaWNlAAAAAAAAAwAAAAMAAAABAAAAAQAAAAkAAAAAAAAAAAAAAAJUC+QAAAAAAQAAAAAAAAAAAAAAASxiqIvl5E+k9crKi8h1V87Ud/UtOOfWNftOQUbizvLRAAAACXNldF9wcmljZQAAAAAAAAMAAAADAAAAAQAAAAEAAAAJAAAAAAAAAAAAAAACVAvkAAAAAAAAAAABAAAAAAAAAAIAAAAGAAAAASxiqIvl5E+k9crKi8h1V87Ud/UtOOfWNftOQUbizvLRAAAAFAAAAAEAAAAHtG6wcUh/yelE4Mo5xb8iCSWybOS5ZuiiNrZ/Ps7wmesAAAABAAAABgAAAAEsYqiL5eRPpPXKyovIdVfO1Hf1LTjn1jX7TkFG4s7y0QAAAAMAAAABAAAAAAA7uNwAAB8EAAAAmAAAAAAAAegOAAAAAYRKJrYAAABARZy4UI+vmHnfij4bZzud6KkNbmRu957Kznc/PmUAwffNq119qbjVPFPZ4TnUP0NlQ/Dev2P5v22UcUor4QF3BQ==", + "resultXdr": "AAAAAAABM+8AAAAAAAAAAQAAAAAAAAAYAAAAAMu8SHUN67hTUJOz3q+IrH9M/4dCVXaljeK6x1Ss20YWAAAAAA==", + "resultMetaXdr": "AAAAAwAAAAAAAAACAAAAAwM01twAAAAAAAAAAGYbHMEFsW5VnLqKoB/YUey5yeyBKJ2E3D2vRliESia2AAAAABXGz6cDDjo/AABLOAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAMAAAAAAzTWcgAAAABnACQBAAAAAAAAAAEDNNbcAAAAAAAAAABmGxzBBbFuVZy6iqAf2FHsucnsgSidhNw9r0ZYhEomtgAAAAAVxs+nAw46PwAASzkAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAADAAAAAAM01twAAAAAZwAmWgAAAAAAAAABAAAABAAAAAMDNNZyAAAACX9bHGhnB1g3wkzCyXp6pYQWTmO7K7AE0UdRZgq/caeEAzVdcgAAAAAAAAABAzTW3AAAAAl/WxxoZwdYN8JMwsl6eqWEFk5juyuwBNFHUWYKv3GnhAM1XdwAAAAAAAAAAwM01nIAAAAGAAAAAAAAAAEsYqiL5eRPpPXKyovIdVfO1Hf1LTjn1jX7TkFG4s7y0QAAAAMAAAABAAAAAAAAABEAAAABAAAAAgAAAA8AAAAJZ2FzX3ByaWNlAAAAAAAACQAAAAAAAAAAAAAAAubSZgwAAAAPAAAABXByaWNlAAAAAAAACQAAAAAAAACCv/mmJzRnAAAAAAAAAAAAAQM01twAAAAGAAAAAAAAAAEsYqiL5eRPpPXKyovIdVfO1Hf1LTjn1jX7TkFG4s7y0QAAAAMAAAABAAAAAAAAABEAAAABAAAAAgAAAA8AAAAJZ2FzX3ByaWNlAAAAAAAACQAAAAAAAAAAAAAAAlQL5AAAAAAPAAAABXByaWNlAAAAAAAACQAAAAAAAACCv/mmJzRnAAAAAAAAAAAAAgAAAAMDNNbcAAAAAAAAAABmGxzBBbFuVZy6iqAf2FHsucnsgSidhNw9r0ZYhEomtgAAAAAVxs+nAw46PwAASzkAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAADAAAAAAM01twAAAAAZwAmWgAAAAAAAAABAzTW3AAAAAAAAAAAZhscwQWxblWcuoqgH9hR7LnJ7IEonYTcPa9GWIRKJrYAAAAAFceEKgMOOj8AAEs5AAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAwAAAAADNNbcAAAAAGcAJloAAAAAAAAAAQAAAAEAAAAAAAAAAAABChEAAAAAAAApegAAAAAAAClSAAAAAAAAAAEAAAAVAAAAAQAAAAAAAAAAAAAAAgAAAAAAAAADAAAADwAAAAdmbl9jYWxsAAAAAA0AAAAgLGKoi+XkT6T1ysqLyHVXztR39S0459Y1+05BRuLO8tEAAAAPAAAACXNldF9wcmljZQAAAAAAABAAAAABAAAAAwAAAAMAAAABAAAAAQAAAAkAAAAAAAAAAAAAAAJUC+QAAAAAAQAAAAAAAAABLGKoi+XkT6T1ysqLyHVXztR39S0459Y1+05BRuLO8tEAAAACAAAAAAAAAAIAAAAPAAAACWZuX3JldHVybgAAAAAAAA8AAAAJc2V0X3ByaWNlAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAgAAAA8AAAAMY29yZV9tZXRyaWNzAAAADwAAAApyZWFkX2VudHJ5AAAAAAAFAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAIAAAAPAAAADGNvcmVfbWV0cmljcwAAAA8AAAALd3JpdGVfZW50cnkAAAAABQAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAAEGxlZGdlcl9yZWFkX2J5dGUAAAAFAAAAAAAAHwQAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAIAAAAPAAAADGNvcmVfbWV0cmljcwAAAA8AAAARbGVkZ2VyX3dyaXRlX2J5dGUAAAAAAAAFAAAAAAAAAJgAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAIAAAAPAAAADGNvcmVfbWV0cmljcwAAAA8AAAANcmVhZF9rZXlfYnl0ZQAAAAAAAAUAAAAAAAAAiAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAgAAAA8AAAAMY29yZV9tZXRyaWNzAAAADwAAAA53cml0ZV9rZXlfYnl0ZQAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAADnJlYWRfZGF0YV9ieXRlAAAAAAAFAAAAAAAAAUwAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAIAAAAPAAAADGNvcmVfbWV0cmljcwAAAA8AAAAPd3JpdGVfZGF0YV9ieXRlAAAAAAUAAAAAAAAAmAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAgAAAA8AAAAMY29yZV9tZXRyaWNzAAAADwAAAA5yZWFkX2NvZGVfYnl0ZQAAAAAABQAAAAAAAB24AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAAD3dyaXRlX2NvZGVfYnl0ZQAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAIAAAAPAAAADGNvcmVfbWV0cmljcwAAAA8AAAAKZW1pdF9ldmVudAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAAD2VtaXRfZXZlbnRfYnl0ZQAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAIAAAAPAAAADGNvcmVfbWV0cmljcwAAAA8AAAAIY3B1X2luc24AAAAFAAAAAAA5LXkAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAIAAAAPAAAADGNvcmVfbWV0cmljcwAAAA8AAAAIbWVtX2J5dGUAAAAFAAAAAAAa59kAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAIAAAAPAAAADGNvcmVfbWV0cmljcwAAAA8AAAARaW52b2tlX3RpbWVfbnNlY3MAAAAAAAAFAAAAAAAGFgkAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAIAAAAPAAAADGNvcmVfbWV0cmljcwAAAA8AAAAPbWF4X3J3X2tleV9ieXRlAAAAAAUAAAAAAAAANAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAgAAAA8AAAAMY29yZV9tZXRyaWNzAAAADwAAABBtYXhfcndfZGF0YV9ieXRlAAAABQAAAAAAAAC0AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAAEG1heF9yd19jb2RlX2J5dGUAAAAFAAAAAAAAHbgAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAIAAAAPAAAADGNvcmVfbWV0cmljcwAAAA8AAAATbWF4X2VtaXRfZXZlbnRfYnl0ZQAAAAAFAAAAAAAAAAA=", + "ledger": 53794524, + "createdAt": "1728063066", + "diagnosticEventsXdr": [ + "AAAAAQAAAAAAAAAAAAAAAgAAAAAAAAADAAAADwAAAAdmbl9jYWxsAAAAAA0AAAAgLGKoi+XkT6T1ysqLyHVXztR39S0459Y1+05BRuLO8tEAAAAPAAAACXNldF9wcmljZQAAAAAAABAAAAABAAAAAwAAAAMAAAABAAAAAQAAAAkAAAAAAAAAAAAAAAJUC+QA", + "AAAAAQAAAAAAAAABLGKoi+XkT6T1ysqLyHVXztR39S0459Y1+05BRuLO8tEAAAACAAAAAAAAAAIAAAAPAAAACWZuX3JldHVybgAAAAAAAA8AAAAJc2V0X3ByaWNlAAAAAAAAAQ==", + "AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAACnJlYWRfZW50cnkAAAAAAAUAAAAAAAAAAw==", + "AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAAC3dyaXRlX2VudHJ5AAAAAAUAAAAAAAAAAQ==", + "AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAAEGxlZGdlcl9yZWFkX2J5dGUAAAAFAAAAAAAAHwQ=", + "AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAAEWxlZGdlcl93cml0ZV9ieXRlAAAAAAAABQAAAAAAAACY", + "AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAADXJlYWRfa2V5X2J5dGUAAAAAAAAFAAAAAAAAAIg=", + "AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAADndyaXRlX2tleV9ieXRlAAAAAAAFAAAAAAAAAAA=", + "AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAADnJlYWRfZGF0YV9ieXRlAAAAAAAFAAAAAAAAAUw=", + "AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAAD3dyaXRlX2RhdGFfYnl0ZQAAAAAFAAAAAAAAAJg=", + "AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAADnJlYWRfY29kZV9ieXRlAAAAAAAFAAAAAAAAHbg=", + "AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAAD3dyaXRlX2NvZGVfYnl0ZQAAAAAFAAAAAAAAAAA=", + "AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAACmVtaXRfZXZlbnQAAAAAAAUAAAAAAAAAAA==", + "AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAAD2VtaXRfZXZlbnRfYnl0ZQAAAAAFAAAAAAAAAAA=", + "AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAACGNwdV9pbnNuAAAABQAAAAAAOS15", + "AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAACG1lbV9ieXRlAAAABQAAAAAAGufZ", + "AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAAEWludm9rZV90aW1lX25zZWNzAAAAAAAABQAAAAAABhYJ", + "AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAAD21heF9yd19rZXlfYnl0ZQAAAAAFAAAAAAAAADQ=", + "AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAAEG1heF9yd19kYXRhX2J5dGUAAAAFAAAAAAAAALQ=", + "AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAAEG1heF9yd19jb2RlX2J5dGUAAAAFAAAAAAAAHbg=", + "AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAAE21heF9lbWl0X2V2ZW50X2J5dGUAAAAABQAAAAAAAAAA" + ] + } + } \ No newline at end of file diff --git a/src/fixtures/transactions_response.json b/src/fixtures/curr_transactions_response.json similarity index 100% rename from src/fixtures/transactions_response.json rename to src/fixtures/curr_transactions_response.json diff --git a/src/lib.rs b/src/lib.rs index 02d566f..0409e26 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -121,7 +121,6 @@ pub struct SendTransactionResponse { #[derive(serde::Deserialize, serde::Serialize, Debug, Clone)] pub struct GetTransactionResponseRaw { - pub status: String, #[serde(rename = "latestLedger")] pub latest_ledger: u32, #[serde( @@ -131,7 +130,10 @@ pub struct GetTransactionResponseRaw { pub latest_ledger_close_time: i64, #[serde(rename = "oldestLedger")] pub oldest_ledger: u32, - #[serde(rename = "oldestLedgerCloseTime")] + #[serde( + rename = "oldestLedgerCloseTime", + deserialize_with = "deserialize_number_from_string" + )] pub oldest_ledger_close_time: u32, #[serde(flatten)] pub transaction_info: TransactionInfoRaw, @@ -139,7 +141,6 @@ pub struct GetTransactionResponseRaw { #[derive(serde::Deserialize, serde::Serialize, Debug, Clone)] pub struct GetTransactionResponse { - pub status: String, pub latest_ledger: u32, pub latest_ledger_close_time: i64, pub oldest_ledger: u32, @@ -152,7 +153,6 @@ impl TryInto for GetTransactionResponseRaw { fn try_into(self) -> Result { Ok(GetTransactionResponse { - status: self.status, latest_ledger: self.latest_ledger, latest_ledger_close_time: self.latest_ledger_close_time, oldest_ledger: self.oldest_ledger, @@ -196,17 +196,27 @@ impl GetTransactionResponse { .filter(|e| matches!(e.event.type_, ContractEventType::Contract)) .collect::>()) } + + pub fn result(&self) -> Option<&xdr::TransactionResult> { + self.transaction_info.result.as_ref() + } + + pub fn result_meta(&self) -> Option<&xdr::TransactionMeta> { + self.transaction_info.result_meta.as_ref() + } + + pub fn envelope(&self) -> Option<&xdr::TransactionEnvelope> { + self.transaction_info.envelope.as_ref() + } } #[derive(serde::Deserialize, serde::Serialize, Debug, Clone)] pub struct TransactionInfoRaw { pub status: String, - #[serde(rename = "txHash")] - pub transaction_hash: String, #[serde(rename = "applicationOrder")] pub application_order: i32, - #[serde(rename = "feeBump")] - pub fee_bump: bool, + #[serde(flatten)] + pub diff: Option, #[serde( rename = "envelopeXdr", skip_serializing_if = "Option::is_none", @@ -235,12 +245,31 @@ pub struct TransactionInfoRaw { pub ledger_close_time: i64, } +#[derive(serde::Deserialize, serde::Serialize, Debug, Clone)] +#[serde(untagged)] +pub enum TransactionInfoDiffRaw { + Protocol22 { + #[serde(rename = "txHash", default, skip_serializing_if = "Option::is_none")] + transaction_hash: Option, + #[serde(rename = "feeBump")] + fee_bump: bool, + }, +} + +#[derive(serde::Deserialize, serde::Serialize, Debug, Clone)] +#[serde(untagged)] +pub enum TransactionInfoDiff { + Protocol22 { + transaction_hash: Option, + fee_bump: bool, + }, +} + #[derive(serde::Deserialize, serde::Serialize, Debug, Clone)] pub struct TransactionInfo { pub status: String, - pub transaction_hash: Hash, pub application_order: i32, - pub fee_bump: bool, + pub diff: Option, pub envelope: Option, pub result: Option, pub result_meta: Option, @@ -254,7 +283,16 @@ impl TryInto for TransactionInfoRaw { fn try_into(self) -> Result { Ok(TransactionInfo { status: self.status, - transaction_hash: self.transaction_hash.parse()?, + diff: match self.diff { + Some(TransactionInfoDiffRaw::Protocol22 { + transaction_hash, + fee_bump, + }) => Some(TransactionInfoDiff::Protocol22 { + transaction_hash: transaction_hash.as_deref().map(str::parse).transpose()?, + fee_bump, + }), + _ => None, + }, envelope: self .envelope_xdr .map(|v| ReadXdr::from_xdr_base64(v, Limits::none())) @@ -268,14 +306,13 @@ impl TryInto for TransactionInfoRaw { .map(|v| ReadXdr::from_xdr_base64(v, Limits::none())) .transpose()?, application_order: self.application_order, - fee_bump: self.fee_bump, ledger: self.ledger, - ledger_close_time: self.ledger_close_time, diagnostic_events_xdr: self .diagnostic_events_xdr .iter() .map(|event| DiagnosticEvent::from_xdr_base64(event, Limits::none())) .collect::, _>>()?, + ledger_close_time: self.ledger_close_time, }) } } @@ -507,14 +544,14 @@ pub struct GetEventsResponseRaw { pub events: Vec, #[serde(rename = "latestLedger")] pub latest_ledger: u32, - pub cusor: String, + pub cusor: Option, } #[derive(serde::Deserialize, serde::Serialize, Debug, Clone)] pub struct GetEventsResponse { pub events: Vec, pub latest_ledger: u32, - pub cusor: String, + pub cusor: Option, } impl TryInto for GetEventsResponseRaw { @@ -580,12 +617,14 @@ pub struct EventRaw { #[serde(rename = "contractId")] pub contract_id: String, pub id: String, - #[serde(rename = "inSuccessfulContractCall")] - pub in_successful_contract_call: bool, + #[serde(rename = "pagingToken")] + pub paging_token: Option, #[serde(rename = "txHash")] - pub transaction_hash: String, pub topic: Vec, pub value: String, + #[serde(rename = "inSuccessfulContractCall")] + pub in_successful_contract_call: bool, + pub transaction_hash: String, } #[derive(serde::Deserialize, serde::Serialize, Debug, Clone)] @@ -595,10 +634,11 @@ pub struct Event { pub ledger_closed_at: String, pub contract_id: String, pub id: String, - pub in_successful_contract_call: bool, - pub transaction_hash: Hash, + pub paging_token: Option, pub topic: Vec, pub value: ScVal, + pub in_successful_contract_call: bool, + pub transaction_hash: Hash, } impl TryInto for EventRaw { @@ -611,14 +651,15 @@ impl TryInto for EventRaw { ledger_closed_at: self.ledger_closed_at, contract_id: self.contract_id, id: self.id, - in_successful_contract_call: self.in_successful_contract_call, - transaction_hash: self.transaction_hash.parse()?, + paging_token: self.paging_token, topic: self .topic .iter() .map(|v| ReadXdr::from_xdr_base64(v, Limits::none())) .collect::>()?, value: ReadXdr::from_xdr_base64(&self.value, Limits::none())?, + in_successful_contract_call: self.in_successful_contract_call, + transaction_hash: self.transaction_hash.parse()?, }) } } @@ -1011,7 +1052,7 @@ impl Client { let mut sleep_time = Duration::from_secs(1); loop { let response = self.get_transaction(tx_id).await?; - match response.status.as_str() { + match response.transaction_info.status.as_str() { "SUCCESS" => { // TODO: the caller should probably be printing this tracing::trace!("{response:#?}"); @@ -1027,7 +1068,9 @@ impl Client { } "NOT_FOUND" => (), _ => { - return Err(Error::UnexpectedTransactionStatus(response.status)); + return Err(Error::UnexpectedTransactionStatus( + response.transaction_info.status, + )); } }; if start.elapsed() > timeout { @@ -1307,26 +1350,25 @@ mod tests { panic!("Could not find repository root"); } - #[test] - fn test_parse_get_transactions_response() { + fn read_fixture_file(filename: &str) -> T { let repo_root = get_repo_root(); - let fixture_path = repo_root - .join("src") - .join("fixtures") - .join("transactions_response.json"); + let fixture_path = repo_root.join("src").join("fixtures").join(filename); let response_content = - fs::read_to_string(fixture_path).expect("Failed to read transactions_response.json"); - + fs::read_to_string(fixture_path).expect("Failed to read fixture file"); // Parse the entire response let full_response: serde_json::Value = serde_json::from_str(&response_content) - .expect("Failed to parse JSON from transactions_response.json"); + .unwrap_or_else(|_| panic!("Failed to parse JSON from {filename}")); // Extract the "result" field let result = full_response["result"].clone(); // Parse the "result" content as GetTransactionsResponseRaw - let raw_response: GetTransactionsResponseRaw = serde_json::from_value(result) - .expect("Failed to parse 'result' into GetTransactionsResponseRaw"); + serde_json::from_value(result).expect("Failed to parse 'result'") + } + #[test] + fn parse_get_transactions_response() { + let raw_response: GetTransactionsResponseRaw = + read_fixture_file("curr_transactions_response.json"); // Convert GetTransactionsResponseRaw to GetTransactionsResponse let response: GetTransactionsResponse = raw_response .try_into() @@ -1339,12 +1381,43 @@ mod tests { // Additional assertions for specific transaction attributes assert_eq!(response.transactions[0].status, "SUCCESS"); - //assert_eq!(response.transactions[0].application_order, 1); - //assert_eq!(response.transactions[0].ledger, 554000); + assert_eq!(response.transactions[0].application_order, 1); + assert_eq!(response.transactions[0].ledger, 554_000); + assert_eq!(response.transactions[0].ledger_close_time, 1_721_053_660); + } + + #[test] + fn parse_get_transaction_response() { + // Parse the "result" content as GetTransactionsResponseRaw + let raw_response: GetTransactionResponseRaw = + read_fixture_file("curr_transaction_response.json"); + // Convert GetTransactionsResponseRaw to GetTransactionsResponse + let response: GetTransactionResponse = raw_response + .try_into() + .expect("Failed to convert GetTransactionsResponseRaw to GetTransactionsResponse"); + assert_eq!(response.transaction_info.diagnostic_events_xdr.len(), 21); + assert_eq!(response.transaction_info.status, "SUCCESS"); + assert_eq!(response.transaction_info.application_order, 251); + assert_eq!(response.transaction_info.ledger_close_time, 1_728_063_066); + assert_eq!(response.latest_ledger, 53_794_558); + assert_eq!(response.oldest_ledger, 53_777_279); + assert_eq!(response.oldest_ledger_close_time, 1_727_963_878); + assert_eq!(response.latest_ledger_close_time, 1_728_063_258); + assert_eq!(response.transaction_info.ledger, 53_794_524); + } + + #[test] + fn parse_curr_simulation_response() { + let raw_response: SimulateTransactionResponse = + read_fixture_file("curr_simulation_response.json"); + assert_eq!(raw_response.min_resource_fee, 92487); + assert_eq!(raw_response.latest_ledger, 53_795_023); + assert_eq!(raw_response.results.len(), 1); + assert_eq!(raw_response.events().unwrap().len(), 2); } #[test] - fn test_rpc_url_default_ports() { + fn rpc_url_default_ports() { // Default ports are added. let client = Client::new("http://example.com").unwrap(); assert_eq!(client.base_url(), "http://example.com:80/"); @@ -1375,7 +1448,7 @@ mod tests { #[test] // Taken from [RPC server // tests](https://github.com/stellar/soroban-tools/blob/main/cmd/soroban-rpc/internal/methods/get_events_test.go#L21). - fn test_does_topic_match() { + fn topic_match() { struct TestCase<'a> { name: &'a str, filter: Vec<&'a str>,