Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use concrete signature types #715

Merged
merged 55 commits into from
Jul 14, 2023
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
b54b833
Update crypto and stronghold
Jul 3, 2023
53a5e6b
Use strong typed ed25519 public key and signature
Jul 3, 2023
64694be
clippy
Jul 3, 2023
0c973e9
Merge branch 'develop' into feat/ed25519-signature
Jul 3, 2023
d0f4ff5
Chnagelog
Jul 3, 2023
61f383c
Fix tests
Jul 5, 2023
103172e
Fix serialization
Jul 5, 2023
4a16333
Merge branch 'develop' into feat/ed25519-signature
Jul 5, 2023
2ffaec0
changelog
Jul 5, 2023
32b6635
import nit
Jul 5, 2023
6ddc8ea
Merge branch 'develop' into feat/ed25519-signature
Jul 5, 2023
986b100
Example imports and clippy
Jul 6, 2023
215645b
Merge branch 'develop' into feat/ed25519-signature
Jul 6, 2023
4ac8adb
Remove serde-big-array dep
Jul 6, 2023
2678394
Merge branch 'develop' into feat/ed25519-signature
Jul 11, 2023
04b2f4d
Update crypto again
Jul 11, 2023
d7cc350
Update bindings
Jul 11, 2023
c6f01d9
Merge branch 'develop' into feat/ed25519-signature
Jul 11, 2023
46a38ef
Fix no_std
Jul 11, 2023
0e25ea0
shuffle features
Jul 11, 2023
ce5a08e
Fix python test and slip10 derive chain handling. Remove std feature
Jul 11, 2023
db6cf4e
Use stronghold release
Jul 11, 2023
2f7709d
changelog
Jul 11, 2023
acc0c72
Replace more instances of IBip32Chain
Jul 11, 2023
1a2d259
Try to fix python serialization
Jul 11, 2023
8e9cd29
Fix nodejs stuff
Jul 11, 2023
e70d903
hopefully fix some serde stuff
Jul 11, 2023
145da9d
Merge branch 'develop' into feat/ed25519-signature
Jul 11, 2023
68e0472
oh python....you so silly
Jul 11, 2023
22caa4b
Default coint type
Jul 11, 2023
432324b
delete wasm compatability CI
Jul 11, 2023
63503b4
fix python import
Jul 11, 2023
e147011
Fix tests I broke
Jul 12, 2023
ee019b1
Fix Bip44Def defaults
Jul 12, 2023
52cf269
Add migration and serde utils
Jul 12, 2023
743cedf
fix no_std again
Jul 12, 2023
bfdbde4
Fix test
Jul 12, 2023
71ed7fc
Merge branch 'develop' into feat/ed25519-signature
Jul 12, 2023
b102041
Merge branch 'develop' into feat/ed25519-signature
Jul 13, 2023
c71462e
Use constants in test
Jul 13, 2023
c4c2328
separate changelogs
Jul 13, 2023
a273bc2
more changelog
Jul 13, 2023
9987670
python changelog
Jul 13, 2023
d0d7948
Fix rand feature import
Jul 13, 2023
836a7f6
Add missing serde tag
Jul 13, 2023
e1b0ea8
Update bindings/python/CHANGELOG.md
thibault-martinez Jul 14, 2023
a9ce7ca
Add Bip44 to python changelog
thibault-martinez Jul 14, 2023
8657b27
Changelog nits
thibault-martinez Jul 14, 2023
f08cee2
Merge branch 'develop' into feat/ed25519-signature
thibault-martinez Jul 14, 2023
a575cb6
PR suggestions
Jul 14, 2023
e15ffb8
Merge branch 'develop' into feat/ed25519-signature
Jul 14, 2023
bbc4d40
Merge branch 'develop' into feat/ed25519-signature
Jul 14, 2023
cbe7e8d
organizing all my bikes
Jul 14, 2023
b8d574c
😾
Jul 14, 2023
fa0f5eb
>:I
Jul 14, 2023
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
221 changes: 154 additions & 67 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion bindings/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ backtrace = { version = "0.3.67", default-features = false }
derivative = { version = "2.2.0", default-features = false }
fern-logger = { version = "0.5.0", default-features = false }
futures = { version = "0.3.28", default-features = false }
iota-crypto = { version = "0.20.1", default-features = false, features = [ "slip10" ] }
iota-crypto = { version = "0.21.1", default-features = false, features = [ "slip10" ] }
log = { version = "0.4.18", default-features = false }
packable = { version = "0.8.1", default-features = false }
prefix-hex = { version = "0.7.0", default-features = false }
Expand Down
14 changes: 8 additions & 6 deletions bindings/core/src/method_handler/secret_manager.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2023 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

use crypto::keys::slip10::Chain;
use crypto::keys::slip10::Segment;
use iota_sdk::{
client::{
api::PreparedTransactionData,
Expand Down Expand Up @@ -52,30 +52,32 @@ pub(crate) async fn call_secret_manager_method_internal(
} => {
let transaction_essence_hash: [u8; 32] = prefix_hex::decode(transaction_essence_hash)?;
let unlock: Unlock = secret_manager
.signature_unlock(&transaction_essence_hash, &Chain::from_u32_hardened(chain))
.signature_unlock(
&transaction_essence_hash,
&chain.into_iter().map(Segment::harden).collect::<Vec<_>>(),
)
.await?;

Response::SignatureUnlock((&unlock).into())
}
SecretManagerMethod::SignEd25519 { message, chain } => {
let msg: Vec<u8> = prefix_hex::decode(message)?;
let signature = secret_manager
.sign_ed25519(&msg, &Chain::from_u32_hardened(chain))
.sign_ed25519(&msg, &chain.into_iter().map(Segment::harden).collect::<Vec<_>>())
.await?;
Response::Ed25519Signature(Ed25519SignatureDto::from(&signature))
}
SecretManagerMethod::SignSecp256k1Ecdsa { message, chain } => {
let msg: Vec<u8> = prefix_hex::decode(message)?;
let (public_key, signature) = secret_manager
.sign_secp256k1_ecdsa(&msg, &Chain::from_u32(chain))
.await?;
let (public_key, signature) = secret_manager.sign_secp256k1_ecdsa(&msg, &chain).await?;
Response::Secp256k1EcdsaSignature {
public_key: prefix_hex::encode(public_key.to_bytes()),
signature: prefix_hex::encode(signature.to_bytes()),
}
}
#[cfg(feature = "stronghold")]
SecretManagerMethod::StoreMnemonic { mnemonic } => {
let mnemonic = mnemonic.into();
if let SecretManager::Stronghold(secret_manager) = &*secret_manager {
secret_manager.store_mnemonic(mnemonic).await?;
Response::Ok
Expand Down
17 changes: 8 additions & 9 deletions bindings/core/src/method_handler/utils.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright 2023 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

use crypto::keys::bip39::Mnemonic;
use iota_sdk::{
client::{hex_public_key_to_bech32_address, hex_to_bech32, verify_mnemonic, Client},
types::block::{
Expand All @@ -11,7 +12,6 @@ use iota_sdk::{
Block,
},
};
use zeroize::Zeroize;

use crate::{method::UtilsMethod, response::Response, Result};

Expand All @@ -29,11 +29,10 @@ pub(crate) fn call_utils_method_internal(method: UtilsMethod) -> Result<Response
}
UtilsMethod::ParseBech32Address { address } => Response::ParsedBech32Address(AddressDto::from(address.inner())),
UtilsMethod::IsAddressValid { address } => Response::Bool(Address::is_valid_bech32(&address)),
UtilsMethod::GenerateMnemonic => Response::GeneratedMnemonic(Client::generate_mnemonic()?),
UtilsMethod::MnemonicToHexSeed { mut mnemonic } => {
let response = Response::MnemonicHexSeed(Client::mnemonic_to_hex_seed(&mnemonic)?);
mnemonic.zeroize();
response
UtilsMethod::GenerateMnemonic => Response::GeneratedMnemonic(Client::generate_mnemonic()?.to_string()),
UtilsMethod::MnemonicToHexSeed { mnemonic } => {
let mnemonic = Mnemonic::from(mnemonic);
kwek20 marked this conversation as resolved.
Show resolved Hide resolved
Response::MnemonicHexSeed(Client::mnemonic_to_hex_seed(&mnemonic)?)
}
UtilsMethod::BlockId { block } => {
let block = Block::try_from_dto_unverified(block)?;
Expand All @@ -57,15 +56,15 @@ pub(crate) fn call_utils_method_internal(method: UtilsMethod) -> Result<Response
UtilsMethod::HashTransactionEssence { essence } => Response::TransactionEssenceHash(prefix_hex::encode(
TransactionEssence::try_from_dto_unverified(essence)?.hash(),
)),
UtilsMethod::VerifyMnemonic { mut mnemonic } => {
UtilsMethod::VerifyMnemonic { mnemonic } => {
let mnemonic = Mnemonic::from(mnemonic);
verify_mnemonic(&mnemonic)?;
mnemonic.zeroize();
Response::Ok
}
UtilsMethod::VerifyEd25519Signature { signature, message } => {
let signature = Ed25519Signature::try_from(signature)?;
let message: Vec<u8> = prefix_hex::decode(message)?;
Response::Bool(signature.verify(&message)?)
Response::Bool(signature.verify(&message))
}
UtilsMethod::VerifySecp256k1EcdsaSignature {
public_key,
Expand Down
1 change: 1 addition & 0 deletions bindings/core/src/method_handler/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ pub(crate) async fn call_wallet_method_internal(wallet: &Wallet, method: WalletM
}
#[cfg(feature = "stronghold")]
WalletMethod::StoreMnemonic { mnemonic } => {
let mnemonic = mnemonic.into();
wallet.store_mnemonic(mnemonic).await?;
kwek20 marked this conversation as resolved.
Show resolved Hide resolved
Response::Ok
}
Expand Down
31 changes: 18 additions & 13 deletions cli/src/helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ use clap::Parser;
use dialoguer::{console::Term, theme::ColorfulTheme, Input, Select};
use iota_sdk::{
client::{utils::Password, verify_mnemonic},
crypto::keys::bip39::Mnemonic,
wallet::{Account, Wallet},
};
use tokio::{
fs::{self, OpenOptions},
io::{AsyncBufReadExt, AsyncWriteExt, BufReader},
};
use zeroize::Zeroize;

use crate::{
command::{account::AccountCli, wallet::WalletCli},
Expand Down Expand Up @@ -110,7 +112,7 @@ pub async fn bytes_from_hex_or_file(hex: Option<String>, file: Option<String>) -
})
}

pub async fn enter_or_generate_mnemonic() -> Result<String, Error> {
pub async fn enter_or_generate_mnemonic() -> Result<Mnemonic, Error> {
let choices = ["Generate a new mnemonic", "Enter a mnemonic"];
let selected_choice = Select::with_theme(&ColorfulTheme::default())
.with_prompt("Select how to provide a mnemonic")
Expand All @@ -127,7 +129,7 @@ pub async fn enter_or_generate_mnemonic() -> Result<String, Error> {
Ok(mnemnonic)
}

pub async fn generate_mnemonic() -> Result<String, Error> {
pub async fn generate_mnemonic() -> Result<Mnemonic, Error> {
let mnemonic = iota_sdk::client::generate_mnemonic()?;
println_log_info!("Mnemonic has been generated.");
let choices = [
Expand All @@ -144,7 +146,7 @@ pub async fn generate_mnemonic() -> Result<String, Error> {

if [0, 2].contains(&selected_choice) {
println!("YOUR MNEMONIC:");
println!("{}", mnemonic);
println!("{}", mnemonic.as_ref());
}
if [1, 2].contains(&selected_choice) {
write_mnemonic_to_file(DEFAULT_MNEMONIC_FILE_PATH, &mnemonic).await?;
Expand All @@ -160,11 +162,13 @@ pub async fn generate_mnemonic() -> Result<String, Error> {
Ok(mnemonic)
}

pub fn enter_mnemonic() -> Result<String, Error> {
pub fn enter_mnemonic() -> Result<Mnemonic, Error> {
loop {
let input = Input::<String>::new()
.with_prompt("Enter your mnemonic")
.interact_text()?;
let input = Mnemonic::from(
Input::<String>::new()
.with_prompt("Enter your mnemonic")
.interact_text()?,
);
if verify_mnemonic(&input).is_err() {
println_log_error!("Invalid mnemonic. Please enter a bip-39 conform mnemonic.");
} else {
Expand All @@ -173,7 +177,7 @@ pub fn enter_mnemonic() -> Result<String, Error> {
}
}

pub async fn import_mnemonic(path: &str) -> Result<String, Error> {
pub async fn import_mnemonic(path: &str) -> Result<Mnemonic, Error> {
let mut mnemonics = read_mnemonics_from_file(path).await?;
if mnemonics.is_empty() {
println_log_error!("No valid mnemonics found in '{path}'.");
Expand Down Expand Up @@ -210,16 +214,17 @@ async fn write_mnemonic_to_file(path: &str, mnemonic: &str) -> Result<(), Error>
Ok(())
}

async fn read_mnemonics_from_file(path: &str) -> Result<Vec<String>, Error> {
async fn read_mnemonics_from_file(path: &str) -> Result<Vec<Mnemonic>, Error> {
let file = OpenOptions::new().read(true).open(path).await?;
let mut lines = BufReader::new(file).lines();
let mut mnemonics = Vec::new();
let mut line_index = 1;
while let Some(line) = lines.next_line().await? {
while let Some(mut line) = lines.next_line().await? {
// we allow surrounding whitespace in the file
let trimmed = line.trim();
if verify_mnemonic(trimmed).is_ok() {
mnemonics.push(trimmed.to_string());
let trimmed = Mnemonic::from(line.trim().to_owned());
line.zeroize();
if verify_mnemonic(&trimmed).is_ok() {
mnemonics.push(trimmed);
} else {
return Err(Error::Miscellaneous(format!(
"Invalid mnemonic in file '{path}' at line '{line_index}'."
Expand Down
5 changes: 5 additions & 0 deletions sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Rename `Account::prepare_mint_native_token` to `prepare_create_native_token`, `Account::prepare_increase_native_token_supply` to `prepare_mint_native_token`, `Account::prepare_decrease_native_token_supply` to `prepare_melt_native_token`;
- Rename `MintNativeTokenParams` to `CreateNativeTokenParams`;
- Rename `MintNativeTokenTransaction` to `CreateNativeTokenTransaction` and `PreparedMintNativeTokenTransaction` to `PreparedCreateNativeTokenTransaction` (including their corresponding DTOs);
- `Signature::Ed25519` now holds a boxed type;
- `Ed25519Signature::new` renamed to `try_from_bytes` and returns a Result;
- `Ed25519Signature::new`, `public_key`, `signature` now use concrete types;
- `Ed25519Signature::verify` is no longer fallable;
- `Mnemonic` type used over Strings where possible;
- Rename `SendAmountParams` to `SendParams`;
- Rename `Account::send` to `send_outputs`, `Account::send_amount` to `send`, `Account::prepare_send_amount` to `prepare_send`;

Expand Down
4 changes: 2 additions & 2 deletions sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ derive_more = { version = "0.99.17", default-features = false, features = [ "fro
getset = { version = "0.1.2", default-features = false }
hashbrown = { version = "0.13.2", default-features = false, features = [ "ahash", "inline-more" ] }
hex = { version = "0.4.3", default-features = false }
iota-crypto = { version = "0.20.1", default-features = false, features = [ "blake2b", "ed25519", "secp256k1", "ternary_encoding" ] }
iota-crypto = { version = "0.21.1", default-features = false, features = [ "blake2b", "ed25519", "secp256k1", "ternary_encoding" ] }
iterator-sorted = { version = "0.1.0", default-features = false }
packable = { version = "0.8.1", default-features = false, features = [ "primitive-types" ] }
prefix-hex = { version = "0.7.0", default-features = false, features = [ "primitive-types" ] }
Expand All @@ -44,7 +44,7 @@ heck = { version = "0.4.1", default-features = false, optional = true }
instant = { version = "0.1.12", default-features = false, optional = true }
iota-ledger-nano = { version = "1.0.0-alpha.4", default-features = false, optional = true }
# iota_stronghold = { version = "1.0.5", default-features = false, optional = true }
iota_stronghold = { git = "https://github.com/iotaledger/stronghold.rs", rev = "9df6d19de325481771d69b47534d151e03eae623", default-features = false, optional = true }
iota_stronghold = { git = "https://github.com/iotaledger/stronghold.rs", branch = "2.0", default-features = false, optional = true }
Thoralf-M marked this conversation as resolved.
Show resolved Hide resolved
log = { version = "0.4.18", default-features = false, optional = true }
num_cpus = { version = "1.15.0", default-features = false, optional = true }
once_cell = { version = "1.17.2", default-features = false, optional = true }
Expand Down
5 changes: 2 additions & 3 deletions sdk/examples/client/stronghold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
//! cargo run --release --all-features --example client_stronghold
//! ```

use crypto::keys::bip39::Mnemonic;
thibault-martinez marked this conversation as resolved.
Show resolved Hide resolved
use iota_sdk::client::{
api::GetAddressesOptions,
constants::{SHIMMER_COIN_TYPE, SHIMMER_TESTNET_BECH32_HRP},
Expand All @@ -23,9 +24,7 @@ async fn main() -> Result<()> {

// This example uses secrets in environment variables for simplicity which should not be done in production.
dotenvy::dotenv().ok();

let mnemonic = std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap();

let mnemonic = Mnemonic::from(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap());
// The mnemonic only needs to be stored the first time
stronghold_secret_manager.store_mnemonic(mnemonic).await?;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
//! cargo run --release --all-features --example create_account
//! ```

use crypto::keys::bip39::Mnemonic;
use iota_sdk::{
client::{
constants::SHIMMER_COIN_TYPE,
Expand All @@ -29,7 +30,7 @@ async fn main() -> Result<()> {
.build(std::env::var("STRONGHOLD_SNAPSHOT_PATH").unwrap())?;

// Only required the first time, can also be generated with `manager.generate_mnemonic()?`
let mnemonic = std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap();
let mnemonic = Mnemonic::from(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap());

// The mnemonic only needs to be stored the first time
secret_manager.store_mnemonic(mnemonic).await?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use iota_sdk::client::{Client, Result};
async fn main() -> Result<()> {
let mnemonic = Client::generate_mnemonic()?;

println!("Generated mnemonic:\n{mnemonic}");
println!("Generated mnemonic:\n{}", mnemonic.as_ref());

Ok(())
}
19 changes: 12 additions & 7 deletions sdk/examples/how_tos/sign_and_verify_ed25519/sign_ed25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
//! cargo run --release --all-features --example sign_ed25519
//! ```

use crypto::keys::{bip39::Mnemonic, slip10::Segment};
use iota_sdk::{
client::{
constants::{HD_WALLET_TYPE, SHIMMER_COIN_TYPE},
hex_public_key_to_bech32_address,
secret::{stronghold::StrongholdSecretManager, SecretManage, SecretManager},
},
crypto::keys::slip10::Chain,
wallet::Result,
};

Expand All @@ -34,29 +34,34 @@ async fn main() -> Result<()> {
.build("sign_ed25519.stronghold")?;

stronghold
.store_mnemonic(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())
.store_mnemonic(Mnemonic::from(
std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap(),
))
.await?;

let bip32_chain = Chain::from_u32_hardened([
let bip32_chain = [
HD_WALLET_TYPE,
SHIMMER_COIN_TYPE,
ACCOUNT_INDEX,
INTERNAL_ADDRESS as u32,
ADDRESS_INDEX,
]);
]
.into_iter()
.map(Segment::harden)
.collect::<Vec<_>>();

let message = FOUNDRY_METADATA.as_bytes();
let signature = SecretManager::Stronghold(stronghold)
.sign_ed25519(message, &bip32_chain)
.await?;
println!(
"Public key: {}\nSignature: {}",
prefix_hex::encode(signature.public_key()),
prefix_hex::encode(signature.signature()),
prefix_hex::encode(signature.public_key().as_ref()),
prefix_hex::encode(signature.signature().to_bytes()),
);

// Hash the public key to get the address
let bech32_address = hex_public_key_to_bech32_address(&prefix_hex::encode(signature.public_key()), "rms")?;
let bech32_address = hex_public_key_to_bech32_address(&prefix_hex::encode(signature.public_key().as_ref()), "rms")?;
println!("Address: {bech32_address}");

Ok(())
Expand Down
2 changes: 1 addition & 1 deletion sdk/examples/wallet/getting_started.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ async fn main() -> Result<()> {
// INFO: It is best practice to back up the mnemonic somewhere secure
let mnemonic = wallet.generate_mnemonic()?;
wallet.store_mnemonic(mnemonic.clone()).await?;
println!("Created a wallet from the mnemonic:\n'{mnemonic}'");
println!("Created a wallet from the mnemonic:\n'{}'", mnemonic.as_ref());

// Create an account
let alias = "Alice";
Expand Down
3 changes: 2 additions & 1 deletion sdk/examples/wallet/offline_signing/0_generate_addresses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
//! cargo run --release --all-features --example 0_generate_addresses
//! ```

use crypto::keys::bip39::Mnemonic;
use iota_sdk::{
client::{
constants::{SHIMMER_BECH32_HRP, SHIMMER_COIN_TYPE},
Expand All @@ -32,7 +33,7 @@ async fn main() -> Result<()> {
.password(std::env::var("STRONGHOLD_PASSWORD").unwrap())
.build(STRONGHOLD_SNAPSHOT_PATH)?;

let mnemonic = std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap();
let mnemonic = Mnemonic::from(std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap());

// The mnemonic only needs to be stored the first time
secret_manager.store_mnemonic(mnemonic).await?;
Expand Down
21 changes: 13 additions & 8 deletions sdk/src/client/api/block_builder/input_selection/automatic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

use std::collections::HashSet;

use crypto::keys::slip10::Chain;
use crypto::keys::slip10::Segment;

use crate::{
client::{
Expand Down Expand Up @@ -176,13 +176,18 @@ impl<'a> ClientBlockBuilder<'a> {
available_inputs.push(InputSigningData {
output: output_with_meta.output,
output_metadata: output_with_meta.metadata,
chain: Some(Chain::from_u32_hardened([
HD_WALLET_TYPE,
self.coin_type,
account_index,
internal as u32,
address_index,
])),
chain: Some(
[
HD_WALLET_TYPE,
self.coin_type,
account_index,
internal as u32,
address_index,
]
.into_iter()
.map(Segment::harden)
.collect(),
),
});
}
}
Expand Down
Loading
Loading