Skip to content

Commit

Permalink
Merge branch '2.0' into set-issuer-id
Browse files Browse the repository at this point in the history
  • Loading branch information
thibault-martinez committed Dec 4, 2023
2 parents 68e89a6 + abdd2b5 commit 708edc7
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 26 deletions.
9 changes: 8 additions & 1 deletion bindings/core/src/method/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#[cfg(feature = "stronghold")]
use std::path::PathBuf;

use crypto::{keys::bip44::Bip44, signatures::ed25519::PublicKey};
use derivative::Derivative;
#[cfg(feature = "events")]
use iota_sdk::wallet::events::types::{WalletEvent, WalletEventType};
Expand Down Expand Up @@ -194,7 +195,13 @@ pub enum WalletMethod {
/// Prepares to transition an implicit account to an account.
/// Expected response: [`PreparedTransaction`](crate::Response::PreparedTransaction)
#[serde(rename_all = "camelCase")]
PrepareImplicitAccountTransition { output_id: OutputId },
PrepareImplicitAccountTransition {
output_id: OutputId,
#[serde(default)]
public_key: Option<String>,
#[serde(default)]
bip_path: Option<Bip44>,
},
/// Returns the implicit accounts of the wallet.
/// Expected response: [`OutputsData`](crate::Response::OutputsData)
ImplicitAccounts,
Expand Down
21 changes: 17 additions & 4 deletions bindings/core/src/method_handler/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

use std::time::Duration;

use crypto::signatures::ed25519::PublicKey;
use iota_sdk::{
client::api::{
PreparedTransactionData, PreparedTransactionDataDto, SignedTransactionData, SignedTransactionDataDto,
Expand Down Expand Up @@ -204,13 +205,25 @@ pub(crate) async fn call_wallet_method_internal(wallet: &Wallet, method: WalletM
let implicit_account_creation_address = wallet.implicit_account_creation_address().await?;
Response::Bech32Address(implicit_account_creation_address)
}
WalletMethod::PrepareImplicitAccountTransition {
output_id,
public_key,
bip_path,
} => {
let data = if let Some(public_key_str) = public_key {
let public_key = PublicKey::try_from_bytes(prefix_hex::decode(public_key_str)?)
.map_err(iota_sdk::wallet::Error::from)?;
wallet
.prepare_implicit_account_transition(&output_id, Some(public_key))
.await?
} else {
wallet.prepare_implicit_account_transition(&output_id, bip_path).await?
};
Response::PreparedTransaction(PreparedTransactionDataDto::from(&data))
}
WalletMethod::ImplicitAccounts => {
Response::OutputsData(wallet.data().await.implicit_accounts().cloned().collect())
}
WalletMethod::PrepareImplicitAccountTransition { output_id } => {
let data = wallet.prepare_implicit_account_transition(&output_id).await?;
Response::PreparedTransaction(PreparedTransactionDataDto::from(&data))
}
WalletMethod::IncomingTransactions => Response::Transactions(
wallet
.data()
Expand Down
20 changes: 16 additions & 4 deletions cli/src/wallet_cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use clap::{CommandFactory, Parser, Subcommand};
use colored::Colorize;
use iota_sdk::{
client::request_funds_from_faucet,
crypto::signatures::ed25519::PublicKey,
types::{
api::plugins::participation::types::ParticipationEventId,
block::{
Expand Down Expand Up @@ -123,6 +124,7 @@ pub enum WalletCommand {
ImplicitAccountTransition {
/// Identifier of the implicit account output.
output_id: OutputId,
public_key: Option<String>,
},
/// Lists the implicit accounts of the wallet.
ImplicitAccounts,
Expand Down Expand Up @@ -583,8 +585,18 @@ pub async fn implicit_account_creation_address_command(wallet: &Wallet) -> Resul
}

// `implicit-account-transition` command
pub async fn implicit_account_transition_command(wallet: &Wallet, output_id: OutputId) -> Result<(), Error> {
let transaction = wallet.implicit_account_transition(&output_id).await?;
pub async fn implicit_account_transition_command(
wallet: &Wallet,
output_id: OutputId,
public_key: Option<String>,
) -> Result<(), Error> {
let public_key = public_key
.map(|s| {
PublicKey::try_from_bytes(prefix_hex::decode(s).map_err(|e| Error::Miscellaneous(e.to_string()))?)
.map_err(|e| Error::Miscellaneous(e.to_string()))
})
.transpose()?;
let transaction = wallet.implicit_account_transition(&output_id, public_key).await?;

println_log_info!(
"Implicit account transition transaction sent:\n{:?}\n{:?}",
Expand Down Expand Up @@ -1128,8 +1140,8 @@ pub async fn prompt_internal(
WalletCommand::ImplicitAccountCreationAddress => {
implicit_account_creation_address_command(wallet).await
}
WalletCommand::ImplicitAccountTransition { output_id } => {
implicit_account_transition_command(wallet, output_id).await
WalletCommand::ImplicitAccountTransition { output_id, public_key } => {
implicit_account_transition_command(wallet, output_id, public_key).await
}
WalletCommand::ImplicitAccounts => implicit_accounts_command(wallet).await,
WalletCommand::MeltNativeToken { token_id, amount } => {
Expand Down
6 changes: 6 additions & 0 deletions sdk/src/wallet/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@ pub enum Error {
ImplicitAccountNotFound,
}

impl Error {
pub fn other<E: 'static + std::error::Error + Send + Sync>(err: E) -> Self {
Self::Other(Box::new(err) as _)
}
}

// Serialize type with Display error
impl Serialize for Error {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
Expand Down
59 changes: 42 additions & 17 deletions sdk/src/wallet/operations/transaction/account.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// Copyright 2023 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

use crypto::{keys::bip44::Bip44, signatures::ed25519::PublicKey};
use derive_more::From;

use crate::{
client::{api::PreparedTransactionData, secret::SecretManage},
types::block::{
Expand All @@ -23,19 +26,30 @@ where
crate::client::Error: From<S::Error>,
{
/// Transitions an implicit account to an account.
pub async fn implicit_account_transition(&self, output_id: &OutputId) -> Result<TransactionWithMetadata> {
pub async fn implicit_account_transition(
&self,
output_id: &OutputId,
key_source: Option<impl Into<BlockIssuerKeySource>>,
) -> Result<TransactionWithMetadata> {
let issuer_id = AccountId::from(output_id);

self.sign_and_submit_transaction(
self.prepare_implicit_account_transition(output_id).await?,
self.prepare_implicit_account_transition(output_id, key_source).await?,
issuer_id,
None,
)
.await
}

/// Prepares to transition an implicit account to an account.
pub async fn prepare_implicit_account_transition(&self, output_id: &OutputId) -> Result<PreparedTransactionData> {
pub async fn prepare_implicit_account_transition(
&self,
output_id: &OutputId,
key_source: Option<impl Into<BlockIssuerKeySource>>,
) -> Result<PreparedTransactionData>
where
crate::wallet::Error: From<S::Error>,
{
let implicit_account_data = self.data().await.unspent_outputs.get(output_id).cloned();

let implicit_account = if let Some(implicit_account_data) = &implicit_account_data {
Expand All @@ -48,20 +62,25 @@ where
return Err(Error::ImplicitAccountNotFound);
};

let public_key = if let Some(bip_path) = self.bip_path().await {
self.secret_manager
.read()
.await
.generate_ed25519_public_keys(
bip_path.coin_type,
bip_path.account,
bip_path.address_index..bip_path.address_index + 1,
None,
)
.await?[0]
} else {
// TODO https://github.com/iotaledger/iota-sdk/issues/1666
todo!()
let key_source = match key_source.map(Into::into) {
Some(key_source) => key_source,
None => self.bip_path().await.ok_or(Error::MissingBipPath)?.into(),
};

let public_key = match key_source {
BlockIssuerKeySource::Key(public_key) => public_key,
BlockIssuerKeySource::Bip44Path(bip_path) => {
self.secret_manager
.read()
.await
.generate_ed25519_public_keys(
bip_path.coin_type,
bip_path.account,
bip_path.address_index..bip_path.address_index + 1,
None,
)
.await?[0]
}
};

let account = AccountOutput::build_with_amount(implicit_account.amount(), AccountId::from(output_id))
Expand All @@ -87,3 +106,9 @@ where
.await
}
}

#[derive(From)]
pub enum BlockIssuerKeySource {
Key(PublicKey),
Bip44Path(Bip44),
}

0 comments on commit 708edc7

Please sign in to comment.