Skip to content

Commit 0f7268f

Browse files
authored
feat(cast): decode-event with local and openchain API (#9431)
1 parent 0d76df5 commit 0f7268f

File tree

3 files changed

+66
-11
lines changed

3 files changed

+66
-11
lines changed

crates/cast/bin/args.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -533,8 +533,9 @@ pub enum CastSubcommand {
533533
/// Decode event data.
534534
#[command(visible_aliases = &["event-decode", "--event-decode", "ed"])]
535535
DecodeEvent {
536-
/// The event signature.
537-
sig: String,
536+
/// The event signature. If none provided then tries to decode from local cache or `https://api.openchain.xyz`.
537+
#[arg(long, visible_alias = "event-sig")]
538+
sig: Option<String>,
538539
/// The event data to decode.
539540
data: String,
540541
},

crates/cast/bin/main.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,29 @@ async fn main_args(args: CastArgs) -> Result<()> {
213213
print_tokens(&tokens);
214214
}
215215
CastSubcommand::DecodeEvent { sig, data } => {
216-
let event = get_event(sig.as_str())?;
217-
let decoded_event = event.decode_log_parts(None, &hex::decode(data)?, false)?;
216+
let decoded_event = if let Some(event_sig) = sig {
217+
get_event(event_sig.as_str())?.decode_log_parts(None, &hex::decode(data)?, false)?
218+
} else {
219+
let data = data.strip_prefix("0x").unwrap_or(data.as_str());
220+
let selector = data.get(..64).unwrap_or_default();
221+
let identified_event =
222+
SignaturesIdentifier::new(Config::foundry_cache_dir(), false)?
223+
.write()
224+
.await
225+
.identify_event(&hex::decode(selector)?)
226+
.await;
227+
if let Some(event) = identified_event {
228+
let _ = sh_println!("{}", event.signature());
229+
let data = data.get(64..).unwrap_or_default();
230+
get_event(event.signature().as_str())?.decode_log_parts(
231+
None,
232+
&hex::decode(data)?,
233+
false,
234+
)?
235+
} else {
236+
eyre::bail!("No matching event signature found for selector `{selector}`")
237+
}
238+
};
218239
print_tokens(&decoded_event.body);
219240
}
220241
CastSubcommand::DecodeError { sig, data } => {

crates/cast/tests/cli/main.rs

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1474,15 +1474,35 @@ casttest!(string_decode, |_prj, cmd| {
14741474
"#]]);
14751475
});
14761476

1477-
casttest!(event_decode, |_prj, cmd| {
1478-
cmd.args(["decode-event", "MyEvent(uint256,address)", "0x000000000000000000000000000000000000000000000000000000000000004e0000000000000000000000000000000000000000000000000000000000d0004f"]).assert_success().stdout_eq(str![[r#"
1477+
// tests cast can decode event with provided signature
1478+
casttest!(event_decode_with_sig, |_prj, cmd| {
1479+
cmd.args(["decode-event", "--sig", "MyEvent(uint256,address)", "0x000000000000000000000000000000000000000000000000000000000000004e0000000000000000000000000000000000000000000000000000000000d0004f"]).assert_success().stdout_eq(str![[r#"
14791480
78
14801481
0x0000000000000000000000000000000000D0004F
14811482
1483+
"#]]);
1484+
1485+
cmd.args(["--json"]).assert_success().stdout_eq(str![[r#"
1486+
[
1487+
"78",
1488+
"0x0000000000000000000000000000000000D0004F"
1489+
]
1490+
14821491
"#]]);
14831492
});
14841493

1485-
// tests cast can decode traces with provided signature
1494+
// tests cast can decode event with Openchain API
1495+
casttest!(event_decode_with_openchain, |prj, cmd| {
1496+
prj.clear_cache();
1497+
cmd.args(["decode-event", "0xe27c4c1372396a3d15a9922f74f9dfc7c72b1ad6d63868470787249c356454c1000000000000000000000000000000000000000000000000000000000000004e00000000000000000000000000000000000000000000000000000dd00000004e"]).assert_success().stdout_eq(str![[r#"
1498+
BaseCurrencySet(address,uint256)
1499+
0x000000000000000000000000000000000000004e
1500+
15187004358734 [1.518e13]
1501+
1502+
"#]]);
1503+
});
1504+
1505+
// tests cast can decode error with provided signature
14861506
casttest!(error_decode_with_sig, |_prj, cmd| {
14871507
cmd.args(["decode-error", "--sig", "AnotherValueTooHigh(uint256,address)", "0x7191bc6200000000000000000000000000000000000000000000000000000000000000650000000000000000000000000000000000000000000000000000000000D0004F"]).assert_success().stdout_eq(str![[r#"
14881508
101
@@ -1499,8 +1519,9 @@ casttest!(error_decode_with_sig, |_prj, cmd| {
14991519
"#]]);
15001520
});
15011521

1502-
// tests cast can decode traces with Openchain API
1503-
casttest!(error_decode_with_openchain, |_prj, cmd| {
1522+
// tests cast can decode error with Openchain API
1523+
casttest!(error_decode_with_openchain, |prj, cmd| {
1524+
prj.clear_cache();
15041525
cmd.args(["decode-error", "0x7a0e198500000000000000000000000000000000000000000000000000000000000000650000000000000000000000000000000000000000000000000000000000000064"]).assert_success().stdout_eq(str![[r#"
15051526
ValueTooHigh(uint256,uint256)
15061527
101
@@ -1509,14 +1530,16 @@ ValueTooHigh(uint256,uint256)
15091530
"#]]);
15101531
});
15111532

1512-
// tests cast can decode traces when using local sig identifiers cache
1513-
forgetest!(error_decode_with_cache, |prj, cmd| {
1533+
// tests cast can decode error and event when using local sig identifiers cache
1534+
forgetest!(error_event_decode_with_cache, |prj, cmd| {
1535+
prj.clear_cache();
15141536
foundry_test_utils::util::initialize(prj.root());
15151537
prj.add_source(
15161538
"LocalProjectContract",
15171539
r#"
15181540
contract ContractWithCustomError {
15191541
error AnotherValueTooHigh(uint256, address);
1542+
event MyUniqueEventWithinLocalProject(uint256 a, address b);
15201543
}
15211544
"#,
15221545
)
@@ -1533,6 +1556,16 @@ AnotherValueTooHigh(uint256,address)
15331556
101
15341557
0x0000000000000000000000000000000000D0004F
15351558
1559+
"#]]);
1560+
// Assert cast can decode event with local cache.
1561+
cmd.cast_fuse()
1562+
.args(["decode-event", "0xbd3699995dcc867b64dbb607be2c33be38df9134bef1178df13bfb9446e73104000000000000000000000000000000000000000000000000000000000000004e00000000000000000000000000000000000000000000000000000dd00000004e"])
1563+
.assert_success()
1564+
.stdout_eq(str![[r#"
1565+
MyUniqueEventWithinLocalProject(uint256,address)
1566+
78
1567+
0x00000000000000000000000000000DD00000004e
1568+
15361569
"#]]);
15371570
});
15381571

0 commit comments

Comments
 (0)