bbrtj / btcpaywall

Self-hosted bitcoin payment system
BSD 2-Clause "Simplified" License
7 stars 3 forks source link

Bitcoin::Crypto::set_network no longer returns a Bitcoin::Crypto::Key::ExtPrivate causing Component::MasterKey to die here. #1

Closed mvsjes2 closed 2 years ago

mvsjes2 commented 2 years ago

Component::MasterKey lazy initializes it's _master_key member, expecting a Bitcoin::Crypto::Key::ExtPrivate to be returned from the init routine:

              btc_extprv
                      ->from_mnemonic($key->slurp)
                      ->set_network($self->env->getenv('CRYPTO_NETWORK'));

At Bitcoin-Crypto-0.997, this appeared to be working correctly, set_network returns the current Key object.

At Bitcoin-Crypto-1.002, set_network no longer returns the key object, it returns a Bitcoin::Crypto::Network object (see Bitcoin::Crypto::Role::Network):

has "network" => (
        is => "ro",
        isa => (InstanceOf ["Bitcoin::Crypto::Network"])
                ->plus_coercions(Str, q{Bitcoin::Crypto::Network->get($_)}),
        default => sub {
                return Bitcoin::Crypto::Network->get;
        },
        coerce => 1,
        writer => "set_network"
);

The error returned from btcpaywalls is:

Reference bless( {"bip44_coin" => 0,"extprv_version" => 76066276,"extp...) did not pass type constraint (not isa Bitcoin::Crypto::Key::ExtPrivate) (in $self->{"_mas
ter_key"}) at /home/btcpaywall/gitsrc/btcpaywall/lib/Component/MasterKey.pm line 29
    "InstanceOf["Bitcoin::Crypto::Key::ExtPrivate"]" requires that the reference isa Bitcoin::Crypto::Key::ExtPrivate
    The reference (in $self->{"_master_key"}) isa Bitcoin::Crypto::Network and Moo::Object
bbrtj commented 2 years ago

Hello @mvsjes2, thanks for the report, that's a good catch. This changed in Bitcoin::Crypto 1.000, which was end of the beta phase. I replaced the custom setter subroutine with a Moo setter plus a type coercion, which works pretty much the same, minus the return value.

Since all of the setters return $self and the documentation was not updated, I consider it Bitcoin::Crypto bug and will patch it in the following days. Before I do that, the return value of the set_network method is pretty much whatever Moo returns from its setter, which seems to be object field's value.

I'll also replace the code you pasted with the one that will work with current as well as the next version of Bitcoin::Crypto.

bbrtj commented 2 years ago

Newly uploaded Bitcoin::Crypto version 1.003 has the problem with the return value fixed. The code here will stay as it is after your pull request. I'll close this ticket, thank you!