Skip to content

Commit

Permalink
Merge branch '2.0' into timelock-expiration
Browse files Browse the repository at this point in the history
  • Loading branch information
thibault-martinez authored Nov 14, 2023
2 parents 6662446 + 6b22788 commit 2342073
Show file tree
Hide file tree
Showing 199 changed files with 6,314 additions and 5,516 deletions.
90 changes: 90 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
resolver = "2"
members = [
"bindings/core",
# TODO: issue #1424
#"bindings/nodejs",
"bindings/nodejs",
# TODO: issue #1423
#"bindings/python",
# TODO: issue #1425
Expand Down
33 changes: 25 additions & 8 deletions bindings/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ use fern_logger::{logger_init, LoggerConfig, LoggerOutputConfigBuilder};
pub use iota_sdk;
use iota_sdk::{
client::secret::{SecretManager, SecretManagerDto},
types::block::address::Bech32Address,
utils::serde::bip44::option_bip44,
wallet::{ClientOptions, Wallet},
};
use serde::Deserialize;
Expand All @@ -42,21 +44,24 @@ pub fn init_logger(config: String) -> std::result::Result<(), fern_logger::Error
#[derivative(Debug)]
#[serde(rename_all = "camelCase")]
pub struct WalletOptions {
pub storage_path: Option<String>,
pub client_options: Option<ClientOptions>,
pub address: Option<Bech32Address>,
pub alias: Option<String>,
#[serde(with = "option_bip44", default)]
pub bip_path: Option<Bip44>,
pub client_options: Option<ClientOptions>,
#[derivative(Debug(format_with = "OmittedDebug::omitted_fmt"))]
pub secret_manager: Option<SecretManagerDto>,
pub storage_path: Option<String>,
}

impl WalletOptions {
pub fn with_storage_path(mut self, storage_path: impl Into<Option<String>>) -> Self {
self.storage_path = storage_path.into();
pub fn with_address(mut self, address: impl Into<Option<Bech32Address>>) -> Self {
self.address = address.into();
self
}

pub fn with_client_options(mut self, client_options: impl Into<Option<ClientOptions>>) -> Self {
self.client_options = client_options.into();
pub fn with_alias(mut self, alias: impl Into<Option<String>>) -> Self {
self.alias = alias.into();
self
}

Expand All @@ -65,16 +70,28 @@ impl WalletOptions {
self
}

pub fn with_client_options(mut self, client_options: impl Into<Option<ClientOptions>>) -> Self {
self.client_options = client_options.into();
self
}

pub fn with_secret_manager(mut self, secret_manager: impl Into<Option<SecretManagerDto>>) -> Self {
self.secret_manager = secret_manager.into();
self
}

pub fn with_storage_path(mut self, storage_path: impl Into<Option<String>>) -> Self {
self.storage_path = storage_path.into();
self
}

pub async fn build(self) -> iota_sdk::wallet::Result<Wallet> {
log::debug!("wallet options: {self:?}");
let mut builder = Wallet::builder()
.with_client_options(self.client_options)
.with_bip_path(self.bip_path);
.with_address(self.address)
.with_alias(self.alias)
.with_bip_path(self.bip_path)
.with_client_options(self.client_options);

#[cfg(feature = "storage")]
if let Some(storage_path) = &self.storage_path {
Expand Down
6 changes: 6 additions & 0 deletions bindings/core/src/method/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ use crate::OmittedDebug;
#[serde(tag = "name", content = "data", rename_all = "camelCase")]
#[non_exhaustive]
pub enum WalletMethod {
/// Returns the accounts of the wallet.
/// Expected response: [`OutputsData`](crate::Response::OutputsData)
Accounts,
/// Backup storage. Password must be the current one, when Stronghold is used as SecretManager.
/// Expected response: [`Ok`](crate::Response::Ok)
#[cfg(feature = "stronghold")]
Expand Down Expand Up @@ -188,6 +191,9 @@ pub enum WalletMethod {
/// Returns the implicit account creation address of the wallet if it is Ed25519 based.
/// Expected response: [`Bech32Address`](crate::Response::Bech32Address)
ImplicitAccountCreationAddress,
/// Returns the implicit accounts of the wallet.
/// Expected response: [`OutputsData`](crate::Response::OutputsData)
ImplicitAccounts,
/// Returns all incoming transactions of the wallet
/// Expected response:
/// [`Transactions`](crate::Response::Transactions)
Expand Down
9 changes: 8 additions & 1 deletion bindings/core/src/method_handler/secret_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use iota_sdk::client::secret::stronghold::StrongholdSecretManager;
use iota_sdk::{
client::{
api::{GetAddressesOptions, PreparedTransactionData},
secret::{DowncastSecretManager, SecretManage, SignBlock},
secret::{DowncastSecretManager, SecretManage, SecretManager, SignBlock},
},
types::{
block::{address::ToBech32Ext, core::UnsignedBlock, unlock::Unlock, SignedBlockDto},
Expand Down Expand Up @@ -128,6 +128,13 @@ where
if let Some(secret_manager) = secret_manager.downcast::<StrongholdSecretManager>() {
secret_manager.store_mnemonic(mnemonic).await?;
Response::Ok
} else if let Some(secret_manager) = secret_manager.downcast::<SecretManager>() {
if let SecretManager::Stronghold(secret_manager) = secret_manager {
secret_manager.store_mnemonic(mnemonic).await?;
Response::Ok
} else {
return Err(iota_sdk::client::Error::SecretManagerMismatch.into());
}
} else {
return Err(iota_sdk::client::Error::SecretManagerMismatch.into());
}
Expand Down
12 changes: 10 additions & 2 deletions bindings/core/src/method_handler/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ use crate::{method::WalletMethod, response::Response, Result};
/// Call a wallet method.
pub(crate) async fn call_wallet_method_internal(wallet: &Wallet, method: WalletMethod) -> Result<Response> {
let response = match method {
WalletMethod::Accounts => {
let accounts = wallet.accounts().await;
Response::OutputsData(accounts.iter().map(OutputDataDto::from).collect())
}
#[cfg(feature = "stronghold")]
WalletMethod::Backup { destination, password } => {
wallet.backup(destination, password).await?;
Expand Down Expand Up @@ -206,12 +210,16 @@ 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::ImplicitAccounts => {
let implicit_accounts = wallet.implicit_accounts().await;
Response::OutputsData(implicit_accounts.iter().map(OutputDataDto::from).collect())
}
WalletMethod::IncomingTransactions => {
let transactions = wallet.incoming_transactions().await;
Response::Transactions(transactions.iter().map(TransactionWithMetadataDto::from).collect())
}
WalletMethod::Outputs { filter_options } => {
let outputs = wallet.outputs(filter_options).await?;
let outputs = wallet.outputs(filter_options).await;
Response::OutputsData(outputs.iter().map(OutputDataDto::from).collect())
}
WalletMethod::PendingTransactions => {
Expand Down Expand Up @@ -394,7 +402,7 @@ pub(crate) async fn call_wallet_method_internal(wallet: &Wallet, method: WalletM
Response::Transactions(transactions.iter().map(TransactionWithMetadataDto::from).collect())
}
WalletMethod::UnspentOutputs { filter_options } => {
let outputs = wallet.unspent_outputs(filter_options).await?;
let outputs = wallet.unspent_outputs(filter_options).await;
Response::OutputsData(outputs.iter().map(OutputDataDto::from).collect())
}
};
Expand Down
2 changes: 1 addition & 1 deletion bindings/core/tests/secrets_debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ fn method_interface_secrets_debug() {
let wallet_options = WalletOptions::default().with_secret_manager(SecretManagerDto::Placeholder);
assert_eq!(
format!("{:?}", wallet_options),
"WalletOptions { storage_path: None, client_options: None, bip_path: None, secret_manager: Some(<omitted>) }"
"WalletOptions { address: None, alias: None, bip_path: None, client_options: None, secret_manager: Some(<omitted>), storage_path: None }"
);
}
13 changes: 7 additions & 6 deletions bindings/nodejs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ crate-type = ["cdylib"]
doc = false

[dependencies]
async-trait = { version = "0.1.73", default-features = false }
iota-sdk-bindings-core = { path = "../core", default-features = false, features = [
"events",
"ledger_nano",
Expand All @@ -28,17 +29,17 @@ iota-sdk-bindings-core = { path = "../core", default-features = false, features
"mqtt",
"private_key_secret_manager",
] }

log = { version = "0.4.20", default-features = false }
neon = { version = "0.10.1", default-features = false, features = [
"napi-6",
"event-queue-api",
"promise-api",
] }
napi = { version = "2.13.3", default-features = false, features = ["async"] }
napi-derive = { version = "2.13.0", default-features = false }
once_cell = { version = "1.18.0", default-features = false }
serde_json = { version = "1.0.107", default-features = false }
thiserror = { version = "1.0.49", default-features = false }
tokio = { version = "1.33.0", default-features = false }

[build-dependencies]
napi-build = { version = "2.0.1", default-features = false }

[profile.production]
codegen-units = 1
inherits = "release"
Expand Down
9 changes: 4 additions & 5 deletions bindings/nodejs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,7 @@ If you have already installed the project and only want to run the build, run th
npm run build
```

This command uses the [cargo-cp-artifact](https://github.com/neon-bindings/cargo-cp-artifact) utility to run the Rust
build and copy the built library into `./build/Release/index.node`.
This command uses the napi build utility to run the Rust build and copy the built library into `./build/Release/index.node`.
Prebuild requires that the binary is in `build/Release` as though it was built with node-gyp.

## Client Usage
Expand Down Expand Up @@ -109,23 +108,23 @@ run().then(() => process.exit());
## Wallet Usage

The following example will create a
new [`Wallet`](https://wiki.iota.org/shimmer/iota-sdk/references/nodejs/classes/Wallet/) [`Account`](https://wiki.iota.org/shimmer/iota-sdk/references/nodejs/classes/Account/)
new [`Wallet`](https://wiki.iota.org/shimmer/iota-sdk/references/nodejs/classes/Wallet/)
that connects to the [Shimmer Testnet](https://api.testnet.shimmer.network) using the
[`StrongholdSecretManager`](https://wiki.iota.org/shimmer/iota-sdk/references/python/iota_sdk/secret_manager/#strongholdsecretmanager-objects).

```javascript
import { Wallet, CoinType, WalletOptions } from '@iota/sdk';

const walletOptions: WalletOptions = {
storagePath: `Alice`, // A name to associate with the created account.
storagePath: `Alice`, // A name to associate with the created wallet.
clientOptions: {
nodes: ['https://api.testnet.shimmer.network'], // The node to connect to.
},
coinType: CoinType.Shimmer,
secretManager: {
// Setup Stronghold secret manager
stronghold: {
snapshotPath: 'vault.stronghold', // The path to store the account snapshot.
snapshotPath: 'vault.stronghold', // The path to store the wallet snapshot.
password: 'a-secure-password', // A password to encrypt the stored data. WARNING: Never hardcode passwords in production code.
},
},
Expand Down
8 changes: 8 additions & 0 deletions bindings/nodejs/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright 2023 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

extern crate napi_build;

fn main() {
napi_build::setup();
}
Loading

0 comments on commit 2342073

Please sign in to comment.