Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cosmrs: add tx::BodyBuilder #254

Merged
merged 1 commit into from
Aug 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cosmrs/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub enum Error {
/// Expected type URL.
expected: &'static str,

/// Actual type URL found in the [`prost_types::Any`] message.
/// Actual type URL found in the [`crate::Any`] message.
found: String,
},

Expand Down
2 changes: 2 additions & 0 deletions cosmrs/src/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ pub mod mode_info;

mod auth_info;
mod body;
mod builder;
mod fee;
mod msg;
mod raw;
Expand All @@ -115,6 +116,7 @@ mod signer_info;
pub use self::{
auth_info::AuthInfo,
body::Body,
builder::BodyBuilder,
fee::Fee,
mode_info::ModeInfo,
msg::Msg,
Expand Down
9 changes: 7 additions & 2 deletions cosmrs/src/tx/body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@

use crate::{
proto::{self, traits::MessageExt},
ErrorReport, Result,
Any, ErrorReport, Result,
};
use prost_types::Any;
use tendermint::block;

/// [`Body`] of a transaction that all signers sign over.
Expand Down Expand Up @@ -70,6 +69,12 @@ impl Body {
}
}

impl Default for Body {
fn default() -> Body {
Self::new([], "", 0u8)
}
}

impl From<Body> for proto::cosmos::tx::v1beta1::TxBody {
fn from(body: Body) -> proto::cosmos::tx::v1beta1::TxBody {
proto::cosmos::tx::v1beta1::TxBody {
Expand Down
73 changes: 73 additions & 0 deletions cosmrs/src/tx/builder.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//! Transaction builder.

use super::Body;
use crate::Any;
use tendermint::block;

/// Transaction [`Body`] builder which simplifies incrementally assembling and
/// signing a transaction.
#[derive(Clone, Debug, Default)]
pub struct BodyBuilder {
/// Transaction body in-progress.
body: Body,
}

impl BodyBuilder {
/// Create a new transaction builder in the default state.
pub fn new() -> Self {
Self::default()
}

/// Add a message to the transaction.
pub fn msg(&mut self, msg: impl Into<Any>) -> &mut Self {
self.body.messages.push(msg.into());
self
}

/// Add multiple messages to the transaction.
pub fn msgs(&mut self, msgs: impl IntoIterator<Item = Any>) -> &mut Self {
self.body.messages.extend(msgs);
self
}

/// Set the transaction memo.
pub fn memo(&mut self, memo: impl Into<String>) -> &mut Self {
self.body.memo = memo.into();
self
}

/// Set the timeout height.
pub fn timeout_height(&mut self, height: impl Into<block::Height>) -> &mut Self {
self.body.timeout_height = height.into();
self
}

/// Add an extension option.
pub fn extension_option(&mut self, option: impl Into<Any>) -> &mut Self {
self.body.extension_options.push(option.into());
self
}

/// Add a non-critical extension option.
pub fn non_critical_extension_option(&mut self, option: impl Into<Any>) -> &mut Self {
self.body.extension_options.push(option.into());
self
}

/// Return the finished [`Body`].
pub fn finish(&self) -> Body {
self.into()
}
}

impl From<BodyBuilder> for Body {
fn from(builder: BodyBuilder) -> Body {
builder.body
}
}

impl From<&BodyBuilder> for Body {
fn from(builder: &BodyBuilder) -> Body {
builder.body.clone()
}
}
3 changes: 1 addition & 2 deletions cosmrs/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,8 @@ fn msg_send() {
let sequence_number = 0;
let gas = 100_000;
let fee = Fee::from_amount_and_gas(amount, gas);
let timeout_height = 9001u16;

let tx_body = tx::Body::new(vec![msg_send], MEMO, timeout_height);
let tx_body = tx::BodyBuilder::new().msg(msg_send).memo(MEMO).finish();
let auth_info =
SignerInfo::single_direct(Some(sender_public_key), sequence_number).auth_info(fee);
let sign_doc = SignDoc::new(&tx_body, &auth_info, &chain_id, ACCOUNT_NUMBER).unwrap();
Expand Down