diff --git a/extmod/foundation-rust/Cargo.lock b/extmod/foundation-rust/Cargo.lock index 83c0cff54..0a0421699 100644 --- a/extmod/foundation-rust/Cargo.lock +++ b/extmod/foundation-rust/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "atomic-polyfill" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c314e70d181aa6053b26e3f7fbf86d1dfff84f816a6175b967666b3506ef7289" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" dependencies = [ "critical-section", ] @@ -26,11 +26,20 @@ dependencies = [ "rustc_version 0.2.3", ] +[[package]] +name = "bitcoin-private" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73290177011694f38ec25e165d0387ab7ea749a4b81cd4c80dae5988229f7a57" + [[package]] name = "bitcoin_hashes" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4" +checksum = "5d7066118b13d4b20b23645932dfb3a81ce7e29f95726c2036fa33cd7b092501" +dependencies = [ + "bitcoin-private", +] [[package]] name = "bitfield" @@ -112,14 +121,46 @@ version = "0.1.0" dependencies = [ "cortex-m", "critical-section", + "foundation-ur", + "foundation-urtypes", "heapless", "minicbor", "once_cell", "rand", "rand_core", "secp256k1", - "ur", - "ur-foundation", + "uuid", +] + +[[package]] +name = "foundation-arena" +version = "0.1.0" +source = "git+https://github.com/Foundation-Devices/foundation-rs?branch=main#7fb778d9d3ff9b3925aba3abff16cdb3d387e2e3" + +[[package]] +name = "foundation-ur" +version = "0.1.0" +source = "git+https://github.com/Foundation-Devices/foundation-rs?branch=main#7fb778d9d3ff9b3925aba3abff16cdb3d387e2e3" +dependencies = [ + "bitcoin_hashes", + "crc", + "heapless", + "hex", + "itertools", + "minicbor", + "phf", + "rand_xoshiro", +] + +[[package]] +name = "foundation-urtypes" +version = "0.1.0" +source = "git+https://github.com/Foundation-Devices/foundation-rs?branch=main#7fb778d9d3ff9b3925aba3abff16cdb3d387e2e3" +dependencies = [ + "foundation-arena", + "heapless", + "hex", + "minicbor", "uuid", ] @@ -172,9 +213,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.146" +version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "lock_api" @@ -203,7 +244,7 @@ checksum = "1154809406efdb7982841adb6311b3d095b46f78342dd646736122fe6b19e267" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -233,9 +274,9 @@ dependencies = [ [[package]] name = "phf" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "928c6535de93548188ef63bb7c4036bd415cd8f36ad25af44b9789b2ee72a48c" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" dependencies = [ "phf_macros", "phf_shared", @@ -243,9 +284,9 @@ dependencies = [ [[package]] name = "phf_generator" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1181c94580fa345f50f19d738aaa39c0ed30a600d95cb2d3e23f94266f14fbf" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" dependencies = [ "phf_shared", "rand", @@ -253,22 +294,22 @@ dependencies = [ [[package]] name = "phf_macros" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92aacdc5f16768709a569e913f7451034034178b05bdc8acda226659a3dccc66" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" dependencies = [ "phf_generator", "phf_shared", "proc-macro2", "quote", - "syn", + "syn 2.0.25", ] [[package]] name = "phf_shared" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1fb5f6f826b772a8d4c0394209441e7d37cbbb967ae9c7e0e8134365c9ee676" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" dependencies = [ "siphasher", ] @@ -281,18 +322,18 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.60" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" +checksum = "78803b62cbf1f46fde80d7c0e803111524b9877184cfe7c3033659490ac7a7da" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" dependencies = [ "proc-macro2", ] @@ -433,43 +474,27 @@ dependencies = [ ] [[package]] -name = "unicode-ident" -version = "1.0.9" +name = "syn" +version = "2.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" - -[[package]] -name = "ur" -version = "0.3.0" -source = "git+https://github.com/Foundation-Devices/ur-rs?branch=dev#69297429b4ff6444e049883f79305df678130b30" +checksum = "15e3fc8c0c74267e2df136e5e5fb656a464158aa57624053375eb9c8c6e25ae2" dependencies = [ - "bitcoin_hashes", - "crc", - "heapless", - "itertools", - "minicbor", - "phf", - "rand_xoshiro", - "uuid", + "proc-macro2", + "quote", + "unicode-ident", ] [[package]] -name = "ur-foundation" -version = "0.1.0" -source = "git+https://github.com/Foundation-Devices/rust-ur-foundation?branch=dev-v0.1.0#0ae542143ba9232d734f58a0bee1b22d9a0517a2" -dependencies = [ - "heapless", - "hex", - "minicbor", - "ur", - "uuid", -] +name = "unicode-ident" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" [[package]] name = "uuid" -version = "1.3.4" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa2982af2eec27de306107c027578ff7f423d65f7250e40ce0fea8f45248b81" +checksum = "d023da39d1fde5a8a3fe1f3e01ca9632ada0a63e9797de55a879d6e2236277be" [[package]] name = "vcell" diff --git a/extmod/foundation-rust/Cargo.toml b/extmod/foundation-rust/Cargo.toml index 1a2d95eb7..2c4ef5686 100644 --- a/extmod/foundation-rust/Cargo.toml +++ b/extmod/foundation-rust/Cargo.toml @@ -24,14 +24,14 @@ default-features = false version = "1" default-features = false -[dependencies.ur] -git = "https://github.com/Foundation-Devices/ur-rs" -branch = "dev" +[dependencies.foundation-ur] +git = "https://github.com/Foundation-Devices/foundation-rs" +branch = "main" default-features = false -[dependencies.ur-foundation] -git = "https://github.com/Foundation-Devices/rust-ur-foundation" -branch = "dev-v0.1.0" +[dependencies.foundation-urtypes] +git = "https://github.com/Foundation-Devices/foundation-rs" +branch = "main" default-features = false [target.'cfg(target_arch = "arm")'.dependencies.cortex-m] diff --git a/extmod/foundation-rust/include/foundation.h b/extmod/foundation-rust/include/foundation.h index 0a88e3b40..cbb790588 100644 --- a/extmod/foundation-rust/include/foundation.h +++ b/extmod/foundation-rust/include/foundation.h @@ -74,11 +74,6 @@ */ #define UR_NETWORK_TESTNET 1 -/** - * Maximum number of components that a `crypto-keypath` can have. - */ -#define UR_MAX_PATH_COMPONENTS 4 - typedef enum { BTC, } UR_CoinType; @@ -441,7 +436,7 @@ bool ur_decode_single_part(const uint8_t *ur, * # Parameters * * - `value` is the uniform resource to encode. - * - `max_fragment_len` is the maximum fragment length in bytes. + * - `max_chars` is the maximum fragment length in bytes. * * # Safety * diff --git a/extmod/foundation-rust/src/ur/decoder.rs b/extmod/foundation-rust/src/ur/decoder.rs index d2871bbfe..8b81dc608 100644 --- a/extmod/foundation-rust/src/ur/decoder.rs +++ b/extmod/foundation-rust/src/ur/decoder.rs @@ -5,13 +5,13 @@ use core::{fmt, slice, str}; -use ur::UR; -use ur_foundation::{ur, ur::decoder::Error}; - -use crate::ur::{ - max_fragment_len, max_message_len, registry::UR_Value, UR_Error, +use foundation_ur::{ + bytewords, bytewords::Style, decoder::Error, max_fragment_len, + HeaplessDecoder, UR, }; +use crate::ur::{max_message_len, registry::UR_Value, UR_Error, UR_MAX_TYPE}; + /// Maximum size of an encoded Uniform Resource. /// /// This value assumes a QR code of version of 16 with ECC L using @@ -25,7 +25,7 @@ pub const UR_DECODER_MAX_SEQUENCE_COUNT: usize = 128; /// Maximum fragment length. pub const UR_DECODER_MAX_FRAGMENT_LEN: usize = - max_fragment_len(UR_DECODER_MAX_STRING); + max_fragment_len(UR_MAX_TYPE, usize::MAX, UR_DECODER_MAX_STRING); /// Maximum message length that can be decoded. pub const UR_DECODER_MAX_MESSAGE_LEN: usize = 24 * 1024; @@ -49,7 +49,7 @@ pub const UR_DECODER_MAX_UR_TYPE: usize = "crypto-coin-info".len(); #[used] #[cfg_attr(dtcm, link_section = ".dtcm")] pub static mut UR_DECODER: UR_Decoder = UR_Decoder { - inner: ur::HeaplessDecoder::new_heapless(), + inner: HeaplessDecoder::new(), }; /// cbindgen:ignore @@ -62,7 +62,7 @@ static mut UR_DECODER_SINGLE_PART_MESSAGE: heapless::Vec< /// Uniform Resource decoder. pub struct UR_Decoder { - inner: ur::HeaplessDecoder< + inner: HeaplessDecoder< UR_DECODER_MAX_MESSAGE_LEN, UR_DECODER_MAX_MIXED_PARTS, UR_DECODER_MAX_FRAGMENT_LEN, @@ -213,11 +213,7 @@ pub unsafe extern "C" fn ur_validate(ur: *const u8, ur_len: usize) -> bool { .as_bytewords() .expect("Parsed URs shouldn't be in a deserialized variant"); - return ur::bytewords::validate( - bytewords, - ur::bytewords::Style::Minimal, - ) - .is_ok(); + return bytewords::validate(bytewords, Style::Minimal).is_ok(); } false @@ -256,11 +252,11 @@ pub unsafe extern "C" fn ur_decode_single_part( .resize(UR_DECODER_MAX_SINGLE_PART_MESSAGE_LEN, 0) .expect("Message buffer should have the same size as in the constant"); - let result = ur::bytewords::decode_to_slice( + let result = bytewords::decode_to_slice( ur.as_bytewords() .expect("Uniform Resource should contain bytewords"), message, - ur::bytewords::Style::Minimal, + Style::Minimal, ) .map_err(|e| unsafe { UR_Error::other(&e) }); diff --git a/extmod/foundation-rust/src/ur/encoder.rs b/extmod/foundation-rust/src/ur/encoder.rs index 788f8b786..66beba201 100644 --- a/extmod/foundation-rust/src/ur/encoder.rs +++ b/extmod/foundation-rust/src/ur/encoder.rs @@ -5,10 +5,12 @@ use core::{ffi::c_char, fmt::Write}; +use foundation_ur::{max_fragment_len, HeaplessEncoder}; +use minicbor::{Encode, Encoder}; + use crate::ur::{ - decoder::UR_DECODER_MAX_MESSAGE_LEN, max_fragment_len, registry::UR_Value, + decoder::UR_DECODER_MAX_MESSAGE_LEN, registry::UR_Value, UR_MAX_TYPE, }; -use ur_foundation::ur; /// Maximum size of an encoded Uniform Resource. /// @@ -29,11 +31,11 @@ pub const UR_ENCODER_MIN_STRING: usize = 224; /// parts that the message is divided into. /// cbindgen:ignore pub const UR_ENCODER_MAX_FRAGMENT_LEN: usize = - max_fragment_len(UR_ENCODER_MAX_STRING); + max_fragment_len(UR_MAX_TYPE, usize::MAX, UR_ENCODER_MAX_STRING); /// Minimum fragment length. pub const UR_ENCODER_MIN_FRAGMENT_LEN: usize = - max_fragment_len(UR_ENCODER_MIN_STRING); + max_fragment_len(UR_MAX_TYPE, usize::MAX, UR_ENCODER_MIN_STRING); /// Maximum sequence count for the decoder. /// @@ -52,7 +54,7 @@ pub const UR_ENCODER_MAX_MESSAGE_LEN: usize = UR_DECODER_MAX_MESSAGE_LEN; #[used] #[cfg_attr(dtcm, link_section = ".dtcm")] pub static mut UR_ENCODER: UR_Encoder = UR_Encoder { - inner: ur::HeaplessEncoder::new_heapless(), + inner: HeaplessEncoder::new(), }; /// cbindgen:ignore @@ -69,7 +71,7 @@ static mut UR_ENCODER_MESSAGE: heapless::Vec = /// Uniform Resource encoder. pub struct UR_Encoder { - inner: ur::HeaplessEncoder< + inner: HeaplessEncoder< 'static, 'static, UR_ENCODER_MAX_FRAGMENT_LEN, @@ -82,7 +84,7 @@ pub struct UR_Encoder { /// # Parameters /// /// - `value` is the uniform resource to encode. -/// - `max_fragment_len` is the maximum fragment length in bytes. +/// - `max_chars` is the maximum fragment length in bytes. /// /// # Safety /// @@ -107,11 +109,18 @@ pub unsafe extern "C" fn ur_encoder_start( let message = unsafe { &mut UR_ENCODER_MESSAGE }; message.clear(); - value.encode(Writer(message)).expect("Couldn't encode UR"); - - encoder - .inner - .start(value.ur_type(), message, max_fragment_len(max_chars)); + let mut e = Encoder::new(Writer(message)); + value.encode(&mut e, &mut ()).expect("Couldn't encode UR"); + + encoder.inner.start( + value.ur_type(), + message, + max_fragment_len( + value.ur_type(), + UR_ENCODER_MAX_SEQUENCE_COUNT, + max_chars, + ), + ); } /// Returns the UR corresponding to the next fountain encoded part. diff --git a/extmod/foundation-rust/src/ur/mod.rs b/extmod/foundation-rust/src/ur/mod.rs index 9e777d88d..ff04ba4dc 100644 --- a/extmod/foundation-rust/src/ur/mod.rs +++ b/extmod/foundation-rust/src/ur/mod.rs @@ -4,38 +4,23 @@ //! Uniform Resources. use core::{ffi::c_char, fmt, fmt::Write}; -use ur::fountain::part::Part; -use ur_foundation::ur; /// cbindgen:ignore #[used] #[cfg_attr(sram4, link_section = ".sram4")] static mut UR_ERROR: heapless::String<256> = heapless::String::new(); -pub const fn max_fragment_len(max_characters: usize) -> usize { - const MAX_UR_PREFIX: usize = "ur:crypto-coin-info/".len() - + digit_count(u32::MAX as usize) - + "-".len() - + digit_count(u32::MAX as usize) - + "/".len(); - - let max_chars_for_part = max_characters.saturating_sub(MAX_UR_PREFIX); - let max_bytes_for_part = (max_chars_for_part / 2).saturating_sub(4); - max_bytes_for_part.saturating_sub(Part::max_encoded_len()) -} +/// The maximum length of a UR type that will be accepted or produced. +/// cbindgen:ignore +const UR_MAX_TYPE: &str = "crypto-coin-info"; -pub const fn max_message_len(max_characters: usize) -> usize { - const MAX_UR_PREFIX: usize = "ur:crypto-coin-info/".len(); +const fn max_message_len(max_characters: usize) -> usize { + const MAX_UR_PREFIX: usize = "ur:".len() + UR_MAX_TYPE.len(); let max_chars_for_message = max_characters.saturating_sub(MAX_UR_PREFIX); (max_chars_for_message / 2).saturating_sub(4) } -/// Count the number of digits in a number. -pub const fn digit_count(v: usize) -> usize { - (v.ilog10() + 1) as usize -} - #[repr(C)] pub enum UR_ErrorKind { UR_ERROR_KIND_OTHER, diff --git a/extmod/foundation-rust/src/ur/registry.rs b/extmod/foundation-rust/src/ur/registry.rs index 03fd04004..fd0ae520b 100644 --- a/extmod/foundation-rust/src/ur/registry.rs +++ b/extmod/foundation-rust/src/ur/registry.rs @@ -1,71 +1,29 @@ // SPDX-FileCopyrightText: © 2023 Foundation Devices, Inc. // SPDX-License-Identifier: GPL-3.0-or-later -use crate::ur::UR_Error; use core::{ffi::c_char, num::NonZeroU32, slice, str}; -use ur::registry::{ - crypto_hdkey::{ - BaseHDKey, CoinType, CryptoCoinInfo, CryptoKeypath, DerivedKey, - PathComponent, - }, - crypto_request::Empty, - BaseValue, -}; -use ur_foundation::{ + +use foundation_urtypes::{ passport::Model, - registry::passport::{PassportRequest, PassportResponse}, + registry::PassportRequest, + registry::{ + CoinType, CryptoCoinInfo, CryptoHDKey, CryptoKeypath, DerivedKey, + PassportResponse, PathComponents, + }, supply_chain_validation::{Challenge, Solution}, - ur, + value::Value, }; + use uuid::Uuid; +use crate::ur::UR_Error; + /// `mainnet` network. pub const UR_NETWORK_MAINNET: u32 = 0; /// `testnet` network. pub const UR_NETWORK_TESTNET: u32 = 1; -/// Maximum number of components that a `crypto-keypath` can have. -pub const UR_MAX_PATH_COMPONENTS: usize = 4; - -/// cbindgen:ignore -type PathComponents = heapless::Vec; -/// cbindgen:ignore -type StandardValue<'a> = BaseValue<'a, Empty, PathComponents>; - -/// cbindgen:ignore -#[derive(Debug)] -pub enum Value<'a> { - Standard(StandardValue<'a>), - PassportRequest(PassportRequest), - PassportResponse(PassportResponse<'a>), -} - -impl<'a> Value<'a> { - pub fn encode( - &self, - w: W, - ) -> Result<(), minicbor::encode::Error> { - match self { - Value::Standard(ref standard) => minicbor::encode(standard, w), - Value::PassportRequest(ref passport_request) => { - minicbor::encode(passport_request, w) - } - Value::PassportResponse(ref passport_response) => { - minicbor::encode(passport_response, w) - } - } - } - - pub fn ur_type(&self) -> &'static str { - match self { - Value::Standard(value) => value.ur_type(), - Value::PassportRequest(_) => "crypto-request", - Value::PassportResponse(_) => "crypto-response", - } - } -} - /// A uniform resource. #[repr(C)] pub enum UR_Value { @@ -90,34 +48,25 @@ impl UR_Value { ur_type: &str, message: &[u8], ) -> Result { - let value = match ur_type { - "crypto-request" => Value::PassportRequest( - minicbor::decode(message).map_err(|e| UR_Error::other(&e))?, - ), - _ => Value::Standard( - StandardValue::from_ur(ur_type, message) - .map_err(|e| UR_Error::other(&e))?, - ), - }; + let value = Value::from_ur(ur_type, message) + .map_err(|e| UR_Error::other(&e))?; let value = match value { - Value::Standard(StandardValue::Bytes(bytes)) => UR_Value::Bytes { + Value::Bytes(bytes) => UR_Value::Bytes { data: bytes.as_ptr(), len: bytes.len(), }, - Value::Standard(StandardValue::CryptoPSBT(psbt)) => { - UR_Value::CryptoPSBT { - data: psbt.as_ptr(), - len: psbt.len(), - } - } + Value::CryptoPsbt(psbt) => UR_Value::CryptoPSBT { + data: psbt.as_ptr(), + len: psbt.len(), + }, Value::PassportRequest(passport_request) => { UR_Value::PassportRequest(passport_request.into()) } _ => { return Err(UR_Error::unsupported( &"Unsupported uniform resource", - )) + )); } }; @@ -135,15 +84,13 @@ impl UR_Value { match self { UR_Value::Bytes { data, len } => { let buf = unsafe { slice::from_raw_parts(*data, *len) }; - Value::Standard(StandardValue::Bytes(buf.into())) + Value::Bytes(buf) } UR_Value::CryptoPSBT { data, len } => { let buf = unsafe { slice::from_raw_parts(*data, *len) }; - Value::Standard(StandardValue::CryptoPSBT(buf.into())) - } - UR_Value::CryptoHDKey(v) => { - Value::Standard(StandardValue::CryptoHDKey(v.into())) + Value::CryptoPsbt(buf) } + UR_Value::CryptoHDKey(v) => Value::CryptoHDKey(v.into()), UR_Value::PassportRequest(_) => panic!( "Not implemented as it isn't needed. Should be unreachable" ), @@ -158,14 +105,11 @@ pub enum UR_HDKey { DerivedKey(UR_DerivedKey), } -impl<'a, C> From<&'a UR_HDKey> for BaseHDKey<'a, C> -where - C: ur::collections::Vec, -{ - fn from(value: &'a UR_HDKey) -> BaseHDKey<'a, C> { +impl<'a> From<&'a UR_HDKey> for CryptoHDKey<'a> { + fn from(value: &'a UR_HDKey) -> CryptoHDKey<'a> { match value { UR_HDKey::DerivedKey(v) => { - BaseHDKey::DerivedKey(DerivedKey::from(v)) + CryptoHDKey::DerivedKey(DerivedKey::from(v)) } } } @@ -196,11 +140,8 @@ pub struct UR_DerivedKey { pub parent_fingerprint: u32, } -impl<'a, C> From<&'a UR_DerivedKey> for DerivedKey<'a, C> -where - C: ur::collections::Vec, -{ - fn from(value: &'a UR_DerivedKey) -> DerivedKey<'a, C> { +impl<'a> From<&'a UR_DerivedKey> for DerivedKey<'a> { + fn from(value: &'a UR_DerivedKey) -> DerivedKey<'a> { DerivedKey { is_private: value.is_private, key_data: value.key_data, @@ -272,11 +213,9 @@ pub struct UR_CryptoKeypath { /// Whether `depth` is present. pub has_depth: bool, } -impl From> for UR_CryptoKeypath -where - C: ur::collections::Vec, -{ - fn from(v: CryptoKeypath) -> UR_CryptoKeypath { + +impl<'a> From> for UR_CryptoKeypath { + fn from(v: CryptoKeypath<'a>) -> UR_CryptoKeypath { UR_CryptoKeypath { source_fingerprint: v .source_fingerprint @@ -288,13 +227,10 @@ where } } -impl From<&UR_CryptoKeypath> for CryptoKeypath -where - C: ur::collections::Vec, -{ - fn from(v: &UR_CryptoKeypath) -> CryptoKeypath { +impl<'a> From<&'a UR_CryptoKeypath> for CryptoKeypath<'a> { + fn from(v: &UR_CryptoKeypath) -> CryptoKeypath<'a> { CryptoKeypath { - components: C::default(), + components: PathComponents::from(&[]), source_fingerprint: NonZeroU32::new(v.source_fingerprint), depth: if v.has_depth { Some(v.depth) } else { None }, } @@ -522,6 +458,7 @@ pub extern "C" fn ur_registry_new_crypto_psbt( ) { *value = UR_Value::CryptoPSBT { data, len }; } + /// Create a new Passport ustom `crypto-response` UR. #[no_mangle] pub extern "C" fn ur_registry_new_passport_response(