App-Bitcoin-PaperWallet

 view release on metacpan or  search on metacpan

bin/paper-wallet  view on Meta::CPAN

use App::Bitcoin::PaperWallet;
use Time::Piece;
use Getopt::Long;
use Pod::Usage;

sub get_qr
{
	my ($data) = @_;
	my $arrayref = Text::QRCode->new->plot($data);
	return map { $_ =~ s/\*/â–ˆ/g; $_ } map { join '', map { $_, $_ } @$_ } @$arrayref;
}

sub align_qrs
{
	my ($qr1, $qr2) = @_;
	return @$qr1 unless $qr2;

	my $offset = ' ' x (length $qr1->[0]);

	my @output;
	while (@$qr1 || @$qr2) {
		my $line = shift(@$qr1) // $offset;
		$line .= ' ' x 4;
		$line .= shift(@$qr2) // '';
		push @output, $line;
	}

	return @output;
}

binmode STDIN, ':encoding(UTF-8)';

my $stdout = !!0;
my $filename = 'wallet.txt';
my $auto_entropy = !!0;
my $help = !!0;
my $words = 24;
my $compat_addresses = 1;
my $segwit_addresses = 0;
my $taproot_addresses = 3;
my $network = 'bitcoin';

GetOptions(
	'auto|a' => \$auto_entropy,
	'file|f=s' => \$filename,
	'stdout|o' => \$stdout,
	'words|w=n' => \$words,
	'compat_addrs|c=n' => \$compat_addresses,
	'segwit_addrs|s=n' => \$segwit_addresses,
	'taproot_addrs|t=n' => \$taproot_addresses,
	'network|n=s' => \$network,
	'help|h' => \$help,
);

my $interactive = !$stdout;

sub echo
{
	my ($message) = @_;

	say $message if $interactive;
	return;
}

sub prompt
{
	my ($info) = @_;
	echo $info;

	my $data = <STDIN>;
	chomp $data;

	return $data;
}

sub get_entropy
{
	return prompt "Enter any random entropy: by rolling dice, drawing cards or other means available";
}

sub get_passphrase
{
	return prompt 'Enter passphrase for your private key. Warning: plaintext!';
}

if ($help) {
	pod2usage(1);
}

if (!$stdout && -e $filename) {
	die "wallet file $filename already exists";
}

die 'words must be between 12 and 24'
	unless $words >= 12 && $words <= 24;
die 'words must be divisible by 3'
	unless $words % 3 == 0;
my $entropy_length = 128 + ($words - 12) * 32 / 3;

my $entropy = $auto_entropy ? undef : get_entropy;
my $pass = get_passphrase;

my $bitcoin_data = App::Bitcoin::PaperWallet->generate($entropy, $pass, {
	compat_addresses => $compat_addresses,
	segwit_addresses => $segwit_addresses,
	taproot_addresses => $taproot_addresses,
	entropy_length => $entropy_length,
	network => $network,
});

my @data;
my $id = substr $bitcoin_data->{addresses}[0], -4;

push @data,
	"-- PASSWORD PROTECTED PRIVATE KEY FOR ID $id --",
	$bitcoin_data->{mnemonic},
	'',
	"-- ADDRESSES FOR ID $id --",
	''
;



( run in 2.071 seconds using v1.01-cache-2.11-cpan-5c0b1e786e0 )