package Bitcoin::Crypto::Transaction::Digest::Result;
$Bitcoin::Crypto::Transaction::Digest::Result::VERSION = '4.003';
use v5.14;
use warnings;

use Mooish::Base -standard;

use Bitcoin::Crypto::Types -types;
use Bitcoin::Crypto::Exception;
use Bitcoin::Crypto::Util::Internal qw(hash256 tagged_hash);

use overload
	q{""} => "as_string",
	fallback => 1;

has param 'taproot' => (
	coerce => Bool,
	default => !!0,
);

has option 'preimage' => (
	coerce => ByteStr,
);

has param 'hash' => (
	coerce => ByteStr,
	lazy => 1,
);

sub _build_hash
{
	my $self = shift;
	my $preimage = $self->preimage;

	Bitcoin::Crypto::Exception->raise(
		"can't hash without preimage"
	) unless defined $preimage;

	if ($self->taproot) {
		return tagged_hash('TapSighash', $preimage);
	}
	else {
		return hash256($preimage);
	}
}

sub as_string
{
	my ($self) = @_;

	# backcompat - returns preimage

	Bitcoin::Crypto::Exception->raise(
		'no preimage generated by digesting'
	) unless $self->has_preimage;

	return $self->preimage;
}

1;

__END__
=head1 NAME

Bitcoin::Crypto::Transaction::Digest::Result - Result of digesting a transaction

=head1 SYNOPSIS

	my $digest = $tx->get_digest(...);

	say to_format [hex => $digest];

=head1 DESCRIPTION

This is a simple class that holds the result of digesting a transaction by
L<Bitcoin::Crypto::Transaction/get_digest> and similar methods. It stringifies
automatically to L</preimage>, or throws an exception if there is no preimage.

=head1 INTERFACE

=head2 Attributes

=head3 taproot

I<Available in the constructor>.

This boolean flag controls whether legacy (when false, uses C<hash256>) or
taproot (when true, uses C<tagged_hash>) hashing should be used to obtain
L</hash> from L</preimage>. Default: C<false>.

=head3 preimage

I<Available in the constructor>.

This bytestring is a preimage of the transaction. Note that preimage can not be
set in some edge cases.

I<predicate:> C<has_preimage>

=head3 hash

I<Available in the constructor>.

This bytestring is a hashed preimage. If it is not set, it will be generated lazily.

=head2 Methods

=head3 new

	$block = $class->new(%args)

This is a standard Moo constructor, which can be used to create the object. It
takes arguments specified in L</Attributes>.

Returns class instance.

=head3 as_string

	$preimage = $object->as_string()

Returns L</preimage>. Same as using the object in the string context.

=head1 SEE ALSO

=over

=item L<Bitcoin::Crypto::Transaction>

=back

=cut

