removed old cargo projects

This commit is contained in:
mfahampshire
2023-07-13 13:43:19 +02:00
parent 509b31ad93
commit 3ec9c3b216
12 changed files with 0 additions and 558 deletions
@@ -1,26 +0,0 @@
[package]
name = "rust-cosmos-broadcaster-client"
version = "0.1.0"
authors.workspace = true
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
clap = { version = "4.0", features = ["derive"] }
nym-bin-common = { path = "../../common/bin-common"}
nym-sphinx-addressing = { path = "../../common/nymsphinx/addressing" }
nym-sdk = { path = "../../sdk/rust/nym-sdk" }
nym-crypto = { path = "../../common/crypto" }
nym-cli-commands = { path = "../../common/commands" }
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"] }
cosmrs = { git = "https://github.com/neacsu/cosmos-rust", branch = "neacsu/feegrant_support", features = ["rpc", "bip32", "cosmwasm"] }
tokio = { version = "1.24.1", features = ["rt-multi-thread", "macros"] }
ts-rs = "6.1.2"
bs58 = "0.5.0"
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
anyhow.workspace = true
@@ -1,3 +0,0 @@
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) & the nym-cli tool (:hattip: mr vez)
@@ -1,121 +0,0 @@
use nym_sphinx_addressing::clients::Recipient;
use nym_validator_client::signing::direct_wallet::DirectSecp256k1HdWallet;
use nym_validator_client::signing::tx_signer::TxSigner;
use nym_validator_client::signing::SignerData;
use nym_validator_client::nyxd::cosmwasm_client::types;
use cosmrs::bank::MsgSend;
use cosmrs::tx::Msg;
use cosmrs::{tx, AccountId, Coin, Denom};
use bip39;
use bs58;
use nym_sdk::mixnet::{self, MixnetClient, ReconstructedMessage};
use crate::commands::reqres::{SequenceRequest, ResponseTypes, self, BroadcastRequest};
pub async fn offline_sign(mnemonic: bip39::Mnemonic, to: AccountId, client: &mut MixnetClient , sp_address: Recipient) -> String {
// TODO take coin amount from function args, + load network vars from config file.
let prefix = "n";
let denom: Denom = "unym".parse().unwrap();
let validator = String::from("https://qwerty-validator.qa.nymte.ch");
let signer = DirectSecp256k1HdWallet::from_mnemonic(prefix, mnemonic.clone());
let signer_address = signer.try_derive_accounts().unwrap()[0].address().clone();
// local 'client' ONLY signing messages
let tx_signer = TxSigner::new(signer);
let message = SequenceRequest{
validator,
signer_address,
};
// send req to client
client.send_str(sp_address, &serde_json::to_string(&message).unwrap()).await;
// handle incoming message - we presume its a reply from the SP
let mut message: Vec<ReconstructedMessage> = Vec::new();
// get the actual message - discard the empty vec sent along with the SURB request
while let Some(new_message) = client.wait_for_messages().await {
if new_message.is_empty() {
continue;
} println!("got a response");
message = new_message;
break
}
// convert from vec<u8> -> JSON String
let mut parsed = String::new();
for r in message.iter() {
parsed = String::from_utf8(r.message.clone()).unwrap();
break
};
let sp_response: ResponseTypes = serde_json::from_str(&parsed).unwrap();
let res = match sp_response {
reqres::ResponseTypes::Sequence(request) => {
println!("got a response to the chain sequence request. using this to sign our tx offline");
// use the response to create SignerData instance
let sequence_response = types::SequenceResponse {
account_number: request.account_number,
sequence: request.sequence
};
let signer_data = SignerData::new_from_sequence_response( sequence_response, request.chain_id);
// create (and sign) the send message
let amount = vec![Coin {
denom: denom.clone(),
amount: 12345u32.into(),
}];
// TODO there must be a better way of doing this instead of re-generating the signer address from the mnemonic twice
let signer = DirectSecp256k1HdWallet::from_mnemonic(prefix, mnemonic.clone());
let signer_address = signer.try_derive_accounts().unwrap()[0].address().clone();
let send_msg = MsgSend {
from_address: signer_address.clone(),
to_address: to.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();
let tx_bytes = tx_raw.to_bytes().unwrap();
let base58_tx_bytes = bs58::encode(tx_bytes).into_string();
base58_tx_bytes
},
// TODO make this a proper error
_ => { println!("weird response"); String::from("placeholder error") }
};
res
}
pub async fn send_tx(base58_tx: String, sp_address: Recipient, client: &mut MixnetClient) -> Option<Vec<mixnet::ReconstructedMessage>> {
let broadcast_request = BroadcastRequest {
base58_tx_bytes: base58_tx
};
client.send_str(sp_address, &serde_json::to_string(&broadcast_request).unwrap()).await;
println!("\nWaiting for reply\n");
let res = client.wait_for_messages().await;
res
}
@@ -1,39 +0,0 @@
use serde::{Deserialize, Serialize};
use cosmrs::{AccountId, tendermint};
#[derive(Deserialize, Serialize, Debug)]
pub struct SequenceRequest {
pub validator: String,
pub signer_address: AccountId,
}
#[derive(Deserialize, Serialize, Debug)]
pub struct SequenceRequestResponse {
pub account_number: u64,
pub sequence: u64,
pub chain_id: tendermint::chain::Id
}
#[derive(Deserialize, Serialize, Debug)]
pub struct BroadcastRequest {
pub base58_tx_bytes: String
}
#[derive(Deserialize, Serialize, Debug)]
pub struct BroadcastResponse{
pub tx_hash: String
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(untagged)]
pub enum RequestTypes {
Sequence(SequenceRequest),
Broadcast(BroadcastRequest)
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(untagged)]
pub enum ResponseTypes {
Sequence(SequenceRequestResponse),
Broadcast(BroadcastResponse)
}
@@ -1,2 +0,0 @@
pub mod reqres;
pub mod commands;
@@ -1,39 +0,0 @@
use serde::{Deserialize, Serialize};
use cosmrs::{AccountId, tendermint};
#[derive(Deserialize, Serialize, Debug)]
pub struct SequenceRequest {
pub validator: String,
pub signer_address: AccountId,
}
#[derive(Deserialize, Serialize, Debug)]
pub struct SequenceRequestResponse {
pub account_number: u64,
pub sequence: u64,
pub chain_id: tendermint::chain::Id
}
#[derive(Deserialize, Serialize, Debug)]
pub struct BroadcastRequest {
pub base58_tx_bytes: String
}
#[derive(Deserialize, Serialize, Debug)]
pub struct BroadcastResponse{
pub tx_hash: String
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(untagged)]
pub enum RequestTypes {
Sequence(SequenceRequest),
Broadcast(BroadcastRequest)
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(untagged)]
pub enum ResponseTypes {
Sequence(SequenceRequestResponse),
Broadcast(BroadcastResponse)
}
@@ -1,97 +0,0 @@
use std::path::PathBuf;
use clap::{ Parser, Subcommand, Args};
use nym_sdk::mixnet::{Recipient, MixnetClientBuilder, StoragePaths};
use nym_validator_client::nyxd::AccountId;
use nym_bin_common::logging::setup_logging;
mod commands;
#[derive(Debug, Parser)]
#[clap(name = "nym cosmos tx signer ")]
#[clap(about = "demo binary with which users can perform offline signing and transmission of signed tx to broadcaster via the mixnet ")]
struct Cli {
// TODO make this import from file & remove from cli args
// #[clap(long, global = true)]
// #[clap(
// help = "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC."
// )]
// mnemonic: Option<bip39::Mnemonic>,
// TODO add SP address
#[clap(subcommand)]
command: Option<Commands>,
}
#[derive(Debug, Subcommand)]
enum Commands {
/// sign a transaction offline
OfflineSignTx(OfflineSignTx),
/// send signed tx to SP for broadcast
SendTx(SendTx)
}
#[derive(Debug, Clone, Args)]
struct OfflineSignTx {
/// mnemonic of signing + sending account (you!) - TODO this will be removed and replaced with file
mnemonic: bip39::Mnemonic,
/// recipient nyx chain address for token transfer
nyx_token_receipient: AccountId
}
#[derive(Debug, Args)]
struct SendTx {
/// the base58 encoded signed payload created in OfflineSign()
base58_payload: String,
/// the nym address of the broadcaster service provider
sp_address: Recipient
}
#[tokio::main]
async fn main() {
// setup_logging();
let cli = Cli::parse();
// TODO look @ arg env setup from NR main.rs
// TODO take from args
let sp_address = Recipient::try_from_base58_string("HfbesQm2pRYCN4BAdYXhkqXBbV1Pp929mtKsESVeWXh8.8AgoUPUQbXNBCPaqAaWd3vnxhc9484qwfgrrQwBngQk2@Ck8zpXTSXMtS9YZ7k7a5BiaoLZfffWuqGWLndujh4Lw4").unwrap();
let config_dir = PathBuf::from("/tmp/cosmos-broadcaster-mixnet-client-2");
let storage_paths = StoragePaths::new_from_dir(&config_dir).unwrap();
let client = MixnetClientBuilder::new_with_default_storage(storage_paths)
.await
.unwrap()
.build()
.await
.unwrap();
let mut client = client.connect_to_mixnet().await.unwrap();
let our_address = client.nym_address();
println!("\nOur client nym address is: {our_address}");
match &cli.command {
Some(Commands::OfflineSignTx(OfflineSignTx { mnemonic, nyx_token_receipient} )) => {
println!("sending offline sign info");
let base58_tx_bytes = commands::commands::offline_sign(mnemonic.clone(), nyx_token_receipient.clone(), &mut client, sp_address.clone()).await;
println!("base58 encoded signed tx payload: \n\n{}\n\n", &base58_tx_bytes);
println!("do you wish to send the tx? y/n");
let mut input = String::new();
let stdin = std::io::stdin();
let n = stdin.read_line(&mut input).unwrap();
if input.chars().next().unwrap() == 'y' { // TODO add proper parsing for getting y/n
println!("\nsending tx thru the mixnet to broadcaster service");
let tx_hash = commands::commands::send_tx(base58_tx_bytes, sp_address, &mut client).await;
println!("the response from the broadcaster: {:#?}", tx_hash);
} else if input.chars().next().unwrap() == 'n' {
println!("\nok, you can send the signed tx at a later date by passing the base58 string above as the argument for send-tx")
} else { //TODO make a loop & return to the question if input is not y/n?
println!("\nunrecognised user input");
}
}
Some(Commands::SendTx(SendTx { base58_payload, sp_address} )) => {
let tx_hash = commands::commands::send_tx(base58_payload.clone(), sp_address.clone(), &mut client).await;
println!("the response from the broadcaster: {:#?}", tx_hash);
}
None => {println!("no command specified - nothing to do")}
}
println!("\nend ~(0.o)~ ")
}
@@ -1,28 +0,0 @@
[package]
name = "rust-cosmos-broadcaster-server"
version = "0.1.0"
authors.workspace = true
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
clap = { version = "4.0", features = ["derive"] }
nym-bin-common = { path = "../../common/bin-common"}
nym-sphinx-addressing = { path = "../../common/nymsphinx/addressing" }
nym-sphinx-anonymous-replies = { path = "../../common/nymsphinx/anonymous-replies" }
nym-sdk = { path = "../../sdk/rust/nym-sdk" }
nym-crypto = { path = "../../common/crypto" }
nym-cli-commands = { path = "../../common/commands" }
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"] }
cosmrs = { git = "https://github.com/neacsu/cosmos-rust", branch = "neacsu/feegrant_support", features = ["rpc", "bip32", "cosmwasm"] }
tokio = { version = "1.24.1", features = ["rt-multi-thread", "macros"] }
ts-rs = "6.1.2"
bs58 = "0.5.0"
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
cosmwasm-std = { workspace = true, optional = true }
anyhow.workspace = true
@@ -1,61 +0,0 @@
use nym_validator_client::nyxd::CosmWasmClient;
use cosmrs::rpc::{HttpClient, Client};
use cosmrs::{AccountId, tendermint};
use bs58;
use crate::commands::reqres::{SequenceRequestResponse, BroadcastResponse};
pub async fn get_sequence(validator: String, signer_address: AccountId) -> SequenceRequestResponse {
/*
TODO create broadcaster in different fn and build on setup - pass to both fns as arg
*/
let broadcaster = HttpClient::new(validator.as_str()).unwrap();
// get signer information
let sequence = broadcaster.get_sequence(&signer_address).await.unwrap();
let chain_id: tendermint::chain::Id = broadcaster.get_chain_id().await.unwrap();
let res = SequenceRequestResponse { account_number: sequence.account_number, sequence: sequence.sequence, chain_id };
res
}
pub async fn broadcast(base58_tx_bytes: String) -> BroadcastResponse {
// decode the base58 tx to vec<u8>
let tx_bytes = bs58::decode(base58_tx_bytes).into_vec().unwrap();
println!("decoded tx bytes: {:#?}", tx_bytes);
/*
TODO create broadcaster in different fn and build on setup - pass to both fns as arg
*/
let broadcaster = HttpClient::new("https://qwerty-validator.qa.nymte.ch").unwrap();
let to_address: AccountId = "n1p8ayfmdash352gh6yy8zlxk24dm6yzc9mdq0p6".parse().unwrap();
// compare balances from before and after the tx
let before = broadcaster
.get_balance(&to_address, "unym".to_string())
.await
.unwrap()
.unwrap();
// broadcast the tx
let broadcast_res = Client::broadcast_tx_commit(&broadcaster, tx_bytes.into())
.await
.unwrap();
let after = broadcaster
.get_balance(&to_address, "unym".to_string())
.await
.unwrap()
.unwrap();
println!("{:#?}", broadcast_res.hash);
println!("balance before: {before}");
println!("balance after: {after}");
let res = BroadcastResponse {
tx_hash: serde_json::to_string(&broadcast_res.hash).unwrap()
};
res
}
@@ -1,2 +0,0 @@
pub mod reqres;
pub mod commands;
@@ -1,39 +0,0 @@
use serde::{Deserialize, Serialize};
use cosmrs::{AccountId, tendermint};
#[derive(Deserialize, Serialize, Debug)]
pub struct SequenceRequest {
pub validator: String,
pub signer_address: AccountId,
}
#[derive(Deserialize, Serialize, Debug)]
pub struct SequenceRequestResponse {
pub account_number: u64,
pub sequence: u64,
pub chain_id: tendermint::chain::Id
}
#[derive(Deserialize, Serialize, Debug)]
pub struct BroadcastRequest {
pub base58_tx_bytes: String
}
#[derive(Deserialize, Serialize, Debug)]
pub struct BroadcastResponse{
pub tx_hash: String
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(untagged)]
pub enum RequestTypes {
Sequence(SequenceRequest),
Broadcast(BroadcastRequest)
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(untagged)]
pub enum ResponseTypes {
Sequence(SequenceRequestResponse),
Broadcast(BroadcastResponse)
}
@@ -1,101 +0,0 @@
use nym_sdk::mixnet::{StoragePaths, MixnetClientBuilder, ReconstructedMessage};
use nym_bin_common::logging::setup_logging;
use std::path::PathBuf;
mod commands;
use nym_sphinx_anonymous_replies::{self, requests::AnonymousSenderTag};
use crate::commands::reqres;
#[tokio::main]
async fn main() {
setup_logging();
// TODO put client creation in own fn
let config_dir = PathBuf::from("/tmp/cosmos-broadcaster-mixnet-server-2");
let storage_paths = StoragePaths::new_from_dir(&config_dir).unwrap();
let client = MixnetClientBuilder::new_with_default_storage(storage_paths)
.await
.unwrap()
.build()
.await
.unwrap();
let mut client = client.connect_to_mixnet().await.unwrap();
let our_address = client.nym_address();
println!("\nOur client nym address is: {our_address}");
/*
TODO
* add threads - loop just to check everything works quickly
*/
loop {
println!("\nWaiting for message");
// TODO rewrite this to parse any empty SURB data and then parse the actual incoming message
// let received = client.wait_for_messages().await;
// handle incoming message - we presume its a reply from the SP
// check incoming is empty - SURB requests also send data ( empty vec ) along
let mut received: Vec<ReconstructedMessage> = Vec::new();
// get the actual message - discard the empty vec sent along with the SURB request
while let Some(new_message) = client.wait_for_messages().await {
if new_message.is_empty() {
continue;
}
println!("got a response:");
received = new_message;
println!("{:#?}", &received);
break
}
for r in received.iter() {
// convert incoming vec<u8> -> String
let s = String::from_utf8(r.message.clone());
println!("{:#?}", &s);
if s.is_ok() {
let p = s.unwrap();
println!("{:#?}", &p);
// parse JSON string -> request type & match
let request: reqres::RequestTypes = serde_json::from_str(&p).unwrap();
println!("incoming request: {:#?}", &request);
match request {
reqres::RequestTypes::Sequence(request) => {
println!("\nincoming sequence request details:\nvalidator: {},\nsigner address: {}\n", request.validator, request.signer_address);
let sequence: reqres::SequenceRequestResponse = commands::commands::get_sequence(request.validator, request.signer_address).await;
// print!("debug print -------- {:#?}", sequence);
// println!("debug print SENDER TAG --------- {:#?}", r.sender_tag);
if Some(r.sender_tag).is_some() {
// println!("debug print ---- sending reply ");
let return_recipient: AnonymousSenderTag = r.sender_tag.unwrap();
println!("return recipient surb bucket: {}", &return_recipient);
// todo actually return sequence serialised as json
client.send_str_reply(return_recipient, &serde_json::to_string(&sequence).unwrap()).await;
// println!("sent reply - sleeping");
// tokio::time::sleep(Duration::from_secs(25)).await;
// println!("stopped sleep");
} else {
// TODO replace with actual error type to return
println!("no surbs cannot reply an0n")
}
},
reqres::RequestTypes::Broadcast(request) => {
println!("\nincoming sequence request details: {}\n", request.base58_tx_bytes);
let tx_hash: reqres::BroadcastResponse = commands::commands::broadcast(request.base58_tx_bytes).await;
if Some(r.sender_tag).is_some() {
// println!("debug print ---- sending reply ");
let return_recipient: AnonymousSenderTag = r.sender_tag.unwrap();
println!("return recipient surb bucket: {}", &return_recipient);
// todo actually return sequence serialised as json
client.send_str_reply(return_recipient, &serde_json::to_string(&tx_hash).unwrap()).await;
} else {
// TODO replace with actual error type to return
println!("no surbs cannot reply an0n")
}
}
}
}
}
}
client.disconnect().await;
}