scaffold of offlineSign()

This commit is contained in:
mfahampshire
2023-07-03 21:17:29 +00:00
parent 79ee623a1a
commit dfce9ced1d
5 changed files with 120 additions and 33 deletions
@@ -11,11 +11,8 @@ clap = { version = "4.0", features = ["derive"] }
nym-validator-client = { path = "../../common/client-libs/validator-client", features = ["nyxd-client"] }
nym-network-defaults = { path = "../../common/network-defaults" }
async-trait = { workspace = true, optional = true }
bip39 = { workspace = true, features = ["rand"], optional = true }
bip39 = { workspace = true, features = ["rand"] }
cosmrs = { git = "https://github.com/neacsu/cosmos-rust", branch = "neacsu/feegrant_support", features = ["rpc", "bip32", "cosmwasm"] }
[dev-dependencies]
bip39 = { workspace = true }
cosmrs = { git = "https://github.com/neacsu/cosmos-rust", branch = "neacsu/feegrant_support", features = ["rpc", "bip32"] }
tokio = { version = "1.24.1", features = ["rt-multi-thread", "macros"] }
ts-rs = "6.1.2"
@@ -0,0 +1,3 @@
cosmos broadcaster client code - sign txs offline and send thru the mixnet!
heavily pulling from the offline_signing.rs example file in the validator client code (s/o Jon for writing top examples)
@@ -0,0 +1,71 @@
use cosmrs::bip32::secp256k1::elliptic_curve::generic_array::sequence;
use nym_validator_client::nyxd::CosmWasmClient;
use nym_validator_client::signing::direct_wallet::DirectSecp256k1HdWallet;
use nym_validator_client::signing::tx_signer::TxSigner;
use nym_validator_client::signing::SignerData;
use cosmrs::bank::MsgSend;
use cosmrs::rpc::{self, HttpClient};
use cosmrs::tx::Msg;
use cosmrs::{tx, AccountId, Coin, Denom};
use bip39;
pub async fn offline_sign() -> Vec<u8> {
// TODO load most of this from config file, take address and mnemonic from function args, take address and mnemonic from function args. in V2 take chain-id and tx-type as well
let prefix = "n";
let denom: Denom = "unym".parse().unwrap();
let signer_mnemonic: bip39::Mnemonic = "<SOME MNEMONIC>".parse().unwrap();
let validator = "https://qwerty-validator.qa.nymte.ch";
let to_address: AccountId = "n19kdst4srf76xgwe55jg32mpcpcyf6aqgp6qrdk".parse().unwrap();
let signer = DirectSecp256k1HdWallet::from_mnemonic(prefix, signer_mnemonic);
let signer_address = signer.try_derive_accounts().unwrap()[0].address().clone();
// local 'client' ONLY signing messages
let tx_signer = TxSigner::new(signer);
// possibly remote client that doesn't do ANY signing
// (only broadcasts + queries for sequence numbers)
let broadcaster = HttpClient::new(validator).unwrap();
// get signer information
let sequence_response = broadcaster.get_sequence(&signer_address).await.unwrap();
let chain_id = broadcaster.get_chain_id().await.unwrap();
let signer_data = SignerData::new_from_sequence_response(sequence_response, chain_id);
// create (and sign) the send message
let amount = vec![Coin {
denom: denom.clone(),
amount: 12345u32.into(),
}];
let send_msg = MsgSend {
from_address: signer_address.clone(),
to_address: to_address.clone(),
amount,
}
.to_any()
.unwrap();
let memo = "example memo";
let fee = tx::Fee::from_amount_and_gas(
Coin {
denom,
amount: 2500u32.into(),
},
100000,
);
let tx_raw = tx_signer
.sign_direct(&signer_address, vec![send_msg], fee, memo, signer_data)
.unwrap();
// TODO return this from function
let tx_bytes = tx_raw.to_bytes().unwrap();
tx_bytes
}
@@ -0,0 +1 @@
pub mod commands;
@@ -1,17 +1,20 @@
use clap::{CommandFactory, Parser, Subcommand, Args};
use nym_validator_client::nyxd::CosmWasmClient;
use nym_validator_client::signing::direct_wallet::DirectSecp256k1HdWallet;
use nym_validator_client::signing::tx_signer::TxSigner;
use nym_validator_client::signing::SignerData;
use cosmrs::bank::MsgSend;
use cosmrs::rpc::{self, HttpClient};
use cosmrs::tx::Msg;
use cosmrs::{tx, AccountId, Coin, Denom};
// use cosmrs::bip32::secp256k1::elliptic_curve::generic_array::sequence;
// use nym_validator_client::nyxd::CosmWasmClient;
// use nym_validator_client::signing::direct_wallet::DirectSecp256k1HdWallet;
// use nym_validator_client::signing::tx_signer::TxSigner;
// use nym_validator_client::signing::SignerData;
// use cosmrs::bank::MsgSend;
// use cosmrs::rpc::{self, HttpClient};
// use cosmrs::tx::Msg;
// use cosmrs::{tx, AccountId, Coin, Denom};
// use bip39;
mod commands;
#[derive(Debug, Parser)]
#[clap(name = "cosmos tx broadcaster ")]
#[clap(about = "binary which accepts pre-signed txs from the mixnet and broadcasts them to a cosmos sdk chain ")]
#[clap(name = "nym cosmos tx signer ")]
#[clap(about = "binary with which users can perform offline signing and transmission of signed tx to broadcaster via the mixnet ")]
struct Cli {
#[clap(subcommand)]
command: Option<Commands>,
@@ -19,27 +22,39 @@ struct Cli {
#[derive(Debug, Subcommand)]
enum Commands {
/// Reverses a string
Reverse(Reverse),
/// Inspects a string
Inspect(Inspect),
/// sign a transaction offline
OfflineSignTx(OfflineSignTx),
/// send signed tx to SP for broadcast
SendTx(SendTx)
}
#[derive(Debug, Clone, Args)]
struct OfflineSignTx {
/// some random info for testing
string: String,
}
#[derive(Debug, Args)]
struct Reverse {
/// The string to reverse
string: Option<String>,
struct SendTx {
/// the address of the nym service to send yr signed tx
sp_address: String // TODO replace with mixnet address type
}
#[derive(Debug, Args)]
struct Inspect {
/// The string to inspect
string: Option<String>,
#[arg(short = 'd', long = "digits")]
only_digits: bool,
}
#[tokio::main]
async fn main() {
let cli = Cli::parse();
fn main() {
println!("Hello, world!");
}
match &cli.command {
Some(Commands::OfflineSignTx(string)) => {
let tx_bytes = commands::commands::offline_sign();
// TODO parse future
// println!("{}", parsed.iter().format(", "));
println!("end {:?}", string);
}
Some(Commands::SendTx(sp_address)) => {
todo!();
}
None => {}
}
}