diff --git a/ibc-apps/ics20-transfer/src/context.rs b/ibc-apps/ics20-transfer/src/context.rs index 2917c9fe9..ca7611dcd 100644 --- a/ibc-apps/ics20-transfer/src/context.rs +++ b/ibc-apps/ics20-transfer/src/context.rs @@ -8,7 +8,11 @@ use ibc_core::primitives::Signer; /// Methods required in token transfer validation, to be implemented by the host pub trait TokenTransferValidationContext { - type AccountId: TryFrom; + /// Native chain account id. + type AccountId; + + /// Attempt to convert a [`Signer`] to a native chain account id. + fn account_id_from_signer(&self, signer: &Signer) -> Option; /// get_port returns the portID for the transfer module. fn get_port(&self) -> Result; diff --git a/ibc-apps/ics20-transfer/src/handler/mod.rs b/ibc-apps/ics20-transfer/src/handler/mod.rs index f1cd65967..918958792 100644 --- a/ibc-apps/ics20-transfer/src/handler/mod.rs +++ b/ibc-apps/ics20-transfer/src/handler/mod.rs @@ -17,11 +17,9 @@ pub fn refund_packet_token_execute( packet: &Packet, data: &PacketData, ) -> Result<(), TokenTransferError> { - let sender = data - .sender - .clone() - .try_into() - .map_err(|_| TokenTransferError::FailedToParseAccount)?; + let sender = ctx_a + .account_id_from_signer(&data.sender) + .ok_or(TokenTransferError::FailedToParseAccount)?; if is_sender_chain_source( packet.port_id_on_a.clone(), @@ -48,11 +46,9 @@ pub fn refund_packet_token_validate( packet: &Packet, data: &PacketData, ) -> Result<(), TokenTransferError> { - let sender = data - .sender - .clone() - .try_into() - .map_err(|_| TokenTransferError::FailedToParseAccount)?; + let sender = ctx_a + .account_id_from_signer(&data.sender) + .ok_or(TokenTransferError::FailedToParseAccount)?; if is_sender_chain_source( packet.port_id_on_a.clone(), diff --git a/ibc-apps/ics20-transfer/src/handler/on_recv_packet.rs b/ibc-apps/ics20-transfer/src/handler/on_recv_packet.rs index 76e22b3b6..9fa942a90 100644 --- a/ibc-apps/ics20-transfer/src/handler/on_recv_packet.rs +++ b/ibc-apps/ics20-transfer/src/handler/on_recv_packet.rs @@ -23,12 +23,14 @@ pub fn process_recv_packet_execute( .can_receive_coins() .map_err(|err| (ModuleExtras::empty(), err.into()))?; - let receiver_account = data.receiver.clone().try_into().map_err(|_| { - ( - ModuleExtras::empty(), - TokenTransferError::FailedToParseAccount, - ) - })?; + let receiver_account = ctx_b + .account_id_from_signer(&data.receiver) + .ok_or_else(|| { + ( + ModuleExtras::empty(), + TokenTransferError::FailedToParseAccount, + ) + })?; let extras = if is_receiver_chain_source( packet.port_id_on_a.clone(), diff --git a/ibc-apps/ics20-transfer/src/handler/send_transfer.rs b/ibc-apps/ics20-transfer/src/handler/send_transfer.rs index 39d40ea46..6752430f6 100644 --- a/ibc-apps/ics20-transfer/src/handler/send_transfer.rs +++ b/ibc-apps/ics20-transfer/src/handler/send_transfer.rs @@ -56,12 +56,9 @@ where let token = &msg.packet_data.token; - let sender: TokenCtx::AccountId = msg - .packet_data - .sender - .clone() - .try_into() - .map_err(|_| TokenTransferError::FailedToParseAccount)?; + let sender = token_ctx_a + .account_id_from_signer(&msg.packet_data.sender) + .ok_or(TokenTransferError::FailedToParseAccount)?; if is_sender_chain_source( msg.port_id_on_a.clone(), @@ -129,12 +126,9 @@ where let token = &msg.packet_data.token; - let sender = msg - .packet_data - .sender - .clone() - .try_into() - .map_err(|_| TokenTransferError::FailedToParseAccount)?; + let sender = token_ctx_a + .account_id_from_signer(&msg.packet_data.sender) + .ok_or(TokenTransferError::FailedToParseAccount)?; if is_sender_chain_source( msg.port_id_on_a.clone(), diff --git a/ibc-testkit/src/testapp/ibc/applications/transfer/context.rs b/ibc-testkit/src/testapp/ibc/applications/transfer/context.rs index d4a9677ef..b2e2d1c6e 100644 --- a/ibc-testkit/src/testapp/ibc/applications/transfer/context.rs +++ b/ibc-testkit/src/testapp/ibc/applications/transfer/context.rs @@ -9,6 +9,10 @@ use super::types::DummyTransferModule; impl TokenTransferValidationContext for DummyTransferModule { type AccountId = Signer; + fn account_id_from_signer(&self, signer: &Signer) -> Option { + Some(signer.clone()) + } + fn get_port(&self) -> Result { Ok(PortId::transfer()) }