File Coverage

blib/lib/App/Bitcoin/PaperWallet.pm
Criterion Covered Total %
statement 26 26 100.0
branch 1 2 50.0
condition 1 2 50.0
subroutine 6 6 100.0
pod 1 2 50.0
total 35 38 92.1


line stmt bran cond sub pod time code
1             package App::Bitcoin::PaperWallet;
2              
3             our $VERSION = '1.01';
4              
5 2     2   151190 use v5.12;
  2         18  
6 2     2   16 use warnings;
  2         4  
  2         102  
7              
8 2     2   1111 use Bitcoin::Crypto qw(btc_extprv);
  2         667  
  2         114  
9 2     2   1203 use Digest::SHA qw(sha256);
  2         6953  
  2         627  
10              
11             sub get_addresses
12             {
13 1     1 0 4 my ($key, $count) = @_;
14 1   50     9 $count //= 4;
15              
16 1         2 my @addrs;
17 1         8 my $priv = $key->derive_key_bip44(index => 0)->get_basic_key;
18 1         55062 my $addr = $priv->get_public_key->get_compat_address;
19 1         12172 push @addrs, $addr;
20              
21 1         8 for my $ind (1 .. $count - 1) {
22 3         32 my $priv = $key->derive_key_bip44(index => $ind)->get_basic_key;
23 3         139984 my $addr = $priv->get_public_key->get_segwit_address;
24 3         15321 push @addrs, $addr;
25             }
26              
27 1         46 return @addrs;
28             }
29              
30             sub generate
31             {
32 1     1 1 101 my ($class, $entropy, $pass, $address_count) = @_;
33              
34 1 50       10 my $mnemonic = defined $entropy
35             ? btc_extprv->mnemonic_from_entropy(sha256($entropy))
36             : btc_extprv->generate_mnemonic(256)
37             ;
38              
39 1         545482 my $key = btc_extprv->from_mnemonic($mnemonic, $pass);
40              
41             return {
42 1         30069 mnemonic => $mnemonic,
43             addresses => [get_addresses($key, $address_count)],
44             };
45             }
46              
47             1;
48              
49             __END__
50              
51             =head1 NAME
52              
53             App::Bitcoin::PaperWallet - Generate printable cold storage of bitcoins
54              
55             =head1 SYNOPSIS
56              
57             use App::Bitcoin::PaperWallet;
58              
59             my $hash = App::Bitcoin::PaperWallet->generate($entropy, $password, $address_count // 4);
60              
61             my $mnemonic = $hash->{mnemonic};
62             my $addresses = $hash->{addresses};
63              
64             =head1 DESCRIPTION
65              
66             This module allows you to generate a Hierarchical Deterministic BIP44 compilant Bitcoin wallet.
67              
68             This package contains high level cryptographic operations for doing that. See L<paper-wallet> for the main script of this distribution.
69              
70             =head1 FUNCTIONS
71              
72             =head2 generate
73              
74             my $hash = App::Bitcoin::PaperWallet->generate($entropy, $password, $address_count // 4);
75              
76             Not exported, should be used as a class method. Returns a hash containing two keys: C<mnemonic> (string) and C<addresses> (array reference of strings).
77              
78             C<$entropy> is meant to be user-defined entropy (string) that will be passed through sha256 to obtain wallet seed. Can be passed C<undef> explicitly to use cryptographically secure random number generator instead.
79              
80             C<$password> is a password that will be used to secure the generated mnemonic. Passing empty string will disable the password protection. Note that password does not have to be strong, since it will only secure the mnemonic in case someone obtained physical access to your mnemonic. Using a hard, long password increases the possibility you will not be able to claim your bitcoins in the future.
81              
82             Optional C<$address_count> is the number of addresses that will be generated (default 4). The first address is always SegWit compat address, while the rest are SegWit native addresses.
83              
84             =head1 SEE ALSO
85              
86             L<Bitcoin::Crypto>
87              
88             =head1 AUTHOR
89              
90             Bartosz Jarzyna, E<lt>brtastic.dev@gmail.comE<gt>
91              
92             =head1 COPYRIGHT AND LICENSE
93              
94             Copyright (C) 2021 by Bartosz Jarzyna
95              
96             This library is free software; you can redistribute it and/or modify
97             it under the same terms as Perl itself, either Perl version 5.12.0 or,
98             at your option, any later version of Perl 5 you may have available.
99              
100              
101             =cut