Repository: unionlabs/union
File: cosmwasm/ucs01-relay-api/src/protocol.rs (Rust)

Code before:
#[derive(Error, Debug, PartialEq)]
pub enum ProtocolError {
    #[error("Channel doesn't exist: {channel_id}")]
    NoSuchChannel { channel_id: String },
    #[error("Protocol must be caller")]
    Unauthorized,
}

#[allow(type_alias_bounds)]
pub type PacketExtensionOf<T: TransferProtocol> = <T::Packet as TransferPacket>::Extension;

pub struct TransferInput {
    pub current_time: Timestamp,
    pub timeout_delta: u64,
    pub sender: Addr,
    pub receiver: String,
    pub tokens: Vec<TransferToken>,
}

pub fn token_to_attr(
    TransferToken { denom, amount }: &TransferToken,
) -> Result<Attribute, EncodingError> {
    Ok((
        "denom",
        cosmwasm_std::to_json_string(&Coin::new(*amount, denom))
            .map_err(|_| EncodingError::CoinCouldNotBeEncoded)?,
    )
        .into())
}

// We follow the following module implementation, events and attributes are
// almost 1:1 with the traditional go implementation. As we generalized the base
// implementation for multi-tokens transfer, the events are not containing a
// single ('denom', 'value') and ('amount', 'value') attributes but rather a set
// of ('denom', json_string(('x', '10'))) attributes for each denom `x` with
// amount 10 that is transferred.
// https://github.com/cosmos/ibc-go/blob/7be17857b10457c67cbf66a49e13a9751eb10e8e/modules/apps/transfer/ibc_module.go
pub trait TransferProtocol {
    /// Must be unique per Protocol
    const VERSION: &'static str;
    const ORDERING: IbcOrder;
    /// Must be unique per Protocol
    const RECEIVE_REPLY_ID: u64;

    type Packet: TryFrom<Binary, Error = EncodingError>
        + TryInto<Binary, Error = EncodingError>
        + TransferPacket;

    type Ack: TryFrom<Binary, Error = EncodingError>
        + TryInto<Binary, Error = EncodingError>
        + Into<GenericAck>;

Review comment (bug):
This error should be infallible, serde_json only fails to serialize if there's a map with non-string keys

Code after:
#[derive(Error, Debug, PartialEq)]
pub enum ProtocolError {
    #[error("Channel doesn't exist: {channel_id}")]
    NoSuchChannel { channel_id: String },
    #[error("Protocol must be caller")]
    Unauthorized,
}

#[allow(type_alias_bounds)]
pub type PacketExtensionOf<T: TransferProtocol> = <T::Packet as TransferPacket>::Extension;

pub struct TransferInput {
    pub current_time: Timestamp,
    pub timeout_delta: u64,
    pub sender: Addr,
    pub receiver: String,
    pub tokens: Vec<TransferToken>,
}

pub fn token_to_attr(TransferToken { denom, amount }: &TransferToken) -> Attribute {
    (
        "denom",
        cosmwasm_std::to_json_string(&Coin::new(*amount, denom)).expect("impossible"),
    )
        .into()
}

// We follow the following module implementation, events and attributes are
// almost 1:1 with the traditional go implementation. As we generalized the base
// implementation for multi-tokens transfer, the events are not containing a
// single ('denom', 'value') and ('amount', 'value') attributes but rather a set
// of ('denom', json_string(('x', '10'))) attributes for each denom `x` with
// amount 10 that is transferred.
// https://github.com/cosmos/ibc-go/blob/7be17857b10457c67cbf66a49e13a9751eb10e8e/modules/apps/transfer/ibc_module.go
pub trait TransferProtocol {
    /// Must be unique per Protocol
    const VERSION: &'static str;
    const ORDERING: IbcOrder;
    /// Must be unique per Protocol
    const RECEIVE_REPLY_ID: u64;

    type Packet: TryFrom<Binary, Error = EncodingError>
        + TryInto<Binary, Error = EncodingError>
        + TransferPacket;

    type Ack: TryFrom<Binary, Error = EncodingError>
        + TryInto<Binary, Error = EncodingError>
        + Into<GenericAck>;

    type CustomMsg;