use super::{Msg, TypeName};
use crate::Signature;
use prost_amino::{encode_length_delimiter, Message};
use prost_amino_derive::Message;
use serde::{de, ser, Deserialize, Serialize};
#[derive(Clone, Message)]
pub struct StdTx {
#[prost_amino(bytes, repeated, tag = "1")]
pub msg: Vec<Vec<u8>>,
#[prost_amino(message)]
pub fee: Option<StdFee>,
#[prost_amino(message, repeated)]
pub signatures: Vec<StdSignature>,
#[prost_amino(string)]
pub memo: String,
}
impl StdTx {
pub fn new(
messages: &[Msg],
fee: StdFee,
signatures: Vec<StdSignature>,
memo: impl AsRef<str>,
) -> Self {
Self {
msg: messages.iter().map(|msg| msg.to_amino_bytes()).collect(),
fee: Some(fee),
signatures,
memo: memo.as_ref().to_owned(),
}
}
pub fn to_amino_bytes(&self, type_name: &TypeName) -> Vec<u8> {
let mut amino_tx = type_name.amino_prefix();
self.encode(&mut amino_tx).expect("LEB128 encoding error");
let mut amino_encoded = vec![];
encode_length_delimiter(amino_tx.len(), &mut amino_encoded).expect("LEB128 encoding error");
amino_encoded.append(&mut amino_tx);
amino_encoded
}
}
#[derive(Clone, Message, Deserialize, Serialize)]
pub struct StdFee {
#[prost_amino(message, repeated, tag = "1")]
pub amount: Vec<Coin>,
#[prost_amino(uint64)]
#[serde(serialize_with = "serialize_gas", deserialize_with = "parse_gas")]
pub gas: u64,
}
impl StdFee {
pub fn for_gas(gas: u64) -> Self {
StdFee {
amount: vec![],
gas,
}
}
}
#[derive(Clone, Message, Deserialize, Serialize)]
pub struct Coin {
#[prost_amino(string, tag = "1")]
pub denom: String,
#[prost_amino(string)]
pub amount: String,
}
#[derive(Clone, Message)]
pub struct StdSignature {
#[prost_amino(bytes, tag = "1", amino_name = "tendermint/PubKeySecp256k1")]
pub pub_key: Vec<u8>,
#[prost_amino(bytes)]
pub signature: Vec<u8>,
}
impl From<Signature> for StdSignature {
fn from(signature: Signature) -> StdSignature {
StdSignature {
pub_key: vec![],
signature: signature.as_ref().to_vec(),
}
}
}
fn parse_gas<'de, D>(deserializer: D) -> Result<u64, D::Error>
where
D: de::Deserializer<'de>,
{
String::deserialize(deserializer)?
.parse()
.map_err(serde::de::Error::custom)
}
fn serialize_gas<S>(value: &u64, serializer: S) -> Result<S::Ok, S::Error>
where
S: ser::Serializer,
{
serializer.serialize_str(&value.to_string())
}