Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 33 additions & 3 deletions include/wally.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,18 @@ inline int base64_get_maximum_length(const STR_IN& str_in, uint32_t flags, size_
return detail::check_ret(__FUNCTION__, ret);
}

template <class STR_IN>
inline int base64_n_get_maximum_length(const STR_IN& str_in, size_t str_len, uint32_t flags, size_t* written) {
int ret = ::wally_base64_n_get_maximum_length(detail::get_p(str_in), str_len, flags, written);
return detail::check_ret(__FUNCTION__, ret);
}

template <class STR_IN, class BYTES_OUT>
inline int base64_n_to_bytes(const STR_IN& str_in, size_t str_len, uint32_t flags, BYTES_OUT& bytes_out, size_t* written) {
int ret = ::wally_base64_n_to_bytes(detail::get_p(str_in), str_len, flags, bytes_out.data(), bytes_out.size(), written);
return detail::check_ret(__FUNCTION__, ret);
}

template <class STR_IN, class BYTES_OUT>
inline int base64_to_bytes(const STR_IN& str_in, uint32_t flags, BYTES_OUT& bytes_out, size_t* written) {
int ret = ::wally_base64_to_bytes(detail::get_p(str_in), flags, bytes_out.data(), bytes_out.size(), written);
Expand Down Expand Up @@ -1202,9 +1214,15 @@ inline int psbt_free(struct wally_psbt* psbt) {
return detail::check_ret(__FUNCTION__, ret);
}

template <class BASE64>
inline int psbt_from_base64(const BASE64& base64, uint32_t flags, struct wally_psbt** output) {
int ret = ::wally_psbt_from_base64(detail::get_p(base64), flags, output);
template <class STR_IN>
inline int psbt_from_base64(const STR_IN& str_in, uint32_t flags, struct wally_psbt** output) {
int ret = ::wally_psbt_from_base64(detail::get_p(str_in), flags, output);
return detail::check_ret(__FUNCTION__, ret);
}

template <class STR_IN>
inline int psbt_from_base64_n(const STR_IN& str_in, size_t str_len, uint32_t flags, struct wally_psbt** output) {
int ret = ::wally_psbt_from_base64_n(detail::get_p(str_in), str_len, flags, output);
return detail::check_ret(__FUNCTION__, ret);
}

Expand Down Expand Up @@ -1402,6 +1420,12 @@ inline int psbt_input_set_signatures(const INPUT& input, const struct wally_map*
return detail::check_ret(__FUNCTION__, ret);
}

template <class INPUT, class PUB_KEY>
inline int psbt_input_set_taproot_internal_key(const INPUT& input, const PUB_KEY& pub_key) {
int ret = ::wally_psbt_input_set_taproot_internal_key(detail::get_p(input), pub_key.data(), pub_key.size());
return detail::check_ret(__FUNCTION__, ret);
}

template <class INPUT, class TAP_SIG>
inline int psbt_input_set_taproot_signature(const INPUT& input, const TAP_SIG& tap_sig) {
int ret = ::wally_psbt_input_set_taproot_signature(detail::get_p(input), tap_sig.data(), tap_sig.size());
Expand Down Expand Up @@ -1509,6 +1533,12 @@ inline int psbt_output_set_script(const OUTPUT& output, const SCRIPT& script) {
return detail::check_ret(__FUNCTION__, ret);
}

template <class OUTPUT, class PUB_KEY>
inline int psbt_output_set_taproot_internal_key(const OUTPUT& output, const PUB_KEY& pub_key) {
int ret = ::wally_psbt_output_set_taproot_internal_key(detail::get_p(output), pub_key.data(), pub_key.size());
return detail::check_ret(__FUNCTION__, ret);
}

template <class OUTPUT>
inline int psbt_output_set_unknowns(const OUTPUT& output, const struct wally_map* map_in) {
int ret = ::wally_psbt_output_set_unknowns(detail::get_p(output), map_in);
Expand Down
24 changes: 24 additions & 0 deletions include/wally_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,19 @@ WALLY_CORE_API int wally_base64_to_bytes(
size_t len,
size_t *written);

/**
* Decode a known-length base64 encoded string back into into binary data.
*
* See `wally_base64_to_bytes`.
*/
WALLY_CORE_API int wally_base64_n_to_bytes(
const char *str_in,
size_t str_len,
uint32_t flags,
unsigned char *bytes_out,
size_t len,
size_t *written);

/**
* Return the maximum length of a base64 encoded string once decoded into bytes.
*
Expand All @@ -369,6 +382,17 @@ WALLY_CORE_API int wally_base64_get_maximum_length(
uint32_t flags,
size_t *written);

/**
* Return the maximum length of a known-length base64 encoded string once decoded into bytes.
*
* See `wally_base64_get_maximum_length`.
*/
WALLY_CORE_API int wally_base64_n_get_maximum_length(
const char *str_in,
size_t str_len,
uint32_t flags,
size_t *written);


#ifndef SWIG
/** The type of an overridable function to allocate memory */
Expand Down
2 changes: 1 addition & 1 deletion include/wally_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ WALLY_CORE_API int wally_map_combine(
/**
* Replace a maps contents with another map.
*
* :param map_in: the destination to combine into.
* :param map_in: the destination to assign to.
* :param source: the source to copy items from.
*
* .. note:: If this call fails, ``map_in`` is left untouched.
Expand Down
42 changes: 39 additions & 3 deletions include/wally_psbt.h
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,18 @@ WALLY_CORE_API int wally_psbt_input_set_taproot_signature(
const unsigned char *tap_sig,
size_t tap_sig_len);

/**
* Set the taproot internal public key in an input.
*
* :param input: The input to update.
* :param pub_key: The x-only internal public key for this input.
* :param pub_key_len: The length of ``pub_key`` in bytes. Must be `EC_XONLY_PUBLIC_KEY_LEN`.
*/
WALLY_CORE_API int wally_psbt_input_set_taproot_internal_key(
struct wally_psbt_input *input,
const unsigned char *pub_key,
size_t pub_key_len);

/**
* Find a partial signature matching a pubkey in an input.
*
Expand Down Expand Up @@ -1422,6 +1434,19 @@ WALLY_CORE_API int wally_psbt_output_set_script(
const unsigned char *script,
size_t script_len);

/**
* Set the taproot internal public key in an output.
*
* :param output: The output to update.
* :param pub_key: The x-only internal public key for this output.
* :param pub_key_len: The length of ``pub_key`` in bytes. Must be `EC_XONLY_PUBLIC_KEY_LEN`.
*/
WALLY_CORE_API int wally_psbt_output_set_taproot_internal_key(
struct wally_psbt_output *output,
const unsigned char *pub_key,
size_t pub_key_len);


#ifndef WALLY_ABI_NO_ELEMENTS
/**
* Set the input blinder index in an output.
Expand Down Expand Up @@ -2363,14 +2388,25 @@ WALLY_CORE_API int wally_psbt_to_bytes(
size_t *written);

/**
* Create a PSBT from its serialized base64 string.
* Create a PSBT from a serialized base64 string.
*
* :param base64: Base64 string to create the PSBT from.
* :param str_in: Base64 string to create the PSBT from.
* :param flags: `WALLY_PSBT_PARSE_FLAG_STRICT` or 0.
* :param output: Destination for the resulting PSBT.
*/
WALLY_CORE_API int wally_psbt_from_base64(
const char *base64,
const char *str_in,
uint32_t flags,
struct wally_psbt **output);

/**
* Create a PSBT from a known-length serialized base64 string.
*
* See `wally_psbt_from_base64`.
*/
WALLY_CORE_API int wally_psbt_from_base64_n(
const char *str_in,
size_t str_len,
uint32_t flags,
struct wally_psbt **output);

Expand Down
6 changes: 6 additions & 0 deletions include/wally_psbt_members.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ WALLY_CORE_API int wally_psbt_get_input_signature(const struct wally_psbt *psbt,
WALLY_CORE_API int wally_psbt_get_input_signature_len(const struct wally_psbt *psbt, size_t index, size_t subindex, size_t *written);
WALLY_CORE_API int wally_psbt_get_input_taproot_signature(const struct wally_psbt *psbt, size_t index, unsigned char *bytes_out, size_t len, size_t *written);
WALLY_CORE_API int wally_psbt_get_input_taproot_signature_len(const struct wally_psbt *psbt, size_t index, size_t *written);
WALLY_CORE_API int wally_psbt_get_input_taproot_internal_key(const struct wally_psbt *psbt, size_t index, unsigned char *bytes_out, size_t len, size_t *written);
WALLY_CORE_API int wally_psbt_get_input_taproot_internal_key_len(const struct wally_psbt *psbt, size_t index, size_t *written);
WALLY_CORE_API int wally_psbt_get_input_unknowns_size(const struct wally_psbt *psbt, size_t index, size_t *written);
WALLY_CORE_API int wally_psbt_find_input_unknown(const struct wally_psbt *psbt, size_t index, const unsigned char *key, size_t key_len, size_t *written);
WALLY_CORE_API int wally_psbt_get_input_unknown(const struct wally_psbt *psbt, size_t index, size_t subindex, unsigned char *bytes_out, size_t len, size_t *written);
Expand Down Expand Up @@ -79,6 +81,7 @@ WALLY_CORE_API int wally_psbt_set_input_final_witness(struct wally_psbt *psbt, s
WALLY_CORE_API int wally_psbt_set_input_keypaths(struct wally_psbt *psbt, size_t index, const struct wally_map *map_in);
WALLY_CORE_API int wally_psbt_set_input_signatures(struct wally_psbt *psbt, size_t index, const struct wally_map *map_in);
WALLY_CORE_API int wally_psbt_set_input_taproot_signature(struct wally_psbt *psbt, size_t index, const unsigned char *sig, size_t sig_len);
WALLY_CORE_API int wally_psbt_set_input_taproot_internal_key(struct wally_psbt *psbt, size_t index, const unsigned char *pub_key, size_t pub_key_len);
WALLY_CORE_API int wally_psbt_add_input_signature(struct wally_psbt *psbt, size_t index, const unsigned char *pub_key, size_t pub_key_len, const unsigned char *sig, size_t sig_len);
WALLY_CORE_API int wally_psbt_set_input_unknowns(struct wally_psbt *psbt, size_t index, const struct wally_map *map_in);
WALLY_CORE_API int wally_psbt_set_input_sighash(struct wally_psbt *psbt, size_t index, uint32_t sighash);
Expand Down Expand Up @@ -183,6 +186,8 @@ WALLY_CORE_API int wally_psbt_get_output_script(const struct wally_psbt *psbt, s
WALLY_CORE_API int wally_psbt_get_output_script_len(const struct wally_psbt *psbt, size_t index, size_t *written);
WALLY_CORE_API int wally_psbt_get_output_amount(const struct wally_psbt *psbt, size_t index, uint64_t *value_out);
WALLY_CORE_API int wally_psbt_has_output_amount(const struct wally_psbt *psbt, size_t index, size_t *written);
WALLY_CORE_API int wally_psbt_get_output_taproot_internal_key(const struct wally_psbt *psbt, size_t index, unsigned char *bytes_out, size_t len, size_t *written);
WALLY_CORE_API int wally_psbt_get_output_taproot_internal_key_len(const struct wally_psbt *psbt, size_t index, size_t *written);

WALLY_CORE_API int wally_psbt_set_output_redeem_script(struct wally_psbt *psbt, size_t index, const unsigned char *script, size_t script_len);
WALLY_CORE_API int wally_psbt_set_output_witness_script(struct wally_psbt *psbt, size_t index, const unsigned char *script, size_t script_len);
Expand All @@ -191,6 +196,7 @@ WALLY_CORE_API int wally_psbt_set_output_unknowns(struct wally_psbt *psbt, size_
WALLY_CORE_API int wally_psbt_set_output_script(struct wally_psbt *psbt, size_t index, const unsigned char *script, size_t script_len);
WALLY_CORE_API int wally_psbt_set_output_amount(struct wally_psbt *psbt, size_t index, uint64_t amount);
WALLY_CORE_API int wally_psbt_clear_output_amount(struct wally_psbt *psbt, size_t index);
WALLY_CORE_API int wally_psbt_set_output_taproot_internal_key(struct wally_psbt *psbt, size_t index, const unsigned char *pub_key, size_t pub_key_len);

#ifndef WALLY_ABI_NO_ELEMENTS
WALLY_CORE_API int wally_psbt_get_output_blinder_index(const struct wally_psbt *psbt, size_t index, uint32_t *value_out);
Expand Down
35 changes: 24 additions & 11 deletions src/base_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,42 +25,55 @@ int wally_base64_from_bytes(const unsigned char *bytes, size_t bytes_len,
return WALLY_OK;
}

int wally_base64_get_maximum_length(const char *str_in, uint32_t flags, size_t *written)
int wally_base64_n_get_maximum_length(const char *str_in, size_t str_len, uint32_t flags, size_t *written)
{
if (written)
*written = 0;

if (!str_in || !*str_in || flags || !written)
if (!str_in || !str_len || flags || !written)
return WALLY_EINVAL;

*written = base64_decoded_length(strlen(str_in));
*written = base64_decoded_length(str_len);
return WALLY_OK;
}

int wally_base64_to_bytes(const char *str_in, uint32_t flags,
unsigned char *bytes_out, size_t len,
size_t *written)
int wally_base64_get_maximum_length(const char *str_in, uint32_t flags, size_t *written)
{
size_t str_len = str_in ? strlen(str_in) : 0;
return wally_base64_n_get_maximum_length(str_in, str_len, flags, written);
}

int wally_base64_n_to_bytes(const char *str_in, size_t str_len, uint32_t flags,
unsigned char *bytes_out, size_t len,
size_t *written)
{
size_t decode_len, str_in_len;
size_t decode_len;
ssize_t actual_len;

if (written)
*written = 0;

if (!str_in || flags || !bytes_out || !len || !written)
if (!str_in || !str_len || flags || !bytes_out || !len || !written)
return WALLY_EINVAL;

str_in_len = strlen(str_in);
decode_len = base64_decoded_length(str_in_len);
decode_len = base64_decoded_length(str_len);
if (len < decode_len) {
/* Not enough space; return the amount required */
*written = decode_len;
return WALLY_OK;
}

actual_len = base64_decode((char *)bytes_out, decode_len, str_in, str_in_len);
actual_len = base64_decode((char *)bytes_out, decode_len, str_in, str_len);
if (actual_len < 0)
return WALLY_EINVAL; /* Invalid base64 data */
*written = actual_len;
return WALLY_OK;
}

int wally_base64_to_bytes(const char *str_in, uint32_t flags,
unsigned char *bytes_out, size_t len,
size_t *written)
{
size_t str_len = str_in ? strlen(str_in) : 0;
return wally_base64_n_to_bytes(str_in, str_len, flags, bytes_out, len, written);
}
17 changes: 14 additions & 3 deletions src/psbt.c
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ MAP_INNER_FIELD(input, redeem_script, PSBT_IN_REDEEM_SCRIPT, psbt_fields)
MAP_INNER_FIELD(input, witness_script, PSBT_IN_WITNESS_SCRIPT, psbt_fields)
MAP_INNER_FIELD(input, final_scriptsig, PSBT_IN_FINAL_SCRIPTSIG, psbt_fields)
MAP_INNER_FIELD(input, taproot_signature, PSBT_IN_TAP_KEY_SIG, psbt_fields)
MAP_INNER_FIELD(input, taproot_internal_key, PSBT_IN_TAP_INTERNAL_KEY, psbt_fields)
SET_STRUCT(wally_psbt_input, final_witness, wally_tx_witness_stack,
wally_tx_witness_stack_clone_alloc, wally_tx_witness_stack_free)
SET_MAP(wally_psbt_input, keypath,)
Expand Down Expand Up @@ -870,6 +871,7 @@ static int psbt_input_free(struct wally_psbt_input *input, bool free_parent)

MAP_INNER_FIELD(output, redeem_script, PSBT_OUT_REDEEM_SCRIPT, psbt_fields)
MAP_INNER_FIELD(output, witness_script, PSBT_OUT_WITNESS_SCRIPT, psbt_fields)
MAP_INNER_FIELD(output, taproot_internal_key, PSBT_OUT_TAP_INTERNAL_KEY, psbt_fields)
SET_MAP(wally_psbt_output, keypath,)
ADD_KEYPATH(wally_psbt_output)
ADD_TAP_KEYPATH(wally_psbt_output)
Expand Down Expand Up @@ -3357,22 +3359,23 @@ int wally_psbt_to_bytes(const struct wally_psbt *psbt, uint32_t flags,
return WALLY_OK;
}

int wally_psbt_from_base64(const char *base64, uint32_t flags, struct wally_psbt **output)
int wally_psbt_from_base64_n(const char *str_in, size_t str_len, uint32_t flags, struct wally_psbt **output)
{
unsigned char *decoded;
size_t max_len, written;
int ret;

OUTPUT_CHECK;
if ((ret = wally_base64_get_maximum_length(base64, 0, &max_len)) != WALLY_OK)
if ((ret = wally_base64_n_get_maximum_length(str_in, str_len, 0, &max_len)) != WALLY_OK)
return ret;

/* Allocate the buffer to decode into */
if ((decoded = wally_malloc(max_len)) == NULL)
return WALLY_ENOMEM;

/* Decode the base64 psbt into binary */
if ((ret = wally_base64_to_bytes(base64, 0, decoded, max_len, &written)) != WALLY_OK)
ret = wally_base64_n_to_bytes(str_in, str_len, 0, decoded, max_len, &written);
if (ret != WALLY_OK)
goto done;

if (written <= sizeof(PSBT_MAGIC)) {
Expand All @@ -3392,6 +3395,12 @@ int wally_psbt_from_base64(const char *base64, uint32_t flags, struct wally_psbt
return ret;
}

int wally_psbt_from_base64(const char *str_in, uint32_t flags, struct wally_psbt **output)
{
size_t str_len = str_in ? strlen(str_in) : 0;
return wally_psbt_from_base64_n(str_in, str_len, flags, output);
}

int wally_psbt_to_base64(const struct wally_psbt *psbt, uint32_t flags, char **output)
{
unsigned char *buff;
Expand Down Expand Up @@ -5567,6 +5576,7 @@ PSBT_FIELD(input, redeem_script, PSBT_0)
PSBT_FIELD(input, witness_script, PSBT_0)
PSBT_FIELD(input, final_scriptsig, PSBT_0)
PSBT_FIELD(input, taproot_signature, PSBT_0)
PSBT_FIELD(input, taproot_internal_key, PSBT_0)
PSBT_GET_S(input, final_witness, wally_tx_witness_stack, wally_tx_witness_stack_clone_alloc)
PSBT_GET_M(input, keypath)
PSBT_GET_M(input, signature)
Expand Down Expand Up @@ -5703,6 +5713,7 @@ int wally_psbt_clear_input_required_lockheight(struct wally_psbt *psbt, size_t i
if (!psbt || psbt->version != PSBT_2) return WALLY_EINVAL;
return wally_psbt_input_clear_required_lockheight(psbt_get_input(psbt, index));
}
PSBT_FIELD(output, taproot_internal_key, PSBT_0)

#ifndef WALLY_ABI_NO_ELEMENTS
PSBT_GET_I_PSET(input, amount, uint64_t, PSBT_2)
Expand Down
Loading
Loading