diff --git a/bindings/core/Cargo.toml b/bindings/core/Cargo.toml index 339198725d..291a429598 100644 --- a/bindings/core/Cargo.toml +++ b/bindings/core/Cargo.toml @@ -40,3 +40,4 @@ participation = ["iota-sdk/participation"] rocksdb = ["iota-sdk/rocksdb"] storage = ["iota-sdk/storage"] stronghold = ["iota-sdk/stronghold"] +private_key_secret_manager = ["iota-sdk/private_key_secret_manager"] diff --git a/bindings/nodejs-old/examples/ledger_nano.js b/bindings/nodejs-old/examples/ledger_nano.js index 9221724bfa..7c263beb09 100644 --- a/bindings/nodejs-old/examples/ledger_nano.js +++ b/bindings/nodejs-old/examples/ledger_nano.js @@ -3,7 +3,7 @@ require('dotenv').config({ path: path.resolve(__dirname, '.env') }); const { AccountManager, CoinType } = require('@iota/wallet'); // In this example we will create addresses with a ledger nano hardware wallet -// To use the ledger nano simulator clone https://github.com/iotaledger/ledger-shimmer-app, run `git submodule init && git submodule update --recursive`, +// To use the ledger nano simulator clone https://github.com/iotaledger/ledger-iota-app, run `git submodule init && git submodule update --recursive`, // then `./build.sh -m nanos|nanox|nanosplus -s` and use `true` for `LedgerNano`. async function run() { diff --git a/bindings/nodejs/CHANGELOG.md b/bindings/nodejs/CHANGELOG.md index dc00ee7e7b..de9126299f 100644 --- a/bindings/nodejs/CHANGELOG.md +++ b/bindings/nodejs/CHANGELOG.md @@ -28,6 +28,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `GenericQueryParameter, UnlockableByAddress` types; - `Irc27Metadata` and `Irc30Metadata` helpers; - `Utils::outputHexBytes`; +- `PrivateKeySecretManager`; + +## 1.0.12 - 2023-09-25 + +### Changed + +- Made `TransactionOptions.allowMicroAmount` optional; + +### Fixed + +- Parsing of `RegularTransactionEssence.payload`; +- Don't error if custom remainder address is provided with ledger nano; ## 1.0.11 - 2023-09-14 diff --git a/bindings/nodejs/Cargo.toml b/bindings/nodejs/Cargo.toml index efb31c5732..0d438d149d 100644 --- a/bindings/nodejs/Cargo.toml +++ b/bindings/nodejs/Cargo.toml @@ -26,6 +26,7 @@ iota-sdk-bindings-core = { path = "../core", default-features = false, features "participation", "rocksdb", "mqtt", + "private_key_secret_manager" ] } log = { version = "0.4.20", default-features = false } diff --git a/bindings/nodejs/examples/secret_manager/ledger-nano.ts b/bindings/nodejs/examples/secret_manager/ledger-nano.ts index 667cba263f..14deeafd0c 100644 --- a/bindings/nodejs/examples/secret_manager/ledger-nano.ts +++ b/bindings/nodejs/examples/secret_manager/ledger-nano.ts @@ -8,7 +8,7 @@ require('dotenv').config({ path: '.env' }); // yarn run-example ./secret_manager/ledger-nano.ts // In this example we will get the ledger status and generate an address -// To use the ledger nano simulator clone https://github.com/iotaledger/ledger-shimmer-app, run `git submodule init && git submodule update --recursive`, +// To use the ledger nano simulator clone https://github.com/iotaledger/ledger-iota-app, run `git submodule init && git submodule update --recursive`, // then `./build.sh -m nanos|nanox|nanosplus -s` and use `true` in `LedgerSecretManager::new(true)`. async function run() { initLogger(); diff --git a/bindings/nodejs/lib/types/block/payload/transaction/essence.ts b/bindings/nodejs/lib/types/block/payload/transaction/essence.ts index ff72fa6a0b..b7ad1df95b 100644 --- a/bindings/nodejs/lib/types/block/payload/transaction/essence.ts +++ b/bindings/nodejs/lib/types/block/payload/transaction/essence.ts @@ -2,11 +2,11 @@ // SPDX-License-Identifier: Apache-2.0 import { Type } from 'class-transformer'; -import { PayloadDiscriminator } from '..'; import { HexEncodedString } from '../../../utils'; import { Input, InputDiscriminator } from '../../input'; import { Output, OutputDiscriminator } from '../../output'; -import { Payload } from '../payload'; +import { Payload, PayloadType } from '../payload'; +import { TaggedDataPayload } from '../tagged/tagged'; /** * All of the essence types. @@ -39,6 +39,16 @@ abstract class TransactionEssence { } } +/** + * PayloadDiscriminator for payloads inside of a TransactionEssence. + */ +const PayloadDiscriminator = { + property: 'type', + subTypes: [ + { value: TaggedDataPayload, name: PayloadType.TaggedData as any }, + ], +}; + /** * RegularTransactionEssence transaction essence. */ diff --git a/bindings/nodejs/lib/types/secret_manager/secret-manager.ts b/bindings/nodejs/lib/types/secret_manager/secret-manager.ts index 34c777485a..0b7c9ae54d 100644 --- a/bindings/nodejs/lib/types/secret_manager/secret-manager.ts +++ b/bindings/nodejs/lib/types/secret_manager/secret-manager.ts @@ -33,11 +33,17 @@ export interface StrongholdSecretManager { }; } +/** Secret manager based on a single ED25519 private key. */ +export interface PrivateKeySecretManager { + privateKey: HexEncodedString; +} + /** Supported secret managers */ export type SecretManagerType = | LedgerNanoSecretManager | MnemonicSecretManager | StrongholdSecretManager + | PrivateKeySecretManager | PlaceholderSecretManager; export interface Secp256k1EcdsaSignature { diff --git a/bindings/nodejs/lib/types/wallet/transaction-options.ts b/bindings/nodejs/lib/types/wallet/transaction-options.ts index c79292e99c..579760bb6f 100644 --- a/bindings/nodejs/lib/types/wallet/transaction-options.ts +++ b/bindings/nodejs/lib/types/wallet/transaction-options.ts @@ -26,7 +26,7 @@ export interface TransactionOptions { /** Optional note, that is only stored locally. */ note?: string; /** Whether to allow sending a micro amount. */ - allowMicroAmount: boolean; + allowMicroAmount?: boolean; } /** The possible remainder value strategies. */ diff --git a/bindings/python/examples/secret_manager/ledger_nano.py b/bindings/python/examples/secret_manager/ledger_nano.py index a9f2f9420a..6a2266e307 100644 --- a/bindings/python/examples/secret_manager/ledger_nano.py +++ b/bindings/python/examples/secret_manager/ledger_nano.py @@ -5,7 +5,7 @@ load_dotenv() # In this example we will get the ledger status and generate an address -# To use the ledger nano simulator clone https://github.com/iotaledger/ledger-shimmer-app, run `git submodule init && git submodule update --recursive`, +# To use the ledger nano simulator clone https://github.com/iotaledger/ledger-iota-app, run `git submodule init && git submodule update --recursive`, # then `./build.sh -m nanos|nanox|nanosplus -s` and use `True` in # `LedgerNanoSecretManager(True)`. diff --git a/sdk/CHANGELOG.md b/sdk/CHANGELOG.md index d713498848..0978ca8a2d 100644 --- a/sdk/CHANGELOG.md +++ b/sdk/CHANGELOG.md @@ -42,6 +42,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `migrate_db_chrysalis_to_stardust()` returns an error if no chrysalis data was found; +### Fixed + +- Format of `milestoneIndex` query parameter of `ClientInner::event_status`; +- Don't error if custom remainder address is provided with ledger nano; + ## 1.0.3 - 2023-09-07 ### Added diff --git a/sdk/examples/client/ledger_nano.rs b/sdk/examples/client/ledger_nano.rs index 3b83715854..cd0d2ea713 100644 --- a/sdk/examples/client/ledger_nano.rs +++ b/sdk/examples/client/ledger_nano.rs @@ -4,7 +4,7 @@ //! In this example we will create testnet addresses with a simulated ledger nano hardware wallet. //! //! To use the ledger nano simulator, run the following commands: -//! 1. `clone https://github.com/iotaledger/ledger-shimmer-app` +//! 1. `clone https://github.com/iotaledger/ledger-iota-app` //! 2. `cd ledger-shimmer-app` //! 3. `git submodule init && git submodule update --recursive` //! 4. `./build.sh -m nanos|nanox|nanosplus -s` diff --git a/sdk/examples/client/ledger_nano_transaction.rs b/sdk/examples/client/ledger_nano_transaction.rs index 3029286067..05ec2b0f74 100644 --- a/sdk/examples/client/ledger_nano_transaction.rs +++ b/sdk/examples/client/ledger_nano_transaction.rs @@ -4,7 +4,7 @@ //! In this example we will create a testnet transaction with a simulated ledger nano hardware wallet. //! //! To use the ledger nano simulator, run the following commands: -//! 1. `clone https://github.com/iotaledger/ledger-shimmer-app` +//! 1. `clone https://github.com/iotaledger/ledger-iota-app` //! 2. `cd ledger-shimmer-app` //! 3. `git submodule init && git submodule update --recursive` //! 4. `./build.sh -m nanos|nanox|nanosplus -s` diff --git a/sdk/examples/wallet/ledger_nano.rs b/sdk/examples/wallet/ledger_nano.rs index 3842bc9f88..caa272af05 100644 --- a/sdk/examples/wallet/ledger_nano.rs +++ b/sdk/examples/wallet/ledger_nano.rs @@ -4,7 +4,7 @@ //! In this example we will create addresses with a ledger nano hardware wallet. //! //! To use the ledger nano simulator -//! * clone https://github.com/iotaledger/ledger-shimmer-app, +//! * clone https://github.com/iotaledger/ledger-iota-app, //! * run `git submodule init && git submodule update --recursive`, //! * run `./build.sh -m nanos|nanox|nanosplus -s`, and //! * use `true` in `LedgerSecretManager::new(true)`. diff --git a/sdk/src/client/api/block_builder/input_selection/core/remainder.rs b/sdk/src/client/api/block_builder/input_selection/core/remainder.rs index b4abf79145..bcd6716c87 100644 --- a/sdk/src/client/api/block_builder/input_selection/core/remainder.rs +++ b/sdk/src/client/api/block_builder/input_selection/core/remainder.rs @@ -21,9 +21,26 @@ use crate::{ impl InputSelection { // Gets the remainder address from configuration of finds one from the inputs. - fn get_remainder_address(&self) -> Option<(Address, Option)> { - if self.remainder_address.is_some() { - return self.remainder_address.map(|address| (address, None)); + fn get_remainder_address(&self) -> Result)>, Error> { + if let Some(remainder_address) = self.remainder_address { + // Search in inputs for the Bip44 chain for the remainder address, so the ledger can regenerate it + for input in self.available_inputs.iter().chain(self.selected_inputs.iter()) { + let alias_transition = is_alias_transition( + &input.output, + *input.output_id(), + self.outputs.as_slice(), + self.burn.as_ref(), + ); + let (required_address, _) = + input + .output + .required_and_unlocked_address(self.timestamp, input.output_id(), alias_transition)?; + + if required_address == remainder_address { + return Ok(Some((remainder_address, input.chain))); + } + } + return Ok(Some((remainder_address, None))); } for input in &self.selected_inputs { @@ -33,19 +50,17 @@ impl InputSelection { self.outputs.as_slice(), self.burn.as_ref(), ); - // PANIC: safe to unwrap as outputs with no address have been filtered out already. let required_address = input .output - .required_and_unlocked_address(self.timestamp, input.output_id(), alias_transition) - .unwrap() + .required_and_unlocked_address(self.timestamp, input.output_id(), alias_transition)? .0; if required_address.is_ed25519() { - return Some((required_address, input.chain)); + return Ok(Some((required_address, input.chain))); } } - None + Ok(None) } pub(crate) fn remainder_amount(&self) -> Result<(u64, bool), Error> { @@ -125,7 +140,7 @@ impl InputSelection { return Ok((None, storage_deposit_returns)); } - let Some((remainder_address, chain)) = self.get_remainder_address() else { + let Some((remainder_address, chain)) = self.get_remainder_address()? else { return Err(Error::MissingInputWithEd25519Address); }; diff --git a/sdk/src/client/node_api/participation.rs b/sdk/src/client/node_api/participation.rs index 928a63a56c..2985c10c7a 100644 --- a/sdk/src/client/node_api/participation.rs +++ b/sdk/src/client/node_api/participation.rs @@ -3,7 +3,7 @@ //! IOTA node public participation routes. //! -//! +//! use crate::{ client::{ClientInner, Result}, @@ -49,7 +49,9 @@ impl ClientInner { self.get_request( &route, - milestone_index.map(|index| index.to_string()).as_deref(), + milestone_index + .map(|index| format!("milestoneIndex={index}")) + .as_deref(), false, false, ) diff --git a/sdk/src/client/secret/ledger_nano.rs b/sdk/src/client/secret/ledger_nano.rs index 6baa8a4a1d..27d4797f17 100644 --- a/sdk/src/client/secret/ledger_nano.rs +++ b/sdk/src/client/secret/ledger_nano.rs @@ -295,17 +295,21 @@ impl SecretManage for LedgerSecretManager { .map_err(Error::from)?; } else { // figure out the remainder address and bip32 index (if there is one) + #[allow(clippy::option_if_let_else)] let (remainder_address, remainder_bip32): (Option<&Address>, LedgerBIP32Index) = match &prepared_transaction.remainder { Some(a) => { - let chain = a.chain.ok_or(Error::MissingBip32Chain)?; - ( - Some(&a.address), - LedgerBIP32Index { - bip32_change: chain.change.harden().into(), - bip32_index: chain.address_index.harden().into(), - }, - ) + if let Some(chain) = a.chain { + ( + Some(&a.address), + LedgerBIP32Index { + bip32_change: chain.change.harden().into(), + bip32_index: chain.address_index.harden().into(), + }, + ) + } else { + (None, LedgerBIP32Index::default()) + } } None => (None, LedgerBIP32Index::default()), };