Skip to content

Commit

Permalink
feat: display local time instead of UTC. Add new wallet commands. (#2994
Browse files Browse the repository at this point in the history
)
  • Loading branch information
stringhandler committed Jun 11, 2021
2 parents ac062e5 + f2876a1 commit b376020
Show file tree
Hide file tree
Showing 12 changed files with 375 additions and 158 deletions.
2 changes: 2 additions & 0 deletions applications/tari_base_node/src/command_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ impl CommandHandler {

self.executor.spawn(async move {
let mut status_line = StatusLine::new();
let version = format!("v{}", consts::APP_VERSION_NUMBER);
status_line.add_field("", version);

let state = state_info.recv().await.unwrap();
status_line.add_field("State", state.state_info.short_desc());
Expand Down
38 changes: 31 additions & 7 deletions applications/tari_base_node/src/status_line.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use chrono::Utc;
use chrono::Local;
use std::{fmt, fmt::Display};

#[derive(Debug, Clone, Default)]
Expand All @@ -41,13 +41,37 @@ impl StatusLine {

impl Display for StatusLine {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}: ", Utc::now().format("%H:%M"))?;
let s = self
.fields
.iter()
.map(|(k, v)| format!("{}: {}", k, v))
.collect::<Vec<_>>();
write!(f, "{} ", Local::now().format("%H:%M"))?;
let s = self.fields.iter().map(|(k, v)| format(k, v)).collect::<Vec<_>>();

write!(f, "{}", s.join(", "))
}
}

fn format(k: &&str, v: &str) -> String {
if k.is_empty() {
v.to_string()
} else {
format!("{}: {}", k, v)
}
}

#[cfg(test)]
mod test {
use super::StatusLine;

#[test]
fn test_do_not_display_empty_keys() {
let mut status = StatusLine::new();
status.add_field("key", "val");
let display = status.to_string();
assert!(display.contains("key: val"));
assert_eq!(display.matches(':').count(), 2);

let mut status = StatusLine::new();
status.add_field("", "val");
let display = status.to_string();
assert!(display.contains("val"));
assert_eq!(display.matches(':').count(), 1);
}
}
92 changes: 78 additions & 14 deletions applications/tari_console_wallet/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@

The Tari Console Wallet is a terminal based wallet for sending and receiving Tari. It can be run in a few different modes.

### Terminal UI (TUI) mode
## Terminal UI (TUI) mode

The standard operating mode, TUI mode is the default when starting `tari_console_wallet`. Displays a UI in the terminal to interact with the wallet.

![](./docs/img/tui.png)

### Daemon (GRPC) mode
## Daemon (GRPC) mode

Run as a server with no UI, but exposing the GRPC interface with `tari_console_wallet --daemon`.

### Command mode
## Command mode

Run a once off command with the `--command` argument:

- **get-balance**
Expand All @@ -20,6 +23,7 @@ Get your wallet balance
`tari_console_wallet --command "get-balance"`

example output:

```
Available balance: 1268922.299856 T
Pending incoming balance: 6010 µT
Expand All @@ -33,6 +37,7 @@ Send an amount of Tari to a public key or emoji id.
`tari_console_wallet --command "send-tari <amount> <pubkey> <optional message>"`

example:

```
$ tari_console_wallet --command "send-tari 1T c69fbe5f05a304eaec65d5f234a6aa258a90b8bb5b9ceffea779653667ef2108 coffee"
Expand All @@ -49,8 +54,9 @@ Make it rain! Send many transactions to a public key or emoji id.
`tari_console_wallet --command "make-it-rain <tx/sec> <duration> <amount> <increment> <start time or now> <pubkey> <optional message>"`

example:

```
$ tari_console_wallet --command "make-it-rain 1 10 8000 100 now c69fbe5f05a304eaec65d5f234a6aa258a90b8bb5b9ceffea779653667ef2108 makin it rain yo"
$ tari_console_wallet --command "make-it-rain 1 10 8000 100 now c69fbe5f05a304eaec65d5f234a6aa258a90b8bb5b9ceffea779653667ef2108 makin it rain yo"
1. make-it-rain 1 10 8000 µT 100 µT 2021-03-26 10:03:30.459157 UTC c69fbe5f05a304eaec65d5f234a6aa258a90b8bb5b9ceffea779653667ef2108 makin it rain yo
Expand All @@ -64,11 +70,11 @@ Split one or more unspent transaction outputs into many.
Creates a transaction that must be mined before the new outputs can be spent.

`tari_console_wallet --command "coin-split <amount per coin> <number of coins>"`

example:
$ tari_console_wallet --command "coin-split 10000 9"
example output:

```
$ tari_console_wallet --command "coin-split 10000 µT 9"
$ tari_console_wallet --command "coin-split 10000 9"
1. coin-split 10000 µT 9
Expand All @@ -77,19 +83,71 @@ Monitoring 1 sent transactions to Broadcast stage...
Done! All transactions monitored to Broadcast stage.
```

- **set-base-node**

Sets the base node peer that the wallet should connect to (not persisted after exit, normally used in a script).

`tari_console_wallet --command "set-base-node <public key or emoji id> <network address>"`

example:

```
$ tari_console_wallet --command "set-base-node 3883ab92d91eb70155d1d471c9e569d2bcae10ee3f196b8dfdaade1e7546c520 /onion3/wlyt2p4ft4mtj6zs2fdgw6hwfqvf5i4hhia4y6ffk6oybfsbrwqcpead:18141"
1. set-base-node 3883ab92d91eb70155d1d471c9e569d2bcae10ee3f196b8dfdaade1e7546c520 /onion3/wlyt2p4ft4mtj6zs2fdgw6hwfqvf5i4hhia4y6ffk6oybfsbrwqcpead:18141
Setting base node peer...
3883ab92d91eb70155d1d471c9e569d2bcae10ee3f196b8dfdaade1e7546c520::/onion3/wlyt2p4ft4mtj6zs2fdgw6hwfqvf5i4hhia4y6ffk6oybfsbrwqcpead:18141
```

- **set-custom-base-node**

Sets the custom base node peer that the wallet should connect to, and persists the peer to the wallet database.

`tari_console_wallet --command "set-custom-base-node <public key or emoji id> <network address>"`

example:

```
$ tari_console_wallet --command "set-custom-base-node 3883ab92d91eb70155d1d471c9e569d2bcae10ee3f196b8dfdaade1e7546c520 /onion3/wlyt2p4ft4mtj6zs2fdgw6hwfqvf5i4hhia4y6ffk6oybfsbrwqcpead:18141"
1. set-custom-base-node 3883ab92d91eb70155d1d471c9e569d2bcae10ee3f196b8dfdaade1e7546c520 /onion3/wlyt2p4ft4mtj6zs2fdgw6hwfqvf5i4hhia4y6ffk6oybfsbrwqcpead:18141
Setting base node peer...
3883ab92d91eb70155d1d471c9e569d2bcae10ee3f196b8dfdaade1e7546c520::/onion3/wlyt2p4ft4mtj6zs2fdgw6hwfqvf5i4hhia4y6ffk6oybfsbrwqcpead:18141
Saving custom base node peer in wallet database.
```

- **clear-custom-base-node**

Clears the custom base node peer from the wallet database.

`tari_console_wallet --command "clear-custom-base-node"`

example:

```
$ tari_console_wallet --command clear-custom-base-node
1. clear-custom-base-node
Clearing custom base node peer in wallet database.
```

- **export-utxos**

Export all the unspent transaction outputs (UTXOs) in the wallet. This can either list the UTXOs directly in the
console, or write them to file. In the latter case the complete unblinded set of information will be exported.
Export all the unspent transaction outputs (UTXOs) in the wallet. This can either list the UTXOs directly in the
console, or write them to file. In the latter case the complete unblinded set of information will be exported.

```
tari_console_wallet --command "export-utxos"
tari_console_wallet --command "export-utxos --csv-file <file name>"
```

example output - console only:

```
$ tari_console_wallet --command "export-utxos"
$ tari_console_wallet --command "export-utxos"
1. export-utxos
Expand All @@ -103,8 +161,9 @@ Total value of UTXOs: 1268921.295856 T
```

example output - `--csv-file` (console output):

```
$ tari_console_wallet --command "export-utxos --csv-file utxos.csv"
$ tari_console_wallet --command "export-utxos --csv-file utxos.csv"
1. export-utxos --csv-file utxos.csv
Expand All @@ -113,6 +172,7 @@ Total value of UTXOs: 36105.165440 T
```

example output - `--csv-file` (contents of `utxos.csv`)

```
"#","Value (uT)","Spending Key","Commitment","Flags","Maturity"
"1","121999250","0b0ce2add569845ec8bb84256b731e644e2224580b568e75666399e868ea5701","22514e279bd7e7e0a6e45905e07323b16f6114e300bcc02f36b2baf44a17b43d","(empty)","0"
Expand All @@ -130,6 +190,7 @@ Count the number of unspent transaction outputs (UTXOs) in the wallet.
`tari_console_wallet --command "count-utxos"`

example output:

```
1. count-utxos
Expand All @@ -147,6 +208,7 @@ Discover a peer on the network by public key or emoji id.
`tari_console_wallet --command "discover-peer <public key or emoji id>"`

example output:

```
1. discover-peer c69fbe5f05a304eaec65d5f234a6aa258a90b8bb5b9ceffea779653667ef2108
Expand All @@ -163,18 +225,20 @@ Look up a public key or emoji id, useful for converting between the two formats.
`tari_console_wallet --command "whois <public key or emoji id>"`

example output:

```
1. whois c69fbe5f05a304eaec65d5f234a6aa258a90b8bb5b9ceffea779653667ef2108
Public Key: c69fbe5f05a304eaec65d5f234a6aa258a90b8bb5b9ceffea779653667ef2108
Emoji ID : 📈👛💭🎾🌍👡🌋😻🚀🏉🔥🚓🍳👹👿🍕🐵🐼💡💦🎺👘🚌🚿👻🐛🏉🍵🏥🚌🍑🌞🍹
```

### Script mode
## Script mode

Run a series of commands from a given script.
Run a series of commands from a given script. The commands should be formatted the same way as Command mode, one per line in a text file.

`tari_console_wallet --script /path/to/script`

### Recovery mode
## Recovery mode

todo docs
71 changes: 51 additions & 20 deletions applications/tari_console_wallet/src/automation/command_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use std::{
str::FromStr,
};
use tari_app_utilities::utilities::parse_emoji_id_or_public_key;
use tari_comms::multiaddr::Multiaddr;

use tari_core::transactions::{tari_amount::MicroTari, types::PublicKey};

Expand All @@ -41,17 +42,21 @@ pub struct ParsedCommand {

impl Display for ParsedCommand {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
use WalletCommand::*;
let command = match self.command {
WalletCommand::GetBalance => "get-balance",
WalletCommand::SendTari => "send-tari",
WalletCommand::SendOneSided => "send-one-sided",
WalletCommand::MakeItRain => "make-it-rain",
WalletCommand::CoinSplit => "coin-split",
WalletCommand::DiscoverPeer => "discover-peer",
WalletCommand::Whois => "whois",
WalletCommand::ExportUtxos => "export-utxos",
WalletCommand::ExportSpentUtxos => "export-spent-utxos",
WalletCommand::CountUtxos => "count-utxos",
GetBalance => "get-balance",
SendTari => "send-tari",
SendOneSided => "send-one-sided",
MakeItRain => "make-it-rain",
CoinSplit => "coin-split",
DiscoverPeer => "discover-peer",
Whois => "whois",
ExportUtxos => "export-utxos",
ExportSpentUtxos => "export-spent-utxos",
CountUtxos => "count-utxos",
SetBaseNode => "set-base-node",
SetCustomBaseNode => "set-custom-base-node",
ClearCustomBaseNode => "clear-custom-base-node",
};

let args = self
Expand All @@ -75,19 +80,22 @@ pub enum ParsedArgument {
Date(DateTime<Utc>),
OutputToCSVFile(String),
CSVFileName(String),
Address(Multiaddr),
}

impl Display for ParsedArgument {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
use ParsedArgument::*;
match self {
ParsedArgument::Amount(v) => write!(f, "{}", v.to_string()),
ParsedArgument::PublicKey(v) => write!(f, "{}", v.to_string()),
ParsedArgument::Text(v) => write!(f, "{}", v.to_string()),
ParsedArgument::Float(v) => write!(f, "{}", v.to_string()),
ParsedArgument::Int(v) => write!(f, "{}", v.to_string()),
ParsedArgument::Date(v) => write!(f, "{}", v.to_string()),
ParsedArgument::OutputToCSVFile(v) => write!(f, "{}", v.to_string()),
ParsedArgument::CSVFileName(v) => write!(f, "{}", v.to_string()),
Amount(v) => write!(f, "{}", v.to_string()),
PublicKey(v) => write!(f, "{}", v.to_string()),
Text(v) => write!(f, "{}", v.to_string()),
Float(v) => write!(f, "{}", v.to_string()),
Int(v) => write!(f, "{}", v.to_string()),
Date(v) => write!(f, "{}", v.to_string()),
OutputToCSVFile(v) => write!(f, "{}", v.to_string()),
CSVFileName(v) => write!(f, "{}", v.to_string()),
Address(v) => write!(f, "{}", v.to_string()),
}
}
}
Expand All @@ -106,11 +114,14 @@ pub fn parse_command(command: &str) -> Result<ParsedCommand, ParseError> {
SendOneSided => parse_send_tari(args)?,
MakeItRain => parse_make_it_rain(args)?,
CoinSplit => parse_coin_split(args)?,
DiscoverPeer => parse_discover_peer(args)?,
DiscoverPeer => parse_public_key(args)?,
Whois => parse_whois(args)?,
ExportUtxos => parse_export_utxos(args)?, // todo: only show X number of utxos
ExportSpentUtxos => parse_export_spent_utxos(args)?, // todo: only show X number of utxos
CountUtxos => Vec::new(),
SetBaseNode => parse_public_key_and_address(args)?,
SetCustomBaseNode => parse_public_key_and_address(args)?,
ClearCustomBaseNode => Vec::new(),
};

Ok(ParsedCommand { command, args })
Expand All @@ -129,7 +140,7 @@ fn parse_whois(mut args: SplitWhitespace) -> Result<Vec<ParsedArgument>, ParseEr
Ok(parsed_args)
}

fn parse_discover_peer(mut args: SplitWhitespace) -> Result<Vec<ParsedArgument>, ParseError> {
fn parse_public_key(mut args: SplitWhitespace) -> Result<Vec<ParsedArgument>, ParseError> {
let mut parsed_args = Vec::new();

// public key/emoji id
Expand All @@ -142,6 +153,26 @@ fn parse_discover_peer(mut args: SplitWhitespace) -> Result<Vec<ParsedArgument>,
Ok(parsed_args)
}

fn parse_public_key_and_address(mut args: SplitWhitespace) -> Result<Vec<ParsedArgument>, ParseError> {
let mut parsed_args = Vec::new();

// public key/emoji id
let pubkey = args
.next()
.ok_or_else(|| ParseError::Empty("public key or emoji id".to_string()))?;
let pubkey = parse_emoji_id_or_public_key(pubkey).ok_or(ParseError::PublicKey)?;
parsed_args.push(ParsedArgument::PublicKey(pubkey));

// address
let address = args
.next()
.ok_or_else(|| ParseError::Empty("net address".to_string()))?;
let address = address.parse::<Multiaddr>().map_err(|_| ParseError::Address)?;
parsed_args.push(ParsedArgument::Address(address));

Ok(parsed_args)
}

fn parse_make_it_rain(mut args: SplitWhitespace) -> Result<Vec<ParsedArgument>, ParseError> {
let mut parsed_args = Vec::new();

Expand Down
Loading

0 comments on commit b376020

Please sign in to comment.