Skip to content

Commit 547a58c

Browse files
authored
Merge pull request #61 from fpco/rujira-secured-withdraw
Rujira secured withdraw
2 parents 6ea2596 + 0055711 commit 547a58c

File tree

4 files changed

+145
-8
lines changed

4 files changed

+145
-8
lines changed

packages/cosmos-bin/src/chain.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ use cosmos::{
66
proto::{
77
cosmos::{
88
base::abci::v1beta1::TxResponse,
9-
tx::v1beta1::{AuthInfo, OrderBy, Tx},
9+
tx::v1beta1::{AuthInfo, OrderBy, Tx, TxBody},
1010
},
1111
traits::Message,
12+
Any,
1213
},
1314
Address, BlockInfo, Cosmos, TxResponseExt,
1415
};
@@ -180,7 +181,7 @@ pub(crate) async fn go(Opt { sub }: Opt, opt: crate::cli::Opt) -> Result<()> {
180181
let tx = tx.context("Missing tx field")?;
181182
println!("Encoded length: {}", tx.encoded_len());
182183
let Tx {
183-
body: _,
184+
body,
184185
auth_info,
185186
signatures: _,
186187
} = Tx::decode(&*tx.value)?;
@@ -201,6 +202,20 @@ pub(crate) async fn go(Opt { sub }: Opt, opt: crate::cli::Opt) -> Result<()> {
201202
println!();
202203
println!("Signer count: {}", signer_infos.len());
203204
if complete {
205+
let TxBody {
206+
messages,
207+
memo,
208+
timeout_height: _,
209+
extension_options: _,
210+
non_critical_extension_options: _,
211+
} = body.context("No body provided")?;
212+
println!("Memo: {memo}");
213+
for (idx, Any { type_url, value }) in messages.into_iter().enumerate() {
214+
println!(
215+
"Message #{idx}: {type_url}: {}",
216+
String::from_utf8_lossy(&value)
217+
);
218+
}
204219
println!("Data: {data}");
205220
for (idx, log) in logs.into_iter().enumerate() {
206221
println!("Log #{idx}: {log:?}");

packages/cosmos-bin/src/rujira.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
use anyhow::Result;
2+
use cosmos::{HasAddress, HasAddressHrp, TxBuilder};
3+
4+
use crate::cli::TxOpt;
25

36
#[derive(clap::Parser)]
47
pub(crate) enum Subcommand {
@@ -9,20 +12,47 @@ pub(crate) enum Subcommand {
912
},
1013
/// Print information about all pools
1114
Pools {},
15+
/// Withdraw secured assets
16+
Withdraw {
17+
chain: String,
18+
symbol: String,
19+
amount: u128,
20+
destination: String,
21+
#[clap(flatten)]
22+
tx_opt: TxOpt,
23+
},
1224
}
1325

1426
pub(crate) async fn go(opt: crate::cli::Opt, inner: Subcommand) -> Result<()> {
27+
let cosmos = opt.network_opt.build().await?;
1528
match inner {
1629
Subcommand::Pool { asset } => {
17-
let cosmos = opt.network_opt.build().await?;
1830
let x = cosmos.rujira_pool(asset).await?;
1931
println!("{x:#?}");
2032
}
2133
Subcommand::Pools {} => {
22-
let cosmos = opt.network_opt.build().await?;
2334
let x = cosmos.rujira_pools().await?;
2435
println!("{x:#?}");
2536
}
37+
Subcommand::Withdraw {
38+
chain,
39+
symbol,
40+
amount,
41+
destination,
42+
tx_opt,
43+
} => {
44+
let wallet = tx_opt.get_wallet(cosmos.get_address_hrp())?;
45+
let mut builder = TxBuilder::default();
46+
builder.add_message(cosmos::rujira::MsgDeposit {
47+
chain,
48+
symbol,
49+
amount,
50+
destination,
51+
signer: wallet.get_address(),
52+
});
53+
let res = builder.sign_and_broadcast(&cosmos, &wallet).await?;
54+
println!("txhash: {}", res.txhash);
55+
}
2656
}
2757

2858
Ok(())

packages/cosmos/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ mod ext;
3131
mod gas_multiplier;
3232
mod injective;
3333
mod parsed_coin;
34-
mod rujira;
34+
/// Contains Rujira-specific messages.
35+
pub mod rujira;
3536
mod tokenfactory;
3637
mod txbuilder;
3738
mod wallet;

packages/cosmos/src/rujira.rs

Lines changed: 94 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1+
use prost::Message;
12
use tonic::{async_trait, GrpcMethod};
23

34
use crate::{
45
client::{node::Node, query::GrpcRequest},
56
error::Action,
6-
Cosmos,
7+
Address, Cosmos, TxMessage,
78
};
89

910
impl Cosmos {
@@ -117,13 +118,16 @@ impl GrpcRequest for QueryPoolsRequest {
117118
}
118119

119120
#[derive(Clone, PartialEq, ::prost::Message)]
120-
pub struct QueryPoolRequest {
121+
pub(crate) struct QueryPoolRequest {
121122
#[prost(string, tag = "1")]
122123
pub asset: ::prost::alloc::string::String,
123124
#[prost(string, tag = "2")]
124125
pub height: ::prost::alloc::string::String,
125126
}
127+
128+
/// Response with information on a THORChain pool.
126129
#[derive(Clone, PartialEq, ::prost::Message)]
130+
#[allow(missing_docs)]
127131
pub struct QueryPoolResponse {
128132
#[prost(string, tag = "1")]
129133
pub asset: ::prost::alloc::string::String,
@@ -188,12 +192,99 @@ pub struct QueryPoolResponse {
188192
pub derived_depth_bps: ::prost::alloc::string::String,
189193
}
190194
#[derive(Clone, PartialEq, ::prost::Message)]
191-
pub struct QueryPoolsRequest {
195+
pub(crate) struct QueryPoolsRequest {
192196
#[prost(string, tag = "1")]
193197
pub height: ::prost::alloc::string::String,
194198
}
195199
#[derive(Clone, PartialEq, ::prost::Message)]
200+
#[allow(missing_docs)]
196201
pub struct QueryPoolsResponse {
197202
#[prost(message, repeated, tag = "1")]
198203
pub pools: ::prost::alloc::vec::Vec<QueryPoolResponse>,
199204
}
205+
206+
#[derive(Clone, PartialEq, ::prost::Message)]
207+
struct MsgDepositInner {
208+
#[prost(message, repeated, tag = "1")]
209+
coins: Vec<RujiraCoin>,
210+
#[prost(string, tag = "2")]
211+
memo: String,
212+
#[prost(bytes, tag = "3")]
213+
signer: Vec<u8>,
214+
}
215+
216+
#[derive(Clone, PartialEq, ::prost::Message)]
217+
struct RujiraCoin {
218+
#[prost(message, tag = "1")]
219+
asset: Option<RujiraAsset>,
220+
#[prost(string, tag = "2")]
221+
amount: String,
222+
#[prost(int64, tag = "3")]
223+
decimals: i64,
224+
}
225+
226+
#[derive(Clone, PartialEq, ::prost::Message)]
227+
struct RujiraAsset {
228+
#[prost(string, tag = "1")]
229+
chain: String,
230+
#[prost(string, tag = "2")]
231+
symbol: String,
232+
#[prost(string, tag = "3")]
233+
ticker: String,
234+
#[prost(bool, tag = "4")]
235+
synth: bool,
236+
#[prost(bool, tag = "5")]
237+
trade: bool,
238+
#[prost(bool, tag = "6")]
239+
secured: bool,
240+
}
241+
242+
/// A Rujira `MsgDeposit`, used for withdrawing secured assets.
243+
pub struct MsgDeposit {
244+
/// Chain to withdraw to
245+
pub chain: String,
246+
/// Symbol to withdraw
247+
pub symbol: String,
248+
/// Amount of asset to withdraw, given in 10e-8 units
249+
pub amount: u128,
250+
/// Destination to send the asset to
251+
pub destination: String,
252+
/// Account sending the funds
253+
pub signer: Address,
254+
}
255+
256+
impl From<MsgDeposit> for TxMessage {
257+
fn from(
258+
MsgDeposit {
259+
chain,
260+
symbol,
261+
amount,
262+
destination,
263+
signer,
264+
}: MsgDeposit,
265+
) -> Self {
266+
let description =
267+
format!("Withdraw secured assets: {amount}{chain}-{symbol} to {destination}");
268+
TxMessage::new(
269+
"/types.MsgDeposit",
270+
MsgDepositInner {
271+
coins: vec![RujiraCoin {
272+
asset: Some(RujiraAsset {
273+
chain,
274+
symbol: symbol.clone(),
275+
ticker: symbol,
276+
synth: false,
277+
trade: false,
278+
secured: true,
279+
}),
280+
amount: amount.to_string(),
281+
decimals: 0,
282+
}],
283+
memo: format!("secure-:{destination}"),
284+
signer: signer.raw().as_ref().to_owned(),
285+
}
286+
.encode_to_vec(),
287+
description,
288+
)
289+
}
290+
}

0 commit comments

Comments
 (0)