You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
189 lines
4.6 KiB
189 lines
4.6 KiB
package Hush::App;
|
|
use strict;
|
|
use warnings;
|
|
use Try::Tiny;
|
|
use lib 'lib';
|
|
use Hush::List;
|
|
use Hush::Util qw/barf/;
|
|
use Data::Dumper;
|
|
use Hush::RPC;
|
|
use File::Slurp;
|
|
|
|
my $COMMANDS = {
|
|
"add" => \&add,
|
|
"contact" => \&Hush::Contact::contact,
|
|
"help" => \&help,
|
|
"new" => \&new,
|
|
"remove" => \&remove,
|
|
"send" => \&send,
|
|
"send-file" => \&send_file,
|
|
"show" => \&show,
|
|
"status" => \&status,
|
|
#"public" => \&public,
|
|
"subscribe" => \&subscribe,
|
|
};
|
|
# TODO: translations
|
|
my %HELP = (
|
|
"add" => "Add a contact to a Hushlist",
|
|
"contact" => "Manage Hushlist contacts",
|
|
"help" => "Get your learn on",
|
|
"new" => "Create a new Hushlist",
|
|
"remove" => "Remove a Hushlist",
|
|
"send" => "Send a new Hushlist memo, specified on command-line",
|
|
"send-file" => "Send a new Hushlist memo from a file on disk",
|
|
"status" => "Get overview of Hushlists or a specific Hushlist",
|
|
"show" => "Show Hushlist memos",
|
|
#"public" => "Make a private Hushlist public",
|
|
);
|
|
|
|
my $options = {};
|
|
my $rpc = Hush::RPC->new;
|
|
my $list = Hush::List->new($rpc, $options);
|
|
|
|
sub validate_hushlist_url {
|
|
my ($url) = @_;
|
|
# TODO: allow full syntax and bare privkeys
|
|
# and other chains
|
|
if ($url =~ m!^hushlist://(SK[A-z0-9]+)(\?height=(\d+))?!i) {
|
|
my ($key,$height) = ($1,$3);
|
|
my ($chain,$net) = ("hush","");
|
|
return ($chain, $net, $key,$height);
|
|
}
|
|
return undef;
|
|
}
|
|
|
|
sub subscribe {
|
|
my ($url) = @_;
|
|
|
|
my $status;
|
|
if ($url) {
|
|
if (my @hushlist = validate_hushlist_url($url)) {
|
|
$status = $list->subscribe(@hushlist);
|
|
} else {
|
|
die "Invalid hushlist URL!\n";
|
|
}
|
|
} else {
|
|
die "Usage: hushlist subscribe URL\n";
|
|
}
|
|
return $status;
|
|
}
|
|
|
|
sub show_status {
|
|
my $chaininfo = $rpc->getblockchaininfo;
|
|
my $walletinfo = $rpc->getwalletinfo;
|
|
my $chain = $chaininfo->{chain};
|
|
my $blocks = $chaininfo->{blocks};
|
|
my $balance = $rpc->z_gettotalbalance;
|
|
my $tbalance = sprintf "%.8f", $balance->{transparent};
|
|
my $zbalance = sprintf "%.8f", $balance->{private};
|
|
my $total_balance = $balance->{total};
|
|
my $blockchain = "HUSH";
|
|
|
|
print "Hushlist v$Hush::List::VERSION running on $blockchain ${chain}net, $blocks blocks\n";
|
|
print "Balances: transparent $tbalance HUSH, private $zbalance HUSH\n";
|
|
}
|
|
|
|
|
|
sub run {
|
|
my ($command) = @_;
|
|
#print "Running command $command\n";
|
|
my $cmd = $COMMANDS->{$command};
|
|
|
|
show_status();
|
|
|
|
if ($cmd) {
|
|
return $cmd->(@ARGV);
|
|
} else {
|
|
usage();
|
|
}
|
|
}
|
|
|
|
sub add {
|
|
my ($list_name,$contact) = @_;
|
|
|
|
# we add contacts to a list, not a zaddr
|
|
$list->add_contact($list_name,$contact);
|
|
}
|
|
|
|
sub remove {
|
|
my ($list_name,$zaddr) = @_;
|
|
|
|
$list->remove_zaddr($list_name,$zaddr);
|
|
return $list;
|
|
}
|
|
|
|
# send a Hushlist memo from a file
|
|
sub send_file {
|
|
my ($list_name,$file) = @_;
|
|
|
|
barf "You must specify a Hushlist to send to" unless $list_name;
|
|
barf "You must specify a file to attach" unless $file;
|
|
|
|
if (-e $file) {
|
|
my $memo = read_file($file);
|
|
$list->send_memo($rpc, $list_name, $memo);
|
|
} else {
|
|
barf "Cannot find $file to attach to Hushlist memo to $list_name!";
|
|
}
|
|
return $list;
|
|
}
|
|
|
|
# send a Hushlist memo to list of contacts on the chain
|
|
# specified for this list
|
|
sub send {
|
|
my ($list_name,$memo) = @_;
|
|
|
|
$list->send_memo($rpc, $list_name, $memo);
|
|
}
|
|
|
|
sub help {
|
|
print "Available Hushlist commands:\n";
|
|
my @cmds = sort keys %$COMMANDS;
|
|
for my $cmd (@cmds) {
|
|
print "\t$cmd\t: $HELP{$cmd}\n";
|
|
}
|
|
}
|
|
|
|
sub show {
|
|
my ($name,@args) = @_;
|
|
if ($name) {
|
|
my $status = $list->show($name);
|
|
} else {
|
|
my $status = $list->global_show;
|
|
}
|
|
}
|
|
|
|
sub usage {
|
|
print "Usage: $0 command [subcommand] [options]\n";
|
|
print "$0 help for more details :)\n";
|
|
return 1;
|
|
}
|
|
|
|
sub status {
|
|
my $name = shift;
|
|
if ($name) {
|
|
my $status = $list->status($name);
|
|
} else {
|
|
my $status = $list->global_status;
|
|
}
|
|
}
|
|
|
|
# make a hushlist public by publishing its privkey in OP_RETURN data
|
|
# This operation costs HUSH and cannot be undone!!! It sends private
|
|
# keys to the PUBLIC BLOCKCHAIN
|
|
sub publicize {
|
|
my ($name) = @_;
|
|
|
|
$list->publicize($name);
|
|
}
|
|
|
|
sub new {
|
|
my $name = shift || '';
|
|
#TODO: better validation and allow safe unicode stuff
|
|
barf "Invalid hushlist name '$name' !" unless $name && ($name =~ m/^[A-z0-9_-]{0,64}/);
|
|
|
|
$list->new_list($name);
|
|
print "hushlist '$name' created, enjoy your private comms ;)\n";
|
|
}
|
|
|
|
1;
|
|
|