Skip to content
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@
* various opinionated UI and UX settings
* feel free to change if you have any strong preferences
*/
"window.commandCenter": false,
"window.commandCenter": true,
"files.autoGuessEncoding": true,
"yaml.schemaStore.enable": true,
"editor.minimap.enabled": false,
Expand Down
22 changes: 15 additions & 7 deletions voyager/modules/state/gno/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,12 +181,20 @@ impl Module {
RpcError::fatal_from_message("block height in graphql response is not a u64")
})?;

let raw_event = res
.pointer("/data/getTransactions/0/response/events/0")
let events = res
.pointer("/data/getTransactions/0/response/events")
.and_then(Value::as_array)
.ok_or_else(|| {
RpcError::fatal_from_message("no response events in graphql response")
})?;

let raw_event = events
.iter()
.find(|event| event.pointer("/type").and_then(Value::as_str) == Some("PacketSend"))
.ok_or_else(|| {
RpcError::fatal_from_message("no PacketSend event in graphql response")
})?;

let event = serde_json::from_value(raw_event.clone())
.map_err(RpcError::fatal("invalid attrs in graphql response"))?;

Expand Down Expand Up @@ -798,11 +806,11 @@ impl StateModuleServer<IbcUnion> for Module {
}
}

// REVIEW: Do I need to do unescaping here?
fn parse_gno_string_object(s: impl AsRef<str>) -> RpcResult<String> {
s.as_ref()
.strip_prefix("(\"")
.and_then(|s| s.strip_suffix("\" string)"))
.map(ToOwned::to_owned)
let s = s.as_ref();
// Handles both old format ("value" string) and new format

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need to support both?

// ("value" gno.land/p/.../types.T, nil error)
s.strip_prefix("(\"")
.and_then(|s| s.find("\" ").map(|end| s[..end].to_owned()))
.ok_or(RpcError::fatal_from_message("invalid string object"))
}
78 changes: 61 additions & 17 deletions voyager/plugins/event-source/gno/src/ibc_events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,21 @@ pub enum IbcEvent {
},

// TODO
BatchSend {},
BatchSend {
packet_hash: H256,
batch_hash: H256,
channel_id: ChannelId,
},

PacketRecv {
packet_hash: H256,
packet_data: Bytes,
destination_channel_id: ChannelId,
maker_msg: Bytes,
},

// TODO

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can remove todo

PacketAck {
packet_hash: H256,
source_channel_id: ChannelId,
source_connection_id: ConnectionId,
source_connection_client_id: ClientId,
Expand All @@ -81,12 +91,10 @@ pub enum IbcEvent {
destination_connection_id: ConnectionId,
destination_connection_client_id: ClientId,
timeout_timestamp: Timestamp,
maker_msg: Bytes,
acknowledgement: Bytes,
maker: String,
},

// TODO
PacketAck {},

WriteAck {
packet_hash: H256,
packet_data: Bytes,
Expand Down Expand Up @@ -141,6 +149,35 @@ impl IbcEvent {
.map_err(RpcError::fatal(format!("error parsing value for key {ty}")))
}

fn chunked_attr(attrs: &[gno_rpc::types::EventAttribute], ty: &str) -> RpcResult<Bytes> {
// If no _size field is present, the value was emitted as a single plain attribute.
let Some(hex_str_len) = attr::<usize>(attrs, &format!("{ty}_size")).ok() else {
return attr(attrs, ty);
};

// Collect raw chunk strings. gno splits the full "0x<hex>" string into
// 4096-char slices, so only chunk[0] carries the "0x" prefix; subsequent
// chunks are bare hex continuations.
let combined: String = (0..)
.map_while(|i| {
attrs
.iter()
.find_map(|a| (a.key == format!("{ty}[{i}]")).then(|| a.value.clone()))
})
.collect();

if combined.len() != hex_str_len {
return Err(RpcError::fatal_from_message(format!(
"key {ty} incomplete: got {} hex chars, expected {hex_str_len}",
combined.len(),
)));
}

combined
.parse::<Bytes>()
.map_err(RpcError::fatal(format!("error parsing hex for key {ty}")))
}

let attrs = gno_event
.attrs
.ok_or_else(|| RpcError::fatal_from_message("no attributes on event"))?;
Expand Down Expand Up @@ -204,35 +241,42 @@ impl IbcEvent {
"ChannelOpenConfirm" => IbcEvent::ChannelOpenConfirm(parse_channel_event(attrs)?),
"PacketRecv" => IbcEvent::PacketRecv {
packet_hash: attr(&attrs, "packet_hash")?,
packet_data: attr(&attrs, "packet_data")?,
destination_channel_id: attr(&attrs, "destination_channel_id")?,
maker_msg: chunked_attr(&attrs, "maker_msg")?,
},
"PacketSend" => IbcEvent::PacketSend {
packet_hash: attr(&attrs, "packet_hash")?,
packet_data: chunked_attr(&attrs, "packet_data")?,
source_channel_id: attr(&attrs, "source_channel_id")?,
source_channel_version: attr(&attrs, "source_channel_version")?,
source_connection_id: attr(&attrs, "source_connection_id")?,
source_connection_client_id: attr(&attrs, "source_connection_client_id")?,
destination_channel_id: attr(&attrs, "destination_channel_id")?,
destination_channel_version: attr(&attrs, "destination_channel_version")?,
destination_connection_id: attr(&attrs, "destination_connection_id")?,
destination_connection_client_id: attr(&attrs, "destination_connection_client_id")?,
timeout_timestamp: attr(&attrs, "timeout_timestamp")?,
maker_msg: attr(&attrs, "maker_msg")?,
},
"PacketSend" => IbcEvent::PacketSend {
"BatchSend" => IbcEvent::BatchSend {
packet_hash: attr(&attrs, "packet_hash")?,
batch_hash: attr(&attrs, "batch_hash")?,
channel_id: attr(&attrs, "channel_id")?,
},
"PacketAck" => IbcEvent::PacketAck {
packet_hash: attr(&attrs, "packet_hash")?,
packet_data: attr(&attrs, "packet_data")?,
source_channel_id: attr(&attrs, "source_channel_id")?,
source_channel_version: attr(&attrs, "source_channel_version")?,
source_connection_id: attr(&attrs, "source_connection_id")?,
source_connection_client_id: attr(&attrs, "source_connection_client_id")?,
destination_channel_id: attr(&attrs, "destination_channel_id")?,
destination_channel_version: attr(&attrs, "destination_channel_version")?,
destination_connection_id: attr(&attrs, "destination_connection_id")?,
destination_connection_client_id: attr(&attrs, "destination_connection_client_id")?,
timeout_timestamp: attr(&attrs, "timeout_timestamp")?,
acknowledgement: chunked_attr(&attrs, "acknowledgement")?,
maker: attr(&attrs, "maker")?,
},
// TODO
"BatchSend" => IbcEvent::BatchSend {},
"PacketAck" => IbcEvent::PacketAck {},
"WriteAck" => IbcEvent::WriteAck {
packet_hash: attr(&attrs, "packet_hash")?,
packet_data: attr(&attrs, "packet_data")?,
packet_data: chunked_attr(&attrs, "packet_data")?,
source_channel_id: attr(&attrs, "source_channel_id")?,
source_connection_id: attr(&attrs, "source_connection_id")?,
source_connection_client_id: attr(&attrs, "source_connection_client_id")?,
Expand All @@ -241,7 +285,7 @@ impl IbcEvent {
destination_connection_id: attr(&attrs, "destination_connection_id")?,
destination_connection_client_id: attr(&attrs, "destination_connection_client_id")?,
timeout_timestamp: attr(&attrs, "timeout_timestamp")?,
acknowledgement: attr(&attrs, "acknowledgement")?,
acknowledgement: chunked_attr(&attrs, "acknowledgement")?,
},
event => {
warn!("unknown event: {event}");
Expand Down
Loading