Commit 61bd3405 authored by Éloïs's avatar Éloïs
Browse files

feat(pay): add ud units, pay to scrypt, and confirmation

parent b0d5e5e8
Pipeline #11444 passed with stages
in 8 minutes and 56 seconds
......@@ -81,6 +81,9 @@ name = "arrayvec"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
dependencies = [
"serde",
]
[[package]]
name = "ascii"
......@@ -350,9 +353,9 @@ checksum = "4bb454f0228b18c7f4c3b0ebbee346ed9c52e7443b0999cd543ff3571205701d"
[[package]]
name = "dubp"
version = "0.49.0"
version = "0.50.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9617091ba0d0a0cc95392655b0b7136fee3b63101d64c0fd0a5c2741983f18"
checksum = "1669c61ccfe0d3fc7be8fe3175ebd401b9c879f638425f31e92777c73b32ea86"
dependencies = [
"dubp-common",
"dubp-documents",
......@@ -364,7 +367,7 @@ dependencies = [
[[package]]
name = "dubp-client"
version = "0.1.0"
source = "git+https://git.duniter.org/libs/dubp-rs-client-lib?branch=master#398b44b8b61e6cf631c1842ca44c9f3916c1c66f"
source = "git+https://git.duniter.org/libs/dubp-rs-client-lib?branch=master#a690f9b1bb029495c6aaf957c31d528dd282b49c"
dependencies = [
"bincode",
"dubp",
......@@ -380,9 +383,9 @@ dependencies = [
[[package]]
name = "dubp-common"
version = "0.49.0"
version = "0.50.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da764b34a61ecb52fa90dc11f5a44d6bc9599b043d37592b5102b95d993fd677"
checksum = "515fb09166a50b4543a99c42359fc4afa5a4c7af118c6f9627575c2760f3fef8"
dependencies = [
"dup-crypto",
"serde",
......@@ -393,9 +396,9 @@ dependencies = [
[[package]]
name = "dubp-documents"
version = "0.49.0"
version = "0.50.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8810039b6dd6a101109aebc9836ddec58366052803f824c56016889d9444f5cf"
checksum = "ccc9327c62778ee4fd060c0efbe32c6cfda5e317c4a2eb4ddee8293fbd278904"
dependencies = [
"beef",
"dubp-wallet",
......@@ -407,9 +410,9 @@ dependencies = [
[[package]]
name = "dubp-documents-parser"
version = "0.49.0"
version = "0.50.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c791c77a3f9c670666dc41f861481cc80eb1ad193584727adfee792350fd3129"
checksum = "271ce4a6bebfdfdaefb0e51f57c9bb04976fce5fbe2744dd60c1dcf857c60c20"
dependencies = [
"dubp-documents",
"json-pest-parser",
......@@ -421,9 +424,9 @@ dependencies = [
[[package]]
name = "dubp-wallet"
version = "0.49.0"
version = "0.50.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ef8e7c5334ddbc7899f83911026ebc324ba7fc7232c7ca5265e611490dbd282"
checksum = "f6e65a121fa6745038e903ed3d1eb6a97f9658c6c6e2bfbf7e9ffdaf34161d23"
dependencies = [
"byteorder",
"dubp-common",
......@@ -436,8 +439,9 @@ dependencies = [
[[package]]
name = "duniter-bca-types"
version = "0.1.0"
source = "git+https://git.duniter.org/nodes/typescript/duniter?branch=bca#fd6d221857461f75d059c5fc2afc24daab4d5545"
source = "git+https://git.duniter.org/nodes/typescript/duniter?branch=dev#591f334185151a200a7dbb06b32ff434a19b0885"
dependencies = [
"arrayvec",
"bincode",
"dubp",
"serde",
......@@ -447,9 +451,9 @@ dependencies = [
[[package]]
name = "dup-crypto"
version = "0.49.0"
version = "0.50.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0be04829b31b18bacf5317001366d807e5fbd02085ee6348508c1299b5bcaf6c"
checksum = "3032421000ca2cdd372bd72f4c548be7f1386d357abb0936291890064d3072e8"
dependencies = [
"aes",
"arrayvec",
......@@ -633,6 +637,7 @@ dependencies = [
"anyhow",
"dubp-client",
"mockall 0.8.3",
"read_input",
"rpassword",
"serde",
"structopt",
......@@ -1269,6 +1274,12 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "read_input"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b57518cc6538a2eb7dce826e24fa51d0b7cf8e744ee10c7f56259cdec40050e5"
[[package]]
name = "regex"
version = "1.4.4"
......
......@@ -11,6 +11,7 @@ description = "A command line client written in Rust that use Duniter GVA API."
anyhow = "1.0.32"
dubp-client = { git = "https://git.duniter.org/libs/dubp-rs-client-lib", branch = "master", features = ["blocking"], default-features = false }
#dubp-client= { path = "../dubp-rs-client-lib", features = ["blocking"], default-features = false }
read_input = "0.8.4"
rpassword = "5.0.1"
serde = { version = "1.0.105", features = ["derive"] }
structopt = "0.3.18"
......
......@@ -21,6 +21,7 @@ pub mod wallet;
use crate::*;
#[allow(clippy::large_enum_variant)]
#[derive(StructOpt)]
pub(crate) enum Command {
/// Get account balance
......
......@@ -23,7 +23,7 @@ use dubp_client::{
},
keys::{
ed25519::bip32::{KeyPair, PrivateDerivationPath},
KeyPair as _, KeyPairEnum, PublicKey,
KeyPair as _, KeyPairEnum,
},
mnemonic::{mnemonic_to_seed, Language, Mnemonic, MnemonicType},
utils::U31,
......@@ -31,6 +31,7 @@ use dubp_client::{
wallet::prelude::SourceAmount,
};
#[allow(clippy::large_enum_variant)]
#[derive(StructOpt)]
pub enum WalletCommand {
/// Generate a wallet
......@@ -75,7 +76,7 @@ pub enum WalletCommand {
Pay {
account_index: u32,
#[structopt(short, long)]
amount: u64,
amount: f64,
#[structopt(short, long)]
base: Option<u64>,
#[structopt(short, long)]
......@@ -89,7 +90,13 @@ pub enum WalletCommand {
#[structopt(long)]
password_stdin: bool,
#[structopt(short, long)]
recipient: String,
recipient: PkOrScript,
/// UD units
#[structopt(short, long)]
ud_units: bool,
/// Auto confirm (for non-interactive use)
#[structopt(short, long)]
yes: bool,
},
}
......@@ -176,49 +183,70 @@ pub(crate) fn wallet<C: GvaClient, W: Write>(
lang,
password_stdin,
recipient,
ud_units,
yes,
} => {
let recipient = PublicKey::from_base58(&recipient)?;
let recipient = recipient.0;
let keypair = get_master_keypair(dewif, dewif_file, lang, password_stdin)?;
let (amount, amount_str) = if ud_units {
(Amount::Uds(amount), format!("{:.2} UDğ1", amount))
} else {
(
Amount::Cents(SourceAmount::new(
(amount * 100.0).round() as i64,
base.unwrap_or_default() as i64,
)),
format!("{:.2} Ğ1", amount),
)
};
match account_index % 3 {
0 => {
let trasparent_keypair = keypair.derive(PrivateDerivationPath::transparent(
U31::new(account_index)?,
)?);
writeln!(
out,
"Sending {}.{} Ğ1 to {} from transparent account {} …",
amount / 100,
amount % 100,
recipient,
trasparent_keypair.public_key().to_base58()
)?;
let confirm = if yes {
true
} else {
let res = input()
.msg(format!(
"Send {} to {} from transparent account {}? [y/N]",
amount_str,
recipient.to_string(),
trasparent_keypair.public_key().to_base58()
))
.default('N')
.get();
res == 'y' || res == 'Y'
};
let req_time = Instant::now();
let payment_result = gva_client.simple_payment(
SourceAmount::new(amount as i64, base.unwrap_or_default() as i64),
&trasparent_keypair.generate_signator(),
recipient,
comment,
None,
)?;
if confirm {
let req_time = Instant::now();
let payment_result = gva_client.simple_payment(
amount,
&trasparent_keypair.generate_signator(),
recipient,
comment,
None,
)?;
if let PaymentResult::Errors(errors) = payment_result {
writeln!(out, "All or part of the payment failed, errors: \n")?;
for error in errors {
writeln!(out, "- {:?}", error)?;
if let PaymentResult::Errors(errors) = payment_result {
writeln!(out, "All or part of the payment failed, errors: \n")?;
for error in errors {
writeln!(out, "- {:?}", error)?;
}
todo!()
} else {
let duration = req_time.elapsed();
writeln!(
out,
"Payment succesfully processed in {}.{} ms.",
duration.as_millis(),
duration.subsec_micros() % 1_000
)?;
}
todo!()
} else {
writeln!(out, "Payment succesfully sent.")?;
let duration = req_time.elapsed();
println!(
"Payment processed in {}.{} ms.",
duration.as_millis(),
duration.subsec_micros() % 1_000
);
}
Ok(())
......
// Copyright (C) 2020 Éloïs SANCHEZ.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use crate::*;
use dubp_client::{
crypto::keys::PublicKey as _,
documents_parser::{wallet_script_from_str, TextParseError},
};
pub struct PkOrScript(pub(crate) WalletScriptV10);
impl FromStr for PkOrScript {
type Err = TextParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
if let Ok(pubkey) = PublicKey::from_base58(s) {
Ok(Self(WalletScriptV10::single_sig(pubkey)))
} else {
Ok(Self(wallet_script_from_str(s)?))
}
}
}
......@@ -25,8 +25,10 @@
)]
mod commands;
mod inputs;
use crate::commands::Command;
use crate::inputs::PkOrScript;
use commands::{
balance::balance, current_ud::current_ud, idty::idty, members_count::members_count,
wallet::wallet,
......@@ -35,8 +37,10 @@ use commands::{
use dubp_client::MockGvaClient;
use dubp_client::{
crypto::keys::{ed25519::PublicKey, PublicKey as _},
AccountBalance, GvaClient, Idty, NaiveGvaClient, PaymentResult, PubkeyOrScript,
wallet::prelude::*,
AccountBalance, Amount, GvaClient, Idty, NaiveGvaClient, PaymentResult, PubkeyOrScript,
};
use read_input::prelude::*;
use std::{
env::var_os,
fs::File,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment