From baa5e46d7d514f692056fac91a1e362fc7ac46e3 Mon Sep 17 00:00:00 2001 From: Yeastplume Date: Thu, 14 Mar 2019 12:06:03 +0000 Subject: [PATCH] Refactor crate names, API Crate refactor (#20) * refactor/rename api crate contents, make crate naming consistent (all starting with grin_wallet) * refactor/rename api crate contents, make crate naming consistent (all starting with grin_wallet) * fix rpc api tests * rustfmt * done refactor * rustfmt * travis CI fixes --- .travis.yml | 2 +- Cargo.lock | 160 ++-- Cargo.toml | 8 +- {apiwallet => api}/Cargo.toml | 6 +- api/src/foreign.rs | 129 +++ api/src/foreign_rpc.rs | 251 ++++++ {apiwallet => api}/src/lib.rs | 13 +- apiwallet/src/api.rs => api/src/owner.rs | 1035 +--------------------- api/src/owner_rpc.rs | 667 ++++++++++++++ libwallet/Cargo.toml | 2 +- libwallet/tests/libwallet.rs | 2 +- libwallet/tests/slate_versioning.rs | 3 +- refwallet/Cargo.toml | 6 +- refwallet/src/adapters/keybase.rs | 9 +- refwallet/src/controller.rs | 44 +- refwallet/src/lib.rs | 4 +- refwallet/src/test_framework/mod.rs | 9 +- refwallet/tests/accounts.rs | 10 +- refwallet/tests/check.rs | 8 +- refwallet/tests/encryption.rs | 2 +- refwallet/tests/file.rs | 4 +- refwallet/tests/repost.rs | 4 +- refwallet/tests/restore.rs | 7 +- refwallet/tests/self_send.rs | 4 +- refwallet/tests/transaction.rs | 12 +- src/bin/cmd/wallet.rs | 4 +- src/bin/cmd/wallet_args.rs | 6 +- src/bin/cmd/wallet_tests.rs | 62 +- 28 files changed, 1281 insertions(+), 1192 deletions(-) rename {apiwallet => api}/Cargo.toml (87%) create mode 100644 api/src/foreign.rs create mode 100644 api/src/foreign_rpc.rs rename {apiwallet => api}/src/lib.rs (81%) rename apiwallet/src/api.rs => api/src/owner.rs (56%) create mode 100644 api/src/owner_rpc.rs diff --git a/.travis.yml b/.travis.yml index 1c944c6e..4e8d8fab 100644 --- a/.travis.yml +++ b/.travis.yml @@ -52,7 +52,7 @@ env: matrix: include: - os: linux - env: CI_JOB="test" CI_JOB_ARGS="config libwallet apiwallet" + env: CI_JOB="test" CI_JOB_ARGS="config libwallet api" - os: linux env: CI_JOB="test" CI_JOB_ARGS="refwallet ." - os: linux diff --git a/Cargo.lock b/Cargo.lock index 9d82b600..deba408a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -582,28 +582,6 @@ dependencies = [ "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "grin_apiwallet" -version = "1.1.0" -dependencies = [ - "easy-jsonrpc 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "grin_api 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", - "grin_chain 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", - "grin_core 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", - "grin_keychain 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", - "grin_libwallet 1.1.0", - "grin_refwallet 1.1.0", - "grin_store 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", - "grin_util 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", - "grin_wallet_config 1.1.0", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 3.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "grin_chain" version = "1.1.0" @@ -675,27 +653,6 @@ dependencies = [ "uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "grin_libwallet" -version = "1.1.0" -dependencies = [ - "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "grin_core 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", - "grin_keychain 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", - "grin_store 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", - "grin_util 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", - "grin_wallet_config 1.1.0", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", - "uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "grin_p2p" version = "1.1.0" @@ -735,40 +692,6 @@ dependencies = [ "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "grin_refwallet" -version = "1.1.0" -dependencies = [ - "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "grin_api 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", - "grin_apiwallet 1.1.0", - "grin_chain 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", - "grin_core 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", - "grin_keychain 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", - "grin_libwallet 1.1.0", - "grin_store 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", - "grin_util 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", - "grin_wallet_config 1.1.0", - "hyper 0.12.19 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "prettytable-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", - "term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-retry 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "grin_secp256k1zkp" version = "0.7.5" @@ -834,21 +757,43 @@ dependencies = [ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "grin_api 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", - "grin_apiwallet 1.1.0", "grin_chain 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", "grin_core 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", "grin_keychain 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", - "grin_libwallet 1.1.0", - "grin_refwallet 1.1.0", "grin_store 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", "grin_util 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", + "grin_wallet_api 1.1.0", "grin_wallet_config 1.1.0", + "grin_wallet_libwallet 1.1.0", + "grin_wallet_refwallet 1.1.0", "linefeed 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "prettytable-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "rpassword 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "grin_wallet_api" +version = "1.1.0" +dependencies = [ + "easy-jsonrpc 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "grin_api 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", + "grin_chain 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", + "grin_core 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", + "grin_keychain 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", + "grin_store 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", + "grin_util 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", + "grin_wallet_config 1.1.0", + "grin_wallet_libwallet 1.1.0", + "grin_wallet_refwallet 1.1.0", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", + "tempfile 3.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "grin_wallet_config" version = "1.1.0" @@ -863,6 +808,61 @@ dependencies = [ "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "grin_wallet_libwallet" +version = "1.1.0" +dependencies = [ + "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "grin_core 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", + "grin_keychain 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", + "grin_store 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", + "grin_util 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", + "grin_wallet_config 1.1.0", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", + "uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "grin_wallet_refwallet" +version = "1.1.0" +dependencies = [ + "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "grin_api 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", + "grin_chain 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", + "grin_core 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", + "grin_keychain 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", + "grin_store 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", + "grin_util 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", + "grin_wallet_api 1.1.0", + "grin_wallet_config 1.1.0", + "grin_wallet_libwallet 1.1.0", + "hyper 0.12.19 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "prettytable-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", + "term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-retry 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "h2" version = "0.1.16" diff --git a/Cargo.toml b/Cargo.toml index 08eb0f10..faf3d1d9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ name = "grin-wallet" path = "src/bin/grin-wallet.rs" [workspace] -members = ["apiwallet", "config", "libwallet", "refwallet"] +members = ["api", "config", "libwallet", "refwallet"] exclude = ["integration"] [dependencies] @@ -29,9 +29,9 @@ prettytable-rs = "0.7" log = "0.4" linefeed = "0.5" -grin_apiwallet = { path = "./apiwallet", version = "1.1.0" } -grin_libwallet = { path = "./libwallet", version = "1.1.0" } -grin_refwallet = { path = "./refwallet", version = "1.1.0" } +grin_wallet_api = { path = "./api", version = "1.1.0" } +grin_wallet_libwallet = { path = "./libwallet", version = "1.1.0" } +grin_wallet_refwallet = { path = "./refwallet", version = "1.1.0" } grin_wallet_config = { path = "./config", version = "1.1.0" } grin_core = { git = "https://github.com/mimblewimble/grin", branch = "milestone/1.1.0" } diff --git a/apiwallet/Cargo.toml b/api/Cargo.toml similarity index 87% rename from apiwallet/Cargo.toml rename to api/Cargo.toml index a9a33833..1af7b85b 100644 --- a/apiwallet/Cargo.toml +++ b/api/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "grin_apiwallet" +name = "grin_wallet_api" version = "1.1.0" authors = ["Grin Developers "] description = "Grin Wallet API" @@ -17,7 +17,7 @@ log = "0.4" uuid = { version = "0.6", features = ["serde", "v4"] } easy-jsonrpc = "0.4.1" -grin_libwallet = { path = "../libwallet", version = "1.1.0" } +grin_wallet_libwallet = { path = "../libwallet", version = "1.1.0" } grin_wallet_config = { path = "../config", version = "1.1.0" } grin_core = { git = "https://github.com/mimblewimble/grin", branch = "milestone/1.1.0" } @@ -28,6 +28,6 @@ grin_api = { git = "https://github.com/mimblewimble/grin", branch = "milestone/1 grin_store = { git = "https://github.com/mimblewimble/grin", branch = "milestone/1.1.0" } [dev-dependencies] -grin_refwallet = { path = "../refwallet", version = "1.1.0" } +grin_wallet_refwallet = { path = "../refwallet", version = "1.1.0" } serde_json = "1" tempfile = "3.0.7" diff --git a/api/src/foreign.rs b/api/src/foreign.rs new file mode 100644 index 00000000..bb36f171 --- /dev/null +++ b/api/src/foreign.rs @@ -0,0 +1,129 @@ +// Copyright 2018 The Grin Developers +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Main interface into all wallet API functions. +//! Wallet APIs are split into two seperate blocks of functionality +//! called the 'Owner' and 'Foreign' APIs: +//! +//! * The 'Foreign' API contains methods that other wallets will +//! use to interact with the owner's wallet. This API can be exposed +//! to the outside world, with the consideration as to how that can +//! be done securely up to the implementor. +//! +//! Methods in both APIs are intended to be 'single use', that is to say each +//! method will 'open' the wallet (load the keychain with its master seed), perform +//! its operation, then 'close' the wallet (unloading references to the keychain and master +//! seed). + +use crate::keychain::Keychain; +use crate::libwallet::internal::{tx, updater}; +use crate::libwallet::slate::Slate; +use crate::libwallet::types::{BlockFees, CbData, NodeClient, TxLogEntryType, WalletBackend}; +use crate::libwallet::{Error, ErrorKind}; +use crate::util::secp::{ContextFlag, Secp256k1}; +use crate::util::Mutex; +use std::marker::PhantomData; +use std::sync::Arc; + +const USER_MESSAGE_MAX_LEN: usize = 256; + +/// Wrapper around external API functions, intended to communicate +/// with other parties +pub struct Foreign +where + W: WalletBackend, + C: NodeClient, + K: Keychain, +{ + /// Wallet, contains its keychain (TODO: Split these up into 2 traits + /// perhaps) + pub wallet: Arc>, + phantom: PhantomData, + phantom_c: PhantomData, +} + +impl<'a, W: ?Sized, C, K> Foreign +where + W: WalletBackend, + C: NodeClient, + K: Keychain, +{ + /// Create new API instance + pub fn new(wallet_in: Arc>) -> Box { + Box::new(Foreign { + wallet: wallet_in, + phantom: PhantomData, + phantom_c: PhantomData, + }) + } + + /// Build a new (potential) coinbase transaction in the wallet + pub fn build_coinbase(&self, block_fees: &BlockFees) -> Result { + let mut w = self.wallet.lock(); + w.open_with_credentials()?; + let res = updater::build_coinbase(&mut *w, block_fees); + w.close()?; + res + } + + /// Verifies all messages in the slate match their public keys + pub fn verify_slate_messages(&self, slate: &Slate) -> Result<(), Error> { + let secp = Secp256k1::with_caps(ContextFlag::VerifyOnly); + slate.verify_messages(&secp)?; + Ok(()) + } + + /// Receive a transaction from a sender + pub fn receive_tx( + &self, + slate: &mut Slate, + dest_acct_name: Option<&str>, + message: Option, + ) -> Result<(), Error> { + let mut w = self.wallet.lock(); + w.open_with_credentials()?; + let parent_key_id = match dest_acct_name { + Some(d) => { + let pm = w.get_acct_path(d.to_owned())?; + match pm { + Some(p) => p.path, + None => w.parent_key_id(), + } + } + None => w.parent_key_id(), + }; + // Don't do this multiple times + let tx = updater::retrieve_txs(&mut *w, None, Some(slate.id), Some(&parent_key_id), false)?; + for t in &tx { + if t.tx_type == TxLogEntryType::TxReceived { + return Err(ErrorKind::TransactionAlreadyReceived(slate.id.to_string()).into()); + } + } + + let message = match message { + Some(mut m) => { + m.truncate(USER_MESSAGE_MAX_LEN); + Some(m) + } + None => None, + }; + + let (_, mut create_fn) = + tx::add_output_to_slate(&mut *w, slate, &parent_key_id, 1, message)?; + create_fn(&mut *w, &slate.tx, PhantomData, PhantomData)?; + tx::update_message(&mut *w, slate)?; + w.close()?; + Ok(()) + } +} diff --git a/api/src/foreign_rpc.rs b/api/src/foreign_rpc.rs new file mode 100644 index 00000000..3cf52300 --- /dev/null +++ b/api/src/foreign_rpc.rs @@ -0,0 +1,251 @@ +// Copyright 2019 The Grin Developers +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! JSON-RPC Stub generation for the Foreign API + +use crate::keychain::Keychain; +use crate::libwallet::slate::Slate; +use crate::libwallet::types::{BlockFees, CbData, NodeClient, WalletBackend}; +use crate::libwallet::ErrorKind; +use crate::Foreign; +use easy_jsonrpc; + +/// Public definition used to generate jsonrpc api for Foreign. +#[easy_jsonrpc::rpc] +pub trait ForeignRpc { + /** + Networked version of [Foreign::build_coinbase](struct.Foreign.html#method.build_coinbase). + + # Json rpc example + + ``` + # grin_wallet_api::doctest_helper_json_rpc_foreign_assert_response!( + { + "jsonrpc": "2.0", + "method": "build_coinbase", + "params": [ + { + "fees": 0, + "height": 0, + "key_id": null + } + ], + "id": 1 + }, + { + "jsonrpc": "2.0", + "result": { + "Err": { + "CallbackImpl": "Error opening wallet" + } + }, + "id": 1 + } + # ); + ``` + */ + fn build_coinbase(&self, block_fees: &BlockFees) -> Result; + + /** + Networked version of [Foreign::verify_slate_messages](struct.Foreign.html#method.verify_slate_messages). + + # Json rpc example + + ``` + # grin_wallet_api::doctest_helper_json_rpc_foreign_assert_response!( + { + "jsonrpc": "2.0", + "method": "verify_slate_messages", + "params": [ + { + "version_info": { + "version": 2, + "orig_version": 2, + "min_compat_version": 0 + }, + "amount": 0, + "fee": 0, + "height": 0, + "id": "414bad48-3386-4fa7-8483-72384c886ba3", + "lock_height": 0, + "num_participants": 2, + "participant_data": [], + "tx": { + "body": { + "inputs": [], + "kernels": [], + "outputs": [] + }, + "offset": "0000000000000000000000000000000000000000000000000000000000000000" + } + } + ], + "id": 1 + }, + { + "jsonrpc": "2.0", + "result": { + "Ok": null + }, + "id": 1 + } + # ); + ``` + */ + fn verify_slate_messages(&self, slate: &Slate) -> Result<(), ErrorKind>; + + /** + Networked version of [Foreign::receive_tx](struct.Foreign.html#method.receive_tx). + + # Json rpc example + + ```ignore //TODO: No idea why this isn't expanding properly, check as we adjust the API + # grin_wallet_api::doctest_helper_json_rpc_foreign_assert_response!( + { + "jsonrpc": "2.0", + "method": "receive_tx", + "params": [ + { + "version_info": { + "version": 2, + "orig_version": 2, + "min_compat_version": 0 + }, + "amount": 0, + "fee": 0, + "height": 0, + "id": "414bad48-3386-4fa7-8483-72384c886ba3", + "lock_height": 0, + "num_participants": 2, + "participant_data": [], + "tx": { + "body": { + "inputs": [], + "kernels": [], + "outputs": [] + }, + "offset": "0000000000000000000000000000000000000000000000000000000000000000" + } + }, + null, + null + ], + "id": 1 + }, + { + "jsonrpc": "2.0", + "result": { + "Err": { + "CallbackImpl": "Error opening wallet" + } + }, + "id": 1 + } + # ); + ``` + */ + fn receive_tx( + &self, + slate: Slate, + dest_acct_name: Option, + message: Option, + ) -> Result; +} + +impl ForeignRpc for Foreign +where + W: WalletBackend, + C: NodeClient, + K: Keychain, +{ + fn build_coinbase(&self, block_fees: &BlockFees) -> Result { + Foreign::build_coinbase(self, block_fees).map_err(|e| e.kind()) + } + + fn verify_slate_messages(&self, slate: &Slate) -> Result<(), ErrorKind> { + Foreign::verify_slate_messages(self, slate).map_err(|e| e.kind()) + } + + fn receive_tx( + &self, + mut slate: Slate, + dest_acct_name: Option, + message: Option, + ) -> Result { + Foreign::receive_tx( + self, + &mut slate, + dest_acct_name.as_ref().map(String::as_str), + message, + ) + .map_err(|e| e.kind())?; + Ok(slate) + } +} + +#[doc(hidden)] +#[macro_export] +macro_rules! doctest_helper_json_rpc_foreign_assert_response { + ($request:tt, $expected_response:tt) => { + // create temporary wallet, run jsonrpc request on api of wallet, delete wallet, return + // json response. + // In order to prevent leaking tempdirs, This function should not panic. + fn rpc_owner_result( + request: serde_json::Value, + ) -> Result, String> { + use easy_jsonrpc::Handler; + use grin_keychain::ExtKeychain; + use grin_util::Mutex; + use grin_wallet_api::{Foreign, ForeignRpc}; + use grin_wallet_config::WalletConfig; + use grin_wallet_refwallet::{HTTPNodeClient, LMDBBackend, WalletBackend}; + use serde_json; + use std::sync::Arc; + use tempfile::tempdir; + + let dir = tempdir().map_err(|e| format!("{:#?}", e))?; + { + let mut wallet_config = WalletConfig::default(); + wallet_config.data_file_dir = dir + .path() + .to_str() + .ok_or("Failed to convert tmpdir path to string.".to_owned())? + .to_owned(); + let node_client = + HTTPNodeClient::new(&wallet_config.check_node_api_http_addr, None); + let wallet: Arc>> = + Arc::new(Mutex::new( + LMDBBackend::new(wallet_config.clone(), "", node_client) + .map_err(|e| format!("{:#?}", e))?, + )); + let api_foreign = *Foreign::new(wallet); + let foreign_api = &api_foreign as &dyn ForeignRpc; + Ok(foreign_api.handle_request(request)) + } + } + + let response = rpc_owner_result(serde_json::json!($request)) + .unwrap() + .unwrap(); + let expected_response = serde_json::json!($expected_response); + + if response != expected_response { + panic!( + "(left != right) \nleft: {}\nright: {}", + serde_json::to_string_pretty(&response).unwrap(), + serde_json::to_string_pretty(&expected_response).unwrap() + ); + } + }; +} diff --git a/apiwallet/src/lib.rs b/api/src/lib.rs similarity index 81% rename from apiwallet/src/lib.rs rename to api/src/lib.rs index a8d24828..efb06fe6 100644 --- a/apiwallet/src/lib.rs +++ b/api/src/lib.rs @@ -26,13 +26,18 @@ extern crate grin_core as core; extern crate grin_keychain as keychain; extern crate grin_store as store; extern crate grin_util as util; -extern crate grin_libwallet as libwallet; +extern crate grin_wallet_libwallet as libwallet; extern crate failure_derive; #[macro_use] extern crate log; -pub mod api; -pub use crate::api::{APIForeign, APIOwner}; - +mod foreign; +mod foreign_rpc; +mod owner; +mod owner_rpc; +pub use crate::foreign::Foreign; +pub use crate::foreign_rpc::ForeignRpc; +pub use crate::owner::Owner; +pub use crate::owner_rpc::OwnerRpc; diff --git a/apiwallet/src/api.rs b/api/src/owner.rs similarity index 56% rename from apiwallet/src/api.rs rename to api/src/owner.rs index d75c42cd..9a1a0959 100644 --- a/apiwallet/src/api.rs +++ b/api/src/owner.rs @@ -15,14 +15,11 @@ //! Main interface into all wallet API functions. //! Wallet APIs are split into two seperate blocks of functionality //! called the 'Owner' and 'Foreign' APIs: +//! //! * The 'Owner' API is intended to expose methods that are to be //! used by the wallet owner only. It is vital that this API is not //! exposed to anyone other than the owner of the wallet (i.e. the //! person with access to the seed and password. -//! * The 'Foreign' API contains methods that other wallets will -//! use to interact with the owner's wallet. This API can be exposed -//! to the outside world, with the consideration as to how that can -//! be done securely up to the implementor. //! //! Methods in both APIs are intended to be 'single use', that is to say each //! method will 'open' the wallet (load the keychain with its master seed), perform @@ -41,501 +38,17 @@ use crate::keychain::{Identifier, Keychain}; use crate::libwallet::internal::{keys, tx, updater}; use crate::libwallet::slate::Slate; use crate::libwallet::types::{ - AcctPathMapping, BlockFees, CbData, NodeClient, OutputData, OutputLockFn, TxLogEntry, - TxLogEntryType, TxWrapper, WalletBackend, WalletInfo, + AcctPathMapping, NodeClient, OutputData, OutputLockFn, TxLogEntry, TxWrapper, WalletBackend, + WalletInfo, }; use crate::libwallet::{Error, ErrorKind}; use crate::util; use crate::util::secp::{pedersen, ContextFlag, Secp256k1}; -use easy_jsonrpc; const USER_MESSAGE_MAX_LEN: usize = 256; -/// Public definition used to generate jsonrpc api for APIOwner. -#[easy_jsonrpc::rpc] -pub trait OwnerApi { - /** - Networked version of [APIOwner::accounts](struct.APIOwner.html#method.accounts). - - # Json rpc example - - ``` - # grin_apiwallet::doctest_helper_json_rpc_owner_assert_response!( - { - "jsonrpc": "2.0", - "method": "accounts", - "params": [], - "id": 1 - }, - { - "jsonrpc": "2.0", - "result": { - "Ok": [ - { - "label": "default", - "path": "0200000000000000000000000000000000" - } - ] - }, - "id": 1 - } - # ); - ``` - */ - fn accounts(&self) -> Result, ErrorKind>; - - /** - Networked version of [APIOwner::create_account_path](struct.APIOwner.html#method.create_account_path). - - # Json rpc example - - ``` - # grin_apiwallet::doctest_helper_json_rpc_owner_assert_response!( - { - "jsonrpc": "2.0", - "method": "create_account_path", - "params": ["account1"], - "id": 1 - }, - { - "jsonrpc": "2.0", - "result": { - "Ok": "0200000001000000000000000000000000" - }, - "id": 1 - } - # ); - ``` - */ - fn create_account_path(&self, label: &String) -> Result; - - /** - Networked version of [APIOwner::set_active_account](struct.APIOwner.html#method.set_active_account). - - # Json rpc example - - ``` - # grin_apiwallet::doctest_helper_json_rpc_owner_assert_response!( - { - "jsonrpc": "2.0", - "method": "set_active_account", - "params": ["default"], - "id": 1 - }, - { - "jsonrpc": "2.0", - "result": { - "Ok": null - }, - "id": 1 - } - # ); - ``` - */ - fn set_active_account(&self, label: &String) -> Result<(), ErrorKind>; - - /** - Networked version of [APIOwner::retrieve_outputs](struct.APIOwner.html#method.retrieve_outputs). - - - ``` - # grin_apiwallet::doctest_helper_json_rpc_owner_assert_response!( - { - "jsonrpc": "2.0", - "method": "retrieve_outputs", - "params": [false, false, null], - "id": 1 - }, - { - "jsonrpc": "2.0", - "result": { - "Err": { - "CallbackImpl": "Error opening wallet" - } - }, - "id": 1 - } - # ); - ``` - */ - fn retrieve_outputs( - &self, - include_spent: bool, - refresh_from_node: bool, - tx_id: Option, - ) -> Result<(bool, Vec<(OutputData, pedersen::Commitment)>), ErrorKind>; - - /** - Networked version of [APIOwner::retrieve_txs](struct.APIOwner.html#method.retrieve_txs). - - - ``` - # grin_apiwallet::doctest_helper_json_rpc_owner_assert_response!( - { - "jsonrpc": "2.0", - "method": "retrieve_txs", - "params": [false, null, null], - "id": 1 - }, - { - "jsonrpc": "2.0", - "result": { - "Err": { - "CallbackImpl": "Error opening wallet" - } - }, - "id": 1 - } - # ); - ``` - */ - fn retrieve_txs( - &self, - refresh_from_node: bool, - tx_id: Option, - tx_slate_id: Option, - ) -> Result<(bool, Vec), ErrorKind>; - - /** - Networked version of [APIOwner::retrieve_summary_info](struct.APIOwner.html#method.retrieve_summary_info). - - - ``` - # grin_apiwallet::doctest_helper_json_rpc_owner_assert_response!( - { - "jsonrpc": "2.0", - "method": "retrieve_summary_info", - "params": [false, 1], - "id": 1 - }, - { - "jsonrpc": "2.0", - "result": { - "Err": { - "CallbackImpl": "Error opening wallet" - } - }, - "id": 1 - } - # ); - ``` - */ - fn retrieve_summary_info( - &self, - refresh_from_node: bool, - minimum_confirmations: u64, - ) -> Result<(bool, WalletInfo), ErrorKind>; - - /** - Networked version of [APIOwner::estimate_initiate_tx](struct.APIOwner.html#method.estimate_initiate_tx). - - - ``` - # grin_apiwallet::doctest_helper_json_rpc_owner_assert_response!( - { - "jsonrpc": "2.0", - "method": "estimate_initiate_tx", - "params": [null, 0, 0, 10, 0, false], - "id": 1 - }, - { - "jsonrpc": "2.0", - "result": { - "Err": { - "CallbackImpl": "Error opening wallet" - } - }, - "id": 1 - } - # ); - ``` - */ - fn estimate_initiate_tx( - &self, - src_acct_name: Option, - amount: u64, - minimum_confirmations: u64, - max_outputs: usize, - num_change_outputs: usize, - selection_strategy_is_use_all: bool, - ) -> Result<(/* total */ u64, /* fee */ u64), ErrorKind>; - - /** - Networked version of [APIOwner::finalize_tx](struct.APIOwner.html#method.finalize_tx). - - - ``` - # grin_apiwallet::doctest_helper_json_rpc_owner_assert_response!( - { - "jsonrpc": "2.0", - "method": "finalize_tx", - "params": [{ - "version_info": { - "version": 2, - "orig_version": 2, - "min_compat_version": 0 - }, - "amount": 0, - "fee": 0, - "height": 0, - "id": "414bad48-3386-4fa7-8483-72384c886ba3", - "lock_height": 0, - "num_participants": 2, - "participant_data": [], - "tx": { - "body": { - "inputs": [], - "kernels": [], - "outputs": [] - }, - "offset": "0000000000000000000000000000000000000000000000000000000000000000" - } - }], - "id": 1 - }, - { - "jsonrpc": "2.0", - "result": { - "Err": { - "CallbackImpl": "Error opening wallet" - } - }, - "id": 1 - } - # ); - ``` - */ - fn finalize_tx(&self, slate: Slate) -> Result; - - /** - Networked version of [APIOwner::cancel_tx](struct.APIOwner.html#method.cancel_tx). - - - ``` - # grin_apiwallet::doctest_helper_json_rpc_owner_assert_response!( - { - "jsonrpc": "2.0", - "method": "cancel_tx", - "params": [null, null], - "id": 1 - }, - { - "jsonrpc": "2.0", - "result": { - "Err": { - "CallbackImpl": "Error opening wallet" - } - }, - "id": 1 - } - # ); - ``` - */ - fn cancel_tx(&self, tx_id: Option, tx_slate_id: Option) -> Result<(), ErrorKind>; - - /** - Networked version of [APIOwner::get_stored_tx](struct.APIOwner.html#method.get_stored_tx). - - - ``` - # grin_apiwallet::doctest_helper_json_rpc_owner_assert_response!( - { - "jsonrpc": "2.0", - "method": "get_stored_tx", - "params": [ - { - "amount_credited": 0, - "amount_debited": 0, - "confirmation_ts": null, - "confirmed": false, - "creation_ts": "2019-03-05T20:49:59.444095Z", - "fee": null, - "id": 10, - "messages": null, - "num_inputs": 0, - "num_outputs": 0, - "parent_key_id": "0000000000000000000000000000000000", - "stored_tx": null, - "tx_slate_id": null, - "tx_type": "TxReceived" - } - ], - "id": 1 - }, - { - "jsonrpc": "2.0", - "result": { - "Ok": null - }, - "id": 1 - } - # ); - ``` - */ - fn get_stored_tx(&self, entry: &TxLogEntry) -> Result, ErrorKind>; - - /** - Networked version of [APIOwner::post_tx](struct.APIOwner.html#method.post_tx). - - ```no_run - # // This test currently fails on travis - # grin_apiwallet::doctest_helper_json_rpc_owner_assert_response!( - { - "jsonrpc": "2.0", - "method": "post_tx", - "params": [ - { - "body": { - "inputs": [], - "kernels": [], - "outputs": [] - }, - "offset": "0000000000000000000000000000000000000000000000000000000000000000" - }, - false - ], - "id": 1 - }, - { - "jsonrpc": "2.0", - "result": { - "Err": { - "ClientCallback": "Posting transaction to node: Request error: Cannot make request: an error occurred trying to connect: Connection refused (os error 61)" - } - }, - "id": 1 - } - # ); - ``` - */ - fn post_tx(&self, tx: &Transaction, fluff: bool) -> Result<(), ErrorKind>; - - /** - Networked version of [APIOwner::verify_slate_messages](struct.APIOwner.html#method.verify_slate_messages). - - - ``` - # grin_apiwallet::doctest_helper_json_rpc_owner_assert_response!( - { - "jsonrpc": "2.0", - "method": "verify_slate_messages", - "params": [{ - "version_info": { - "version": 2, - "orig_version": 2, - "min_compat_version": 0 - }, - "amount": 0, - "fee": 0, - "height": 0, - "id": "414bad48-3386-4fa7-8483-72384c886ba3", - "lock_height": 0, - "num_participants": 2, - "participant_data": [], - "tx": { - "body": { - "inputs": [], - "kernels": [], - "outputs": [] - }, - "offset": "0000000000000000000000000000000000000000000000000000000000000000" - } - }], - "id": 1 - }, - { - "jsonrpc": "2.0", - "result": { - "Ok": null - }, - "id": 1 - } - # ); - ``` - */ - fn verify_slate_messages(&self, slate: &Slate) -> Result<(), ErrorKind>; - - /** - Networked version of [APIOwner::restore](struct.APIOwner.html#method.restore). - - - ``` - # grin_apiwallet::doctest_helper_json_rpc_owner_assert_response!( - { - "jsonrpc": "2.0", - "method": "restore", - "params": [], - "id": 1 - }, - { - "jsonrpc": "2.0", - "result": { - "Err": { - "CallbackImpl": "Error opening wallet" - } - }, - "id": 1 - } - # ); - ``` - */ - fn restore(&self) -> Result<(), ErrorKind>; - - /** - Networked version of [APIOwner::check_repair](struct.APIOwner.html#method.check_repair). - - - ``` - # grin_apiwallet::doctest_helper_json_rpc_owner_assert_response!( - { - "jsonrpc": "2.0", - "method": "check_repair", - "params": [false], - "id": 1 - }, - { - "jsonrpc": "2.0", - "result": { - "Err": { - "CallbackImpl": "Error opening wallet" - } - }, - "id": 1 - } - # ); - ``` - */ - fn check_repair(&self, delete_unconfirmed: bool) -> Result<(), ErrorKind>; - - /** - Networked version of [APIOwner::node_height](struct.APIOwner.html#method.node_height). - - - ``` - # grin_apiwallet::doctest_helper_json_rpc_owner_assert_response!( - { - "jsonrpc": "2.0", - "method": "node_height", - "params": [], - "id": 1 - }, - { - "jsonrpc": "2.0", - "result": { - "Err": { - "CallbackImpl": "Error opening wallet" - } - }, - "id": 1 - } - # ); - ``` - */ - fn node_height(&self) -> Result<(u64, bool), ErrorKind>; -} - /// Functions intended for use by the owner (e.g. master seed holder) of the wallet. -pub struct APIOwner +pub struct Owner where W: WalletBackend, C: NodeClient, @@ -548,7 +61,7 @@ where phantom_c: PhantomData, } -impl APIOwner +impl Owner where W: WalletBackend, C: NodeClient, @@ -580,7 +93,7 @@ where /// use util::Mutex; /// /// use keychain::ExtKeychain; - /// use wallet::libwallet::api::APIOwner; + /// use wallet::libwallet::api::Owner; /// /// // These contain sample implementations of each part needed for a wallet /// use wallet::{LMDBBackend, HTTPNodeClient, WalletBackend}; @@ -598,13 +111,13 @@ where /// LMDBBackend::new(wallet_config.clone(), "", node_client).unwrap() /// )); /// - /// let api_owner = APIOwner::new(wallet.clone()); + /// let api_owner = Owner::new(wallet.clone()); /// // .. perform wallet operations /// /// ``` pub fn new(wallet_in: Arc>) -> Self { - APIOwner { + Owner { wallet: wallet_in, phantom: PhantomData, phantom_c: PhantomData, @@ -626,7 +139,7 @@ where /// * This method does not need to use the wallet seed or keychain. /// /// # Example - /// Set up as in [`new`](struct.APIOwner.html#method.new) method above. + /// Set up as in [`new`](struct.Owner.html#method.new) method above. /// ``` ignore /// # extern crate grin_wallet_config as config; /// # extern crate grin_refwallet as wallet; @@ -635,7 +148,7 @@ where /// # use std::sync::Arc; /// # use util::Mutex; /// # use keychain::ExtKeychain; - /// # use wallet::libwallet::api::APIOwner; + /// # use wallet::libwallet::api::Owner; /// # use wallet::{LMDBBackend, HTTPNodeClient, WalletBackend}; /// # use config::WalletConfig; /// # let mut wallet_config = WalletConfig::default(); @@ -646,7 +159,7 @@ where /// # LMDBBackend::new(wallet_config.clone(), "", node_client).unwrap() /// # )); /// - /// let api_owner = APIOwner::new(wallet.clone()); + /// let api_owner = Owner::new(wallet.clone()); /// /// let result = api_owner.accounts(); /// @@ -678,13 +191,13 @@ where /// so the first call will create an account at `m/1/0` and the second at /// `m/2/0` etc. . . /// * The account path is used throughout as the parent key for most key-derivation - /// operations. See [`set_active_account`](struct.APIOwner.html#method.set_active_account) for + /// operations. See [`set_active_account`](struct.Owner.html#method.set_active_account) for /// further details. /// /// * This function does not need to use the root wallet seed or keychain. /// /// # Example - /// Set up as in [`new`](struct.APIOwner.html#method.new) method above. + /// Set up as in [`new`](struct.Owner.html#method.new) method above. /// ``` ignore /// # extern crate grin_wallet as wallet; /// # extern crate grin_keychain as keychain; @@ -692,7 +205,7 @@ where /// # use std::sync::Arc; /// # use util::Mutex; /// # use keychain::ExtKeychain; - /// # use wallet::libwallet::api::APIOwner; + /// # use wallet::libwallet::api::Owner; /// # use wallet::{LMDBBackend, HTTPNodeClient, WalletBackend, WalletConfig}; /// # let mut wallet_config = WalletConfig::default(); /// # wallet_config.data_file_dir = "test_output/doc/wallet1".to_owned(); @@ -702,7 +215,7 @@ where /// # LMDBBackend::new(wallet_config.clone(), "", node_client).unwrap() /// # )); /// - /// let api_owner = APIOwner::new(wallet.clone()); + /// let api_owner = Owner::new(wallet.clone()); /// /// let result = api_owner.create_account_path("account1"); /// @@ -721,7 +234,7 @@ where /// /// # Arguments /// * `label` - The human readable label for the account. Accounts can be retrieved via - /// the [`account`](struct.APIOwner.html#method.accounts) method + /// the [`account`](struct.Owner.html#method.accounts) method /// /// # Returns /// * Result Containing: @@ -738,7 +251,7 @@ where /// * This function does not need to use the root wallet seed or keychain. /// /// # Example - /// Set up as in [`new`](struct.APIOwner.html#method.new) method above. + /// Set up as in [`new`](struct.Owner.html#method.new) method above. /// ``` ignore /// # extern crate grin_wallet as wallet; /// # extern crate grin_keychain as keychain; @@ -746,7 +259,7 @@ where /// # use std::sync::Arc; /// # use util::Mutex; /// # use keychain::ExtKeychain; - /// # use wallet::libwallet::api::APIOwner; + /// # use wallet::libwallet::api::Owner; /// # use wallet::{LMDBBackend, HTTPNodeClient, WalletBackend, WalletConfig}; /// # let mut wallet_config = WalletConfig::default(); /// # wallet_config.data_file_dir = "test_output/doc/wallet1".to_owned(); @@ -756,7 +269,7 @@ where /// # LMDBBackend::new(wallet_config.clone(), "", node_client).unwrap() /// # )); /// - /// let api_owner = APIOwner::new(wallet.clone()); + /// let api_owner = Owner::new(wallet.clone()); /// /// let result = api_owner.create_account_path("account1"); /// @@ -796,7 +309,7 @@ where /// and the Output commitment as identified in the chain's UTXO set /// /// # Example - /// Set up as in [`new`](struct.APIOwner.html#method.new) method above. + /// Set up as in [`new`](struct.Owner.html#method.new) method above. /// ``` ignore /// # extern crate grin_wallet as wallet; /// # extern crate grin_keychain as keychain; @@ -804,7 +317,7 @@ where /// # use std::sync::Arc; /// # use util::Mutex; /// # use keychain::ExtKeychain; - /// # use wallet::libwallet::api::APIOwner; + /// # use wallet::libwallet::api::Owner; /// # use wallet::{LMDBBackend, HTTPNodeClient, WalletBackend, WalletConfig}; /// # let mut wallet_config = WalletConfig::default(); /// # wallet_config.data_file_dir = "test_output/doc/wallet1".to_owned(); @@ -814,7 +327,7 @@ where /// # LMDBBackend::new(wallet_config.clone(), "", node_client).unwrap() /// # )); /// - /// let api_owner = APIOwner::new(wallet.clone()); + /// let api_owner = Owner::new(wallet.clone()); /// let show_spent = false; /// let update_from_node = true; /// let tx_id = None; @@ -873,7 +386,7 @@ where /// [TxLogEntries](../types/struct/TxLogEntry.html) /// /// # Example - /// Set up as in [`new`](struct.APIOwner.html#method.new) method above. + /// Set up as in [`new`](struct.Owner.html#method.new) method above. /// ``` ignore /// # extern crate grin_wallet as wallet; /// # extern crate grin_keychain as keychain; @@ -881,7 +394,7 @@ where /// # use std::sync::Arc; /// # use util::Mutex; /// # use keychain::ExtKeychain; - /// # use wallet::libwallet::api::APIOwner; + /// # use wallet::libwallet::api::Owner; /// # use wallet::{LMDBBackend, HTTPNodeClient, WalletBackend, WalletConfig}; /// # let mut wallet_config = WalletConfig::default(); /// # wallet_config.data_file_dir = "test_output/doc/wallet1".to_owned(); @@ -891,7 +404,7 @@ where /// # LMDBBackend::new(wallet_config.clone(), "", node_client).unwrap() /// # )); /// - /// let api_owner = APIOwner::new(wallet.clone()); + /// let api_owner = Owner::new(wallet.clone()); /// let update_from_node = true; /// let tx_id = None; /// let tx_slate_id = None; @@ -947,7 +460,7 @@ where /// * The second element contains the Summary [`WalletInfo`](../types/struct.WalletInfo.html) /// /// # Example - /// Set up as in [`new`](struct.APIOwner.html#method.new) method above. + /// Set up as in [`new`](struct.Owner.html#method.new) method above. /// ``` ignore /// # extern crate grin_wallet as wallet; /// # extern crate grin_keychain as keychain; @@ -955,7 +468,7 @@ where /// # use std::sync::Arc; /// # use util::Mutex; /// # use keychain::ExtKeychain; - /// # use wallet::libwallet::api::APIOwner; + /// # use wallet::libwallet::api::Owner; /// # use wallet::{LMDBBackend, HTTPNodeClient, WalletBackend, WalletConfig}; /// # let mut wallet_config = WalletConfig::default(); /// # wallet_config.data_file_dir = "test_output/doc/wallet1".to_owned(); @@ -965,7 +478,7 @@ where /// # LMDBBackend::new(wallet_config.clone(), "", node_client).unwrap() /// # )); /// - /// let mut api_owner = APIOwner::new(wallet.clone()); + /// let mut api_owner = Owner::new(wallet.clone()); /// let update_from_node = true; /// let minimum_confirmations=10; /// @@ -1009,7 +522,7 @@ where /// attempt to re-spend outputs that are already included in a transaction before the transaction /// is confirmed. This method also returns a function that will perform that locking, and it is /// up to the caller to decide the best time to call the lock function - /// (via the [`tx_lock_outputs`](struct.APIOwner.html#method.tx_lock_outputs) method). + /// (via the [`tx_lock_outputs`](struct.Owner.html#method.tx_lock_outputs) method). /// If the exchange method is intended to be synchronous (such as via a direct http call,) /// then the lock call can wait until the response is confirmed. If it is asynchronous, (such /// as via file transfer,) the lock call should happen immediately (before the file is sent @@ -1018,7 +531,7 @@ where /// # Arguments /// * `src_acct_name` - The human readable account name from which to draw outputs /// for the transaction, overriding whatever the active account is as set via the - /// [`set_active_account`](struct.APIOwner.html#method.set_active_account) method. + /// [`set_active_account`](struct.Owner.html#method.set_active_account) method. /// If None, the transaction will use the active account. /// * `amount` - The amount to send, in nanogrins. (`1 G = 1_000_000_000nG`) /// * `minimum_confirmations` - The minimum number of confirmations an output @@ -1051,7 +564,7 @@ where /// * A lock function, which should be called when the caller deems it appropriate to lock /// the transaction outputs (i.e. there is relative certaintly that the slate will be /// transmitted to the receiving party). Must be called before calling - /// [`finalize_tx`](struct.APIOwner.html#method.finalize_tx). + /// [`finalize_tx`](struct.Owner.html#method.finalize_tx). /// * or [`libwallet::Error`](../struct.Error.html) if an error is encountered. /// /// # Remarks @@ -1059,10 +572,10 @@ where /// * This method requires an active connection to a node, and will fail with error if a node /// cannot be contacted to refresh output statuses. /// * This method will store a partially completed transaction in the wallet's transaction log, - /// which will be updated on the corresponding call to [`finalize_tx`](struct.APIOwner.html#method.finalize_tx). + /// which will be updated on the corresponding call to [`finalize_tx`](struct.Owner.html#method.finalize_tx). /// /// # Example - /// Set up as in [new](struct.APIOwner.html#method.new) method above. + /// Set up as in [new](struct.Owner.html#method.new) method above. /// ``` ignore /// # extern crate grin_wallet as wallet; /// # extern crate grin_keychain as keychain; @@ -1070,7 +583,7 @@ where /// # use std::sync::Arc; /// # use util::Mutex; /// # use keychain::ExtKeychain; - /// # use wallet::libwallet::api::APIOwner; + /// # use wallet::libwallet::api::Owner; /// # use wallet::{LMDBBackend, HTTPNodeClient, WalletBackend, WalletConfig}; /// # let mut wallet_config = WalletConfig::default(); /// # wallet_config.data_file_dir = "test_output/doc/wallet1".to_owned(); @@ -1080,7 +593,7 @@ where /// # LMDBBackend::new(wallet_config.clone(), "", node_client).unwrap() /// # )); /// - /// let mut api_owner = APIOwner::new(wallet.clone()); + /// let mut api_owner = Owner::new(wallet.clone()); /// let amount = 2_000_000_000; /// /// // Attempt to create a transaction using the 'default' account @@ -1169,7 +682,7 @@ where /// # Arguments /// * `src_acct_name` - The human readable account name from which to draw outputs /// for the transaction, overriding whatever the active account is as set via the - /// [`set_active_account`](struct.APIOwner.html#method.set_active_account) method. + /// [`set_active_account`](struct.Owner.html#method.set_active_account) method. /// If None, the transaction will use the active account. /// * `amount` - The amount to send, in nanogrins. (`1 G = 1_000_000_000nG`) /// * `minimum_confirmations` - The minimum number of confirmations an output @@ -1365,479 +878,3 @@ where } } } - -impl OwnerApi for APIOwner -where - W: WalletBackend, - C: NodeClient, - K: Keychain, -{ - fn accounts(&self) -> Result, ErrorKind> { - APIOwner::accounts(self).map_err(|e| e.kind()) - } - - fn create_account_path(&self, label: &String) -> Result { - APIOwner::create_account_path(self, label).map_err(|e| e.kind()) - } - - fn set_active_account(&self, label: &String) -> Result<(), ErrorKind> { - APIOwner::set_active_account(self, label).map_err(|e| e.kind()) - } - - fn retrieve_outputs( - &self, - include_spent: bool, - refresh_from_node: bool, - tx_id: Option, - ) -> Result<(bool, Vec<(OutputData, pedersen::Commitment)>), ErrorKind> { - APIOwner::retrieve_outputs(self, include_spent, refresh_from_node, tx_id) - .map_err(|e| e.kind()) - } - - fn retrieve_txs( - &self, - refresh_from_node: bool, - tx_id: Option, - tx_slate_id: Option, - ) -> Result<(bool, Vec), ErrorKind> { - APIOwner::retrieve_txs(self, refresh_from_node, tx_id, tx_slate_id).map_err(|e| e.kind()) - } - - fn retrieve_summary_info( - &self, - refresh_from_node: bool, - minimum_confirmations: u64, - ) -> Result<(bool, WalletInfo), ErrorKind> { - APIOwner::retrieve_summary_info(self, refresh_from_node, minimum_confirmations) - .map_err(|e| e.kind()) - } - - fn estimate_initiate_tx( - &self, - src_acct_name: Option, - amount: u64, - minimum_confirmations: u64, - max_outputs: usize, - num_change_outputs: usize, - selection_strategy_is_use_all: bool, - ) -> Result<(/* total */ u64, /* fee */ u64), ErrorKind> { - APIOwner::estimate_initiate_tx( - self, - src_acct_name.as_ref().map(String::as_str), - amount, - minimum_confirmations, - max_outputs, - num_change_outputs, - selection_strategy_is_use_all, - ) - .map_err(|e| e.kind()) - } - - fn finalize_tx(&self, mut slate: Slate) -> Result { - APIOwner::finalize_tx(self, &mut slate).map_err(|e| e.kind())?; - Ok(slate) - } - - fn cancel_tx(&self, tx_id: Option, tx_slate_id: Option) -> Result<(), ErrorKind> { - APIOwner::cancel_tx(self, tx_id, tx_slate_id).map_err(|e| e.kind()) - } - - fn get_stored_tx(&self, entry: &TxLogEntry) -> Result, ErrorKind> { - APIOwner::get_stored_tx(self, entry).map_err(|e| e.kind()) - } - - fn post_tx(&self, tx: &Transaction, fluff: bool) -> Result<(), ErrorKind> { - APIOwner::post_tx(self, tx, fluff).map_err(|e| e.kind()) - } - - fn verify_slate_messages(&self, slate: &Slate) -> Result<(), ErrorKind> { - APIOwner::verify_slate_messages(self, slate).map_err(|e| e.kind()) - } - - fn restore(&self) -> Result<(), ErrorKind> { - APIOwner::restore(self).map_err(|e| e.kind()) - } - - fn check_repair(&self, delete_unconfirmed: bool) -> Result<(), ErrorKind> { - APIOwner::check_repair(self, delete_unconfirmed).map_err(|e| e.kind()) - } - - fn node_height(&self) -> Result<(u64, bool), ErrorKind> { - APIOwner::node_height(self).map_err(|e| e.kind()) - } -} - -/// Public definition used to generate jsonrpc api for APIForeign. -#[easy_jsonrpc::rpc] -pub trait ForeignApi { - /** - Networked version of [APIForeign::build_coinbase](struct.APIForeign.html#method.build_coinbase). - - # Json rpc example - - ``` - # grin_apiwallet::doctest_helper_json_rpc_foreign_assert_response!( - { - "jsonrpc": "2.0", - "method": "build_coinbase", - "params": [ - { - "fees": 0, - "height": 0, - "key_id": null - } - ], - "id": 1 - }, - { - "jsonrpc": "2.0", - "result": { - "Err": { - "CallbackImpl": "Error opening wallet" - } - }, - "id": 1 - } - # ); - ``` - */ - fn build_coinbase(&self, block_fees: &BlockFees) -> Result; - - /** - Networked version of [APIForeign::verify_slate_messages](struct.APIForeign.html#method.verify_slate_messages). - - # Json rpc example - - ``` - # grin_apiwallet::doctest_helper_json_rpc_foreign_assert_response!( - { - "jsonrpc": "2.0", - "method": "verify_slate_messages", - "params": [ - { - "version_info": { - "version": 2, - "orig_version": 2, - "min_compat_version": 0 - }, - "amount": 0, - "fee": 0, - "height": 0, - "id": "414bad48-3386-4fa7-8483-72384c886ba3", - "lock_height": 0, - "num_participants": 2, - "participant_data": [], - "tx": { - "body": { - "inputs": [], - "kernels": [], - "outputs": [] - }, - "offset": "0000000000000000000000000000000000000000000000000000000000000000" - } - } - ], - "id": 1 - }, - { - "jsonrpc": "2.0", - "result": { - "Ok": null - }, - "id": 1 - } - # ); - ``` - */ - fn verify_slate_messages(&self, slate: &Slate) -> Result<(), ErrorKind>; - - /** - Networked version of [APIForeign::receive_tx](struct.APIForeign.html#method.receive_tx). - - # Json rpc example - - ```ignore //TODO: No idea why this isn't expanding properly, check as we adjust the API - # grin_apiwallet::doctest_helper_json_rpc_foreign_assert_response!( - { - "jsonrpc": "2.0", - "method": "receive_tx", - "params": [ - { - "version_info": { - "version": 2, - "orig_version": 2, - "min_compat_version": 0 - }, - "amount": 0, - "fee": 0, - "height": 0, - "id": "414bad48-3386-4fa7-8483-72384c886ba3", - "lock_height": 0, - "num_participants": 2, - "participant_data": [], - "tx": { - "body": { - "inputs": [], - "kernels": [], - "outputs": [] - }, - "offset": "0000000000000000000000000000000000000000000000000000000000000000" - } - }, - null, - null - ], - "id": 1 - }, - { - "jsonrpc": "2.0", - "result": { - "Err": { - "CallbackImpl": "Error opening wallet" - } - }, - "id": 1 - } - # ); - ``` - */ - fn receive_tx( - &self, - slate: Slate, - dest_acct_name: Option, - message: Option, - ) -> Result; -} - -/// Wrapper around external API functions, intended to communicate -/// with other parties -pub struct APIForeign -where - W: WalletBackend, - C: NodeClient, - K: Keychain, -{ - /// Wallet, contains its keychain (TODO: Split these up into 2 traits - /// perhaps) - pub wallet: Arc>, - phantom: PhantomData, - phantom_c: PhantomData, -} - -impl<'a, W: ?Sized, C, K> APIForeign -where - W: WalletBackend, - C: NodeClient, - K: Keychain, -{ - /// Create new API instance - pub fn new(wallet_in: Arc>) -> Box { - Box::new(APIForeign { - wallet: wallet_in, - phantom: PhantomData, - phantom_c: PhantomData, - }) - } - - /// Build a new (potential) coinbase transaction in the wallet - pub fn build_coinbase(&self, block_fees: &BlockFees) -> Result { - let mut w = self.wallet.lock(); - w.open_with_credentials()?; - let res = updater::build_coinbase(&mut *w, block_fees); - w.close()?; - res - } - - /// Verifies all messages in the slate match their public keys - pub fn verify_slate_messages(&self, slate: &Slate) -> Result<(), Error> { - let secp = Secp256k1::with_caps(ContextFlag::VerifyOnly); - slate.verify_messages(&secp)?; - Ok(()) - } - - /// Receive a transaction from a sender - pub fn receive_tx( - &self, - slate: &mut Slate, - dest_acct_name: Option<&str>, - message: Option, - ) -> Result<(), Error> { - let mut w = self.wallet.lock(); - w.open_with_credentials()?; - let parent_key_id = match dest_acct_name { - Some(d) => { - let pm = w.get_acct_path(d.to_owned())?; - match pm { - Some(p) => p.path, - None => w.parent_key_id(), - } - } - None => w.parent_key_id(), - }; - // Don't do this multiple times - let tx = updater::retrieve_txs(&mut *w, None, Some(slate.id), Some(&parent_key_id), false)?; - for t in &tx { - if t.tx_type == TxLogEntryType::TxReceived { - return Err(ErrorKind::TransactionAlreadyReceived(slate.id.to_string()).into()); - } - } - - let message = match message { - Some(mut m) => { - m.truncate(USER_MESSAGE_MAX_LEN); - Some(m) - } - None => None, - }; - - let (_, mut create_fn) = - tx::add_output_to_slate(&mut *w, slate, &parent_key_id, 1, message)?; - create_fn(&mut *w, &slate.tx, PhantomData, PhantomData)?; - tx::update_message(&mut *w, slate)?; - w.close()?; - Ok(()) - } -} - -impl ForeignApi for APIForeign -where - W: WalletBackend, - C: NodeClient, - K: Keychain, -{ - fn build_coinbase(&self, block_fees: &BlockFees) -> Result { - APIForeign::build_coinbase(self, block_fees).map_err(|e| e.kind()) - } - - fn verify_slate_messages(&self, slate: &Slate) -> Result<(), ErrorKind> { - APIForeign::verify_slate_messages(self, slate).map_err(|e| e.kind()) - } - - fn receive_tx( - &self, - mut slate: Slate, - dest_acct_name: Option, - message: Option, - ) -> Result { - APIForeign::receive_tx( - self, - &mut slate, - dest_acct_name.as_ref().map(String::as_str), - message, - ) - .map_err(|e| e.kind())?; - Ok(slate) - } -} - -#[doc(hidden)] -#[macro_export] -macro_rules! doctest_helper_json_rpc_owner_assert_response { - ($request:tt, $expected_response:tt) => { - // create temporary wallet, run jsonrpc request on owner api of wallet, delete wallet, return - // json response. - // In order to prevent leaking tempdirs, This function should not panic. - fn rpc_owner_result( - request: serde_json::Value, - ) -> Result, String> { - use easy_jsonrpc::Handler; - use grin_apiwallet::api::{APIOwner, OwnerApi}; - use grin_keychain::ExtKeychain; - use grin_refwallet::{HTTPNodeClient, LMDBBackend, WalletBackend}; - use grin_util::Mutex; - use grin_wallet_config::WalletConfig; - use serde_json; - use std::sync::Arc; - use tempfile::tempdir; - - let dir = tempdir().map_err(|e| format!("{:#?}", e))?; - { - let mut wallet_config = WalletConfig::default(); - wallet_config.data_file_dir = dir - .path() - .to_str() - .ok_or("Failed to convert tmpdir path to string.".to_owned())? - .to_owned(); - let node_client = - HTTPNodeClient::new(&wallet_config.check_node_api_http_addr, None); - let wallet: Arc>> = - Arc::new(Mutex::new( - LMDBBackend::new(wallet_config.clone(), "", node_client) - .map_err(|e| format!("{:#?}", e))?, - )); - let api_owner = APIOwner::new(wallet); - let owner_api = &api_owner as &dyn OwnerApi; - Ok(owner_api.handle_request(request)) - } - } - - let response = rpc_owner_result(serde_json::json!($request)) - .unwrap() - .unwrap(); - let expected_response = serde_json::json!($expected_response); - - if response != expected_response { - panic!( - "(left != right) \nleft: {}\nright: {}", - serde_json::to_string_pretty(&response).unwrap(), - serde_json::to_string_pretty(&expected_response).unwrap() - ); - } - }; -} - -#[doc(hidden)] -#[macro_export] -macro_rules! doctest_helper_json_rpc_foreign_assert_response { - ($request:tt, $expected_response:tt) => { - // create temporary wallet, run jsonrpc request on api of wallet, delete wallet, return - // json response. - // In order to prevent leaking tempdirs, This function should not panic. - fn rpc_owner_result( - request: serde_json::Value, - ) -> Result, String> { - use easy_jsonrpc::Handler; - use grin_apiwallet::api::{APIForeign, ForeignApi}; - use grin_keychain::ExtKeychain; - use grin_refwallet::{HTTPNodeClient, LMDBBackend, WalletBackend}; - use grin_util::Mutex; - use grin_wallet_config::WalletConfig; - use serde_json; - use std::sync::Arc; - use tempfile::tempdir; - - let dir = tempdir().map_err(|e| format!("{:#?}", e))?; - { - let mut wallet_config = WalletConfig::default(); - wallet_config.data_file_dir = dir - .path() - .to_str() - .ok_or("Failed to convert tmpdir path to string.".to_owned())? - .to_owned(); - let node_client = - HTTPNodeClient::new(&wallet_config.check_node_api_http_addr, None); - let wallet: Arc>> = - Arc::new(Mutex::new( - LMDBBackend::new(wallet_config.clone(), "", node_client) - .map_err(|e| format!("{:#?}", e))?, - )); - let api_foreign = *APIForeign::new(wallet); - let foreign_api = &api_foreign as &dyn ForeignApi; - Ok(foreign_api.handle_request(request)) - } - } - - let response = rpc_owner_result(serde_json::json!($request)) - .unwrap() - .unwrap(); - let expected_response = serde_json::json!($expected_response); - - if response != expected_response { - panic!( - "(left != right) \nleft: {}\nright: {}", - serde_json::to_string_pretty(&response).unwrap(), - serde_json::to_string_pretty(&expected_response).unwrap() - ); - } - }; -} diff --git a/api/src/owner_rpc.rs b/api/src/owner_rpc.rs new file mode 100644 index 00000000..075526ba --- /dev/null +++ b/api/src/owner_rpc.rs @@ -0,0 +1,667 @@ +// Copyright 2019 The Grin Developers +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! JSON-RPC Stub generation for the Foreign API + +use uuid::Uuid; + +use crate::core::core::Transaction; +use crate::keychain::{Identifier, Keychain}; +use crate::libwallet::slate::Slate; +use crate::libwallet::types::{ + AcctPathMapping, NodeClient, OutputData, TxLogEntry, WalletBackend, WalletInfo, +}; +use crate::libwallet::ErrorKind; +use crate::util::secp::pedersen; +use crate::Owner; +use easy_jsonrpc; + +/// Public definition used to generate jsonrpc api for Owner. +#[easy_jsonrpc::rpc] +pub trait OwnerRpc { + /** + Networked version of [Owner::accounts](struct.Owner.html#method.accounts). + + # Json rpc example + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + { + "jsonrpc": "2.0", + "method": "accounts", + "params": [], + "id": 1 + }, + { + "jsonrpc": "2.0", + "result": { + "Ok": [ + { + "label": "default", + "path": "0200000000000000000000000000000000" + } + ] + }, + "id": 1 + } + # ); + ``` + */ + fn accounts(&self) -> Result, ErrorKind>; + + /** + Networked version of [Owner::create_account_path](struct.Owner.html#method.create_account_path). + + # Json rpc example + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + { + "jsonrpc": "2.0", + "method": "create_account_path", + "params": ["account1"], + "id": 1 + }, + { + "jsonrpc": "2.0", + "result": { + "Ok": "0200000001000000000000000000000000" + }, + "id": 1 + } + # ); + ``` + */ + fn create_account_path(&self, label: &String) -> Result; + + /** + Networked version of [Owner::set_active_account](struct.Owner.html#method.set_active_account). + + # Json rpc example + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + { + "jsonrpc": "2.0", + "method": "set_active_account", + "params": ["default"], + "id": 1 + }, + { + "jsonrpc": "2.0", + "result": { + "Ok": null + }, + "id": 1 + } + # ); + ``` + */ + fn set_active_account(&self, label: &String) -> Result<(), ErrorKind>; + + /** + Networked version of [Owner::retrieve_outputs](struct.Owner.html#method.retrieve_outputs). + + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + { + "jsonrpc": "2.0", + "method": "retrieve_outputs", + "params": [false, false, null], + "id": 1 + }, + { + "jsonrpc": "2.0", + "result": { + "Err": { + "CallbackImpl": "Error opening wallet" + } + }, + "id": 1 + } + # ); + ``` + */ + fn retrieve_outputs( + &self, + include_spent: bool, + refresh_from_node: bool, + tx_id: Option, + ) -> Result<(bool, Vec<(OutputData, pedersen::Commitment)>), ErrorKind>; + + /** + Networked version of [Owner::retrieve_txs](struct.Owner.html#method.retrieve_txs). + + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + { + "jsonrpc": "2.0", + "method": "retrieve_txs", + "params": [false, null, null], + "id": 1 + }, + { + "jsonrpc": "2.0", + "result": { + "Err": { + "CallbackImpl": "Error opening wallet" + } + }, + "id": 1 + } + # ); + ``` + */ + fn retrieve_txs( + &self, + refresh_from_node: bool, + tx_id: Option, + tx_slate_id: Option, + ) -> Result<(bool, Vec), ErrorKind>; + + /** + Networked version of [Owner::retrieve_summary_info](struct.Owner.html#method.retrieve_summary_info). + + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + { + "jsonrpc": "2.0", + "method": "retrieve_summary_info", + "params": [false, 1], + "id": 1 + }, + { + "jsonrpc": "2.0", + "result": { + "Err": { + "CallbackImpl": "Error opening wallet" + } + }, + "id": 1 + } + # ); + ``` + */ + fn retrieve_summary_info( + &self, + refresh_from_node: bool, + minimum_confirmations: u64, + ) -> Result<(bool, WalletInfo), ErrorKind>; + + /** + Networked version of [Owner::estimate_initiate_tx](struct.Owner.html#method.estimate_initiate_tx). + + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + { + "jsonrpc": "2.0", + "method": "estimate_initiate_tx", + "params": [null, 0, 0, 10, 0, false], + "id": 1 + }, + { + "jsonrpc": "2.0", + "result": { + "Err": { + "CallbackImpl": "Error opening wallet" + } + }, + "id": 1 + } + # ); + ``` + */ + fn estimate_initiate_tx( + &self, + src_acct_name: Option, + amount: u64, + minimum_confirmations: u64, + max_outputs: usize, + num_change_outputs: usize, + selection_strategy_is_use_all: bool, + ) -> Result<(/* total */ u64, /* fee */ u64), ErrorKind>; + + /** + Networked version of [Owner::finalize_tx](struct.Owner.html#method.finalize_tx). + + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + { + "jsonrpc": "2.0", + "method": "finalize_tx", + "params": [{ + "version_info": { + "version": 2, + "orig_version": 2, + "min_compat_version": 0 + }, + "amount": 0, + "fee": 0, + "height": 0, + "id": "414bad48-3386-4fa7-8483-72384c886ba3", + "lock_height": 0, + "num_participants": 2, + "participant_data": [], + "tx": { + "body": { + "inputs": [], + "kernels": [], + "outputs": [] + }, + "offset": "0000000000000000000000000000000000000000000000000000000000000000" + } + }], + "id": 1 + }, + { + "jsonrpc": "2.0", + "result": { + "Err": { + "CallbackImpl": "Error opening wallet" + } + }, + "id": 1 + } + # ); + ``` + */ + fn finalize_tx(&self, slate: Slate) -> Result; + + /** + Networked version of [Owner::cancel_tx](struct.Owner.html#method.cancel_tx). + + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + { + "jsonrpc": "2.0", + "method": "cancel_tx", + "params": [null, null], + "id": 1 + }, + { + "jsonrpc": "2.0", + "result": { + "Err": { + "CallbackImpl": "Error opening wallet" + } + }, + "id": 1 + } + # ); + ``` + */ + fn cancel_tx(&self, tx_id: Option, tx_slate_id: Option) -> Result<(), ErrorKind>; + + /** + Networked version of [Owner::get_stored_tx](struct.Owner.html#method.get_stored_tx). + + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + { + "jsonrpc": "2.0", + "method": "get_stored_tx", + "params": [ + { + "amount_credited": 0, + "amount_debited": 0, + "confirmation_ts": null, + "confirmed": false, + "creation_ts": "2019-03-05T20:49:59.444095Z", + "fee": null, + "id": 10, + "messages": null, + "num_inputs": 0, + "num_outputs": 0, + "parent_key_id": "0000000000000000000000000000000000", + "stored_tx": null, + "tx_slate_id": null, + "tx_type": "TxReceived" + } + ], + "id": 1 + }, + { + "jsonrpc": "2.0", + "result": { + "Ok": null + }, + "id": 1 + } + # ); + ``` + */ + fn get_stored_tx(&self, entry: &TxLogEntry) -> Result, ErrorKind>; + + /** + Networked version of [Owner::post_tx](struct.Owner.html#method.post_tx). + + ```no_run + # // This test currently fails on travis + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + { + "jsonrpc": "2.0", + "method": "post_tx", + "params": [ + { + "body": { + "inputs": [], + "kernels": [], + "outputs": [] + }, + "offset": "0000000000000000000000000000000000000000000000000000000000000000" + }, + false + ], + "id": 1 + }, + { + "jsonrpc": "2.0", + "result": { + "Err": { + "ClientCallback": "Posting transaction to node: Request error: Cannot make request: an error occurred trying to connect: Connection refused (os error 61)" + } + }, + "id": 1 + } + # ); + ``` + */ + fn post_tx(&self, tx: &Transaction, fluff: bool) -> Result<(), ErrorKind>; + + /** + Networked version of [Owner::verify_slate_messages](struct.Owner.html#method.verify_slate_messages). + + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + { + "jsonrpc": "2.0", + "method": "verify_slate_messages", + "params": [{ + "version_info": { + "version": 2, + "orig_version": 2, + "min_compat_version": 0 + }, + "amount": 0, + "fee": 0, + "height": 0, + "id": "414bad48-3386-4fa7-8483-72384c886ba3", + "lock_height": 0, + "num_participants": 2, + "participant_data": [], + "tx": { + "body": { + "inputs": [], + "kernels": [], + "outputs": [] + }, + "offset": "0000000000000000000000000000000000000000000000000000000000000000" + } + }], + "id": 1 + }, + { + "jsonrpc": "2.0", + "result": { + "Ok": null + }, + "id": 1 + } + # ); + ``` + */ + fn verify_slate_messages(&self, slate: &Slate) -> Result<(), ErrorKind>; + + /** + Networked version of [Owner::restore](struct.Owner.html#method.restore). + + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + { + "jsonrpc": "2.0", + "method": "restore", + "params": [], + "id": 1 + }, + { + "jsonrpc": "2.0", + "result": { + "Err": { + "CallbackImpl": "Error opening wallet" + } + }, + "id": 1 + } + # ); + ``` + */ + fn restore(&self) -> Result<(), ErrorKind>; + + /** + Networked version of [Owner::check_repair](struct.Owner.html#method.check_repair). + + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + { + "jsonrpc": "2.0", + "method": "check_repair", + "params": [false], + "id": 1 + }, + { + "jsonrpc": "2.0", + "result": { + "Err": { + "CallbackImpl": "Error opening wallet" + } + }, + "id": 1 + } + # ); + ``` + */ + fn check_repair(&self, delete_unconfirmed: bool) -> Result<(), ErrorKind>; + + /** + Networked version of [Owner::node_height](struct.Owner.html#method.node_height). + + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + { + "jsonrpc": "2.0", + "method": "node_height", + "params": [], + "id": 1 + }, + { + "jsonrpc": "2.0", + "result": { + "Err": { + "CallbackImpl": "Error opening wallet" + } + }, + "id": 1 + } + # ); + ``` + */ + fn node_height(&self) -> Result<(u64, bool), ErrorKind>; +} + +impl OwnerRpc for Owner +where + W: WalletBackend, + C: NodeClient, + K: Keychain, +{ + fn accounts(&self) -> Result, ErrorKind> { + Owner::accounts(self).map_err(|e| e.kind()) + } + + fn create_account_path(&self, label: &String) -> Result { + Owner::create_account_path(self, label).map_err(|e| e.kind()) + } + + fn set_active_account(&self, label: &String) -> Result<(), ErrorKind> { + Owner::set_active_account(self, label).map_err(|e| e.kind()) + } + + fn retrieve_outputs( + &self, + include_spent: bool, + refresh_from_node: bool, + tx_id: Option, + ) -> Result<(bool, Vec<(OutputData, pedersen::Commitment)>), ErrorKind> { + Owner::retrieve_outputs(self, include_spent, refresh_from_node, tx_id).map_err(|e| e.kind()) + } + + fn retrieve_txs( + &self, + refresh_from_node: bool, + tx_id: Option, + tx_slate_id: Option, + ) -> Result<(bool, Vec), ErrorKind> { + Owner::retrieve_txs(self, refresh_from_node, tx_id, tx_slate_id).map_err(|e| e.kind()) + } + + fn retrieve_summary_info( + &self, + refresh_from_node: bool, + minimum_confirmations: u64, + ) -> Result<(bool, WalletInfo), ErrorKind> { + Owner::retrieve_summary_info(self, refresh_from_node, minimum_confirmations) + .map_err(|e| e.kind()) + } + + fn estimate_initiate_tx( + &self, + src_acct_name: Option, + amount: u64, + minimum_confirmations: u64, + max_outputs: usize, + num_change_outputs: usize, + selection_strategy_is_use_all: bool, + ) -> Result<(/* total */ u64, /* fee */ u64), ErrorKind> { + Owner::estimate_initiate_tx( + self, + src_acct_name.as_ref().map(String::as_str), + amount, + minimum_confirmations, + max_outputs, + num_change_outputs, + selection_strategy_is_use_all, + ) + .map_err(|e| e.kind()) + } + + fn finalize_tx(&self, mut slate: Slate) -> Result { + Owner::finalize_tx(self, &mut slate).map_err(|e| e.kind())?; + Ok(slate) + } + + fn cancel_tx(&self, tx_id: Option, tx_slate_id: Option) -> Result<(), ErrorKind> { + Owner::cancel_tx(self, tx_id, tx_slate_id).map_err(|e| e.kind()) + } + + fn get_stored_tx(&self, entry: &TxLogEntry) -> Result, ErrorKind> { + Owner::get_stored_tx(self, entry).map_err(|e| e.kind()) + } + + fn post_tx(&self, tx: &Transaction, fluff: bool) -> Result<(), ErrorKind> { + Owner::post_tx(self, tx, fluff).map_err(|e| e.kind()) + } + + fn verify_slate_messages(&self, slate: &Slate) -> Result<(), ErrorKind> { + Owner::verify_slate_messages(self, slate).map_err(|e| e.kind()) + } + + fn restore(&self) -> Result<(), ErrorKind> { + Owner::restore(self).map_err(|e| e.kind()) + } + + fn check_repair(&self, delete_unconfirmed: bool) -> Result<(), ErrorKind> { + Owner::check_repair(self, delete_unconfirmed).map_err(|e| e.kind()) + } + + fn node_height(&self) -> Result<(u64, bool), ErrorKind> { + Owner::node_height(self).map_err(|e| e.kind()) + } +} + +#[doc(hidden)] +#[macro_export] +macro_rules! doctest_helper_json_rpc_owner_assert_response { + ($request:tt, $expected_response:tt) => { + // create temporary wallet, run jsonrpc request on owner api of wallet, delete wallet, return + // json response. + // In order to prevent leaking tempdirs, This function should not panic. + fn rpc_owner_result( + request: serde_json::Value, + ) -> Result, String> { + use easy_jsonrpc::Handler; + use grin_keychain::ExtKeychain; + use grin_util::Mutex; + use grin_wallet_api::{Owner, OwnerRpc}; + use grin_wallet_config::WalletConfig; + use grin_wallet_refwallet::{HTTPNodeClient, LMDBBackend, WalletBackend}; + use serde_json; + use std::sync::Arc; + use tempfile::tempdir; + + let dir = tempdir().map_err(|e| format!("{:#?}", e))?; + { + let mut wallet_config = WalletConfig::default(); + wallet_config.data_file_dir = dir + .path() + .to_str() + .ok_or("Failed to convert tmpdir path to string.".to_owned())? + .to_owned(); + let node_client = + HTTPNodeClient::new(&wallet_config.check_node_api_http_addr, None); + let wallet: Arc>> = + Arc::new(Mutex::new( + LMDBBackend::new(wallet_config.clone(), "", node_client) + .map_err(|e| format!("{:#?}", e))?, + )); + let api_owner = Owner::new(wallet); + let owner_api = &api_owner as &dyn OwnerRpc; + Ok(owner_api.handle_request(request)) + } + } + + let response = rpc_owner_result(serde_json::json!($request)) + .unwrap() + .unwrap(); + let expected_response = serde_json::json!($expected_response); + + if response != expected_response { + panic!( + "(left != right) \nleft: {}\nright: {}", + serde_json::to_string_pretty(&response).unwrap(), + serde_json::to_string_pretty(&expected_response).unwrap() + ); + } + }; +} diff --git a/libwallet/Cargo.toml b/libwallet/Cargo.toml index 26d2b477..997fab6b 100644 --- a/libwallet/Cargo.toml +++ b/libwallet/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "grin_libwallet" +name = "grin_wallet_libwallet" version = "1.1.0" authors = ["Grin Developers "] description = "Simple, private and scalable cryptocurrency implementation based on the MimbleWimble chain format." diff --git a/libwallet/tests/libwallet.rs b/libwallet/tests/libwallet.rs index 1a1814b0..d126c223 100644 --- a/libwallet/tests/libwallet.rs +++ b/libwallet/tests/libwallet.rs @@ -17,10 +17,10 @@ use self::core::libtx::{aggsig, proof}; use self::keychain::{BlindSum, BlindingFactor, ExtKeychain, Keychain}; use self::util::secp; use self::util::secp::key::{PublicKey, SecretKey}; -use grin_libwallet::types::Context; use grin_core as core; use grin_keychain as keychain; use grin_util as util; +use grin_wallet_libwallet::types::Context; use rand::thread_rng; fn kernel_sig_msg() -> secp::Message { diff --git a/libwallet/tests/slate_versioning.rs b/libwallet/tests/slate_versioning.rs index 2fd6873d..49572735 100644 --- a/libwallet/tests/slate_versioning.rs +++ b/libwallet/tests/slate_versioning.rs @@ -12,7 +12,7 @@ // limitations under the License. //! core::libtx specific tests -use grin_libwallet::slate::Slate; +use grin_wallet_libwallet::slate::Slate; // test all slate conversions #[test] @@ -65,5 +65,4 @@ fn slate_conversions() { let s = res.unwrap().serialize_to_version(Some(0)); assert!(s.is_ok()); println!("v2 -> v0: {}", s.unwrap()); - } diff --git a/refwallet/Cargo.toml b/refwallet/Cargo.toml index b86c2ce2..5d6bc7fb 100644 --- a/refwallet/Cargo.toml +++ b/refwallet/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "grin_refwallet" +name = "grin_wallet_refwallet" version = "1.1.0" authors = ["Grin Developers "] description = "Simple, private and scalable cryptocurrency implementation based on the MimbleWimble chain format." @@ -32,8 +32,8 @@ uuid = { version = "0.6", features = ["serde", "v4"] } url = "1.7.0" chrono = { version = "0.4.4", features = ["serde"] } -grin_apiwallet = { path = "../apiwallet", version = "1.1.0" } -grin_libwallet = { path = "../libwallet", version = "1.1.0" } +grin_wallet_api = { path = "../api", version = "1.1.0" } +grin_wallet_libwallet = { path = "../libwallet", version = "1.1.0" } grin_wallet_config = { path = "../config", version = "1.1.0" } grin_core = { git = "https://github.com/mimblewimble/grin", branch = "milestone/1.1.0" } diff --git a/refwallet/src/adapters/keybase.rs b/refwallet/src/adapters/keybase.rs index 06c8bcdf..0396ba9b 100644 --- a/refwallet/src/adapters/keybase.rs +++ b/refwallet/src/adapters/keybase.rs @@ -267,7 +267,7 @@ fn poll(nseconds: u64, channel: &str) -> Option { channel, slate.id, ); return Some(slate); - }, + } Err(_) => (), } } @@ -301,7 +301,7 @@ impl WalletCommAdapter for KeybaseWalletCommAdapter { false => { return Err(ErrorKind::ClientCallback( "Posting transaction slate".to_owned(), - ))? + ))?; } } info!("tx request has been sent to @{}, tx uuid: {}", addr, id); @@ -311,7 +311,7 @@ impl WalletCommAdapter for KeybaseWalletCommAdapter { None => { return Err(ErrorKind::ClientCallback( "Receiving reply from recipient".to_owned(), - ))? + ))?; } } } @@ -384,7 +384,8 @@ impl WalletCommAdapter for KeybaseWalletCommAdapter { }) { // Reply to the same channel with topic SLATE_SIGNED Ok(_) => { - let slate = slate.serialize_to_version(Some(slate.version_info.orig_version))?; + let slate = slate + .serialize_to_version(Some(slate.version_info.orig_version))?; // TODO: Send the same version of slate that was sent to us let success = send(slate, channel, SLATE_SIGNED, TTL); diff --git a/refwallet/src/controller.rs b/refwallet/src/controller.rs index b03067d0..83aae396 100644 --- a/refwallet/src/controller.rs +++ b/refwallet/src/controller.rs @@ -17,7 +17,7 @@ //! Still experimental use crate::adapters::{FileWalletCommAdapter, HTTPWalletCommAdapter, KeybaseWalletCommAdapter}; use crate::api::{ApiServer, BasicAuthMiddleware, Handler, ResponseFuture, Router, TLSConfig}; -use crate::apiwallet::api::{APIForeign, APIOwner}; +use crate::apiwallet::{Foreign, Owner}; use crate::core::core; use crate::core::core::Transaction; use crate::keychain::Keychain; @@ -47,11 +47,11 @@ use uuid::Uuid; pub fn owner_single_use(wallet: Arc>, f: F) -> Result<(), Error> where T: WalletBackend, - F: FnOnce(&mut APIOwner) -> Result<(), Error>, + F: FnOnce(&mut Owner) -> Result<(), Error>, C: NodeClient, K: Keychain, { - f(&mut APIOwner::new(wallet.clone()))?; + f(&mut Owner::new(wallet.clone()))?; Ok(()) } @@ -60,11 +60,11 @@ where pub fn foreign_single_use(wallet: Arc>, f: F) -> Result<(), Error> where T: WalletBackend, - F: FnOnce(&mut APIForeign) -> Result<(), Error>, + F: FnOnce(&mut Foreign) -> Result<(), Error>, C: NodeClient, K: Keychain, { - f(&mut APIForeign::new(wallet.clone()))?; + f(&mut Foreign::new(wallet.clone()))?; Ok(()) } @@ -186,7 +186,7 @@ where pub fn retrieve_outputs( &self, req: &Request, - api: APIOwner, + api: Owner, ) -> Result<(bool, Vec<(OutputData, pedersen::Commitment)>), Error> { let mut update_from_node = false; let mut id = None; @@ -210,7 +210,7 @@ where pub fn retrieve_txs( &self, req: &Request, - api: APIOwner, + api: Owner, ) -> Result<(bool, Vec), Error> { let mut tx_id = None; let mut tx_slate_id = None; @@ -237,7 +237,7 @@ where pub fn retrieve_stored_tx( &self, req: &Request, - api: APIOwner, + api: Owner, ) -> Result<(bool, Option), Error> { let params = parse_params(req); if let Some(id_string) = params.get("id") { @@ -270,7 +270,7 @@ where pub fn retrieve_summary_info( &self, req: &Request, - api: APIOwner, + api: Owner, ) -> Result<(bool, WalletInfo), Error> { let mut minimum_confirmations = 1; // TODO - default needed here let params = parse_params(req); @@ -288,13 +288,13 @@ where pub fn node_height( &self, _req: &Request, - api: APIOwner, + api: Owner, ) -> Result<(u64, bool), Error> { api.node_height() } fn handle_get_request(&self, req: &Request) -> Result, Error> { - let api = APIOwner::new(self.wallet.clone()); + let api = Owner::new(self.wallet.clone()); Ok( match req @@ -318,7 +318,7 @@ where pub fn issue_send_tx( &self, req: Request, - api: APIOwner, + api: Owner, ) -> Box + Send> { Box::new(parse_body(req).and_then(move |args: SendTXArgs| { let result = api.initiate_tx( @@ -382,7 +382,7 @@ where pub fn finalize_tx( &self, req: Request, - api: APIOwner, + api: Owner, ) -> Box + Send> { Box::new( parse_body(req).and_then(move |mut slate| match api.finalize_tx(&mut slate) { @@ -398,7 +398,7 @@ where pub fn cancel_tx( &self, req: Request, - api: APIOwner, + api: Owner, ) -> Box + Send> { let params = parse_params(&req); if let Some(id_string) = params.get("id") { @@ -446,7 +446,7 @@ where pub fn post_tx( &self, req: Request, - api: APIOwner, + api: Owner, ) -> Box + Send> { let params = match req.uri().query() { Some(query_string) => form_urlencoded::parse(query_string.as_bytes()) @@ -472,7 +472,7 @@ where pub fn repost( &self, req: Request, - api: APIOwner, + api: Owner, ) -> Box + Send> { let params = parse_params(&req); let mut id_int: Option = None; @@ -551,7 +551,7 @@ where } fn handle_post_request(&self, req: Request) -> WalletResponseFuture { - let api = APIOwner::new(self.wallet.clone()); + let api = Owner::new(self.wallet.clone()); match req .uri() .path() @@ -652,7 +652,7 @@ where fn build_coinbase( &self, req: Request, - api: APIForeign, + api: Foreign, ) -> Box + Send> { Box::new(parse_body(req).and_then(move |block_fees| api.build_coinbase(&block_fees))) } @@ -660,7 +660,7 @@ where fn receive_tx( &self, req: Request, - api: APIForeign, + api: Foreign, ) -> Box + Send> { Box::new(parse_body(req).and_then( //TODO: No way to insert a message from the params @@ -671,7 +671,9 @@ where err(e) } else { match api.receive_tx(&mut slate, None, None) { - Ok(_) => ok(slate.serialize_to_version(Some(slate.version_info.orig_version)).unwrap()), + Ok(_) => ok(slate + .serialize_to_version(Some(slate.version_info.orig_version)) + .unwrap()), Err(e) => { error!("receive_tx: failed with error: {}", e); err(e) @@ -683,7 +685,7 @@ where } fn handle_request(&self, req: Request) -> WalletResponseFuture { - let api = *APIForeign::new(self.wallet.clone()); + let api = *Foreign::new(self.wallet.clone()); match req .uri() .path() diff --git a/refwallet/src/lib.rs b/refwallet/src/lib.rs index 194e1a47..a931b652 100644 --- a/refwallet/src/lib.rs +++ b/refwallet/src/lib.rs @@ -27,10 +27,10 @@ use failure; use grin_api as api; extern crate grin_core as core; use grin_keychain as keychain; -use grin_libwallet as libwallet; -use grin_apiwallet as apiwallet; use grin_store as store; use grin_util as util; +use grin_wallet_api as apiwallet; +use grin_wallet_libwallet as libwallet; extern crate grin_wallet_config as config; mod adapters; diff --git a/refwallet/src/test_framework/mod.rs b/refwallet/src/test_framework/mod.rs index 5a71e987..a07efbd4 100644 --- a/refwallet/src/test_framework/mod.rs +++ b/refwallet/src/test_framework/mod.rs @@ -17,7 +17,7 @@ use self::core::core::{OutputFeatures, OutputIdentifier, Transaction}; use self::core::{consensus, global, pow, ser}; use self::util::secp::pedersen; use self::util::Mutex; -use crate::apiwallet::api::APIOwner; +use crate::apiwallet::Owner; use crate::libwallet::types::{BlockFees, CbData, NodeClient, WalletInfo, WalletInst}; use crate::lmdb_wallet::LMDBBackend; use crate::{controller, libwallet, WalletSeed}; @@ -185,7 +185,7 @@ where /// send an amount to a destination pub fn send_to_dest( client: LocalWalletClient, - api: &mut APIOwner, + api: &mut Owner, dest: &str, amount: u64, ) -> Result<(), libwallet::Error> @@ -201,8 +201,7 @@ where 500, // max outputs 1, // num change outputs true, // select all outputs - None, - None, + None, None, )?; let mut slate = client.send_tx_slate_direct(dest, &slate_i)?; api.tx_lock_outputs(&slate, lock_fn)?; @@ -213,7 +212,7 @@ where /// get wallet info totals pub fn wallet_info( - api: &mut APIOwner, + api: &mut Owner, ) -> Result where T: WalletBackend, diff --git a/refwallet/tests/accounts.rs b/refwallet/tests/accounts.rs index 0aff34c9..7d92ec78 100644 --- a/refwallet/tests/accounts.rs +++ b/refwallet/tests/accounts.rs @@ -14,7 +14,7 @@ //! tests differing accounts in the same wallet #[macro_use] extern crate log; -extern crate grin_refwallet as wallet; +extern crate grin_wallet_refwallet as wallet; use self::core::global; use self::core::global::ChainTypes; @@ -22,12 +22,11 @@ use self::keychain::{ExtKeychain, Keychain}; use grin_core as core; use grin_keychain as keychain; use grin_util as util; -use grin_libwallet as libwallet; -use wallet::test_framework::{self, LocalWalletClient, WalletProxy}; +use grin_wallet_libwallet as libwallet; use std::fs; use std::thread; use std::time::Duration; - +use wallet::test_framework::{self, LocalWalletClient, WalletProxy}; fn clean_output_dir(test_dir: &str) { let _ = fs::remove_dir_all(test_dir); @@ -184,8 +183,7 @@ fn accounts_test_impl(test_dir: &str) -> Result<(), libwallet::Error> { 500, // max outputs 1, // num change outputs true, // select all outputs - None, - None, + None, None, )?; slate = client1.send_tx_slate_direct("wallet2", &slate)?; api.tx_lock_outputs(&slate, lock_fn)?; diff --git a/refwallet/tests/check.rs b/refwallet/tests/check.rs index 5cf39259..952a7616 100644 --- a/refwallet/tests/check.rs +++ b/refwallet/tests/check.rs @@ -14,21 +14,21 @@ //! tests differing accounts in the same wallet #[macro_use] extern crate log; -extern crate grin_refwallet as wallet; +extern crate grin_wallet_refwallet as wallet; use self::core::consensus; use self::core::global; use self::core::global::ChainTypes; use self::keychain::ExtKeychain; -use wallet::FileWalletCommAdapter; use grin_core as core; use grin_keychain as keychain; use grin_util as util; -use grin_libwallet as libwallet; -use wallet::test_framework::{self, LocalWalletClient, WalletProxy}; +use grin_wallet_libwallet as libwallet; use std::fs; use std::thread; use std::time::Duration; +use wallet::test_framework::{self, LocalWalletClient, WalletProxy}; +use wallet::FileWalletCommAdapter; fn clean_output_dir(test_dir: &str) { let _ = fs::remove_dir_all(test_dir); diff --git a/refwallet/tests/encryption.rs b/refwallet/tests/encryption.rs index 5c052ab9..4f3ccef5 100644 --- a/refwallet/tests/encryption.rs +++ b/refwallet/tests/encryption.rs @@ -12,7 +12,7 @@ // limitations under the License. //! core::libtx specific tests -extern crate grin_refwallet as wallet; +extern crate grin_wallet_refwallet as wallet; use self::wallet::{EncryptedWalletSeed, WalletSeed}; diff --git a/refwallet/tests/file.rs b/refwallet/tests/file.rs index 47a8aee4..e1fe0b10 100644 --- a/refwallet/tests/file.rs +++ b/refwallet/tests/file.rs @@ -14,7 +14,7 @@ //! Test a wallet file send/recieve #[macro_use] extern crate log; -extern crate grin_refwallet as wallet; +extern crate grin_wallet_refwallet as wallet; use self::core::global; use self::core::global::ChainTypes; @@ -24,7 +24,7 @@ use self::wallet::FileWalletCommAdapter; use grin_core as core; use grin_keychain as keychain; use grin_util as util; -use grin_libwallet as libwallet; +use grin_wallet_libwallet as libwallet; use std::fs; use std::thread; use std::time::Duration; diff --git a/refwallet/tests/repost.rs b/refwallet/tests/repost.rs index 1557e3d6..5023ff2f 100644 --- a/refwallet/tests/repost.rs +++ b/refwallet/tests/repost.rs @@ -14,8 +14,8 @@ //! Test a wallet repost command #[macro_use] extern crate log; -extern crate grin_refwallet as wallet; -extern crate grin_libwallet as libwallet; +extern crate grin_wallet_libwallet as libwallet; +extern crate grin_wallet_refwallet as wallet; use self::core::global; use self::core::global::ChainTypes; diff --git a/refwallet/tests/restore.rs b/refwallet/tests/restore.rs index 25b25e2b..aea0ed7b 100644 --- a/refwallet/tests/restore.rs +++ b/refwallet/tests/restore.rs @@ -14,8 +14,8 @@ //! tests for wallet restore #[macro_use] extern crate log; -extern crate grin_refwallet as wallet; -extern crate grin_libwallet as libwallet; +extern crate grin_wallet_libwallet as libwallet; +extern crate grin_wallet_refwallet as wallet; use self::core::global; use self::core::global::ChainTypes; @@ -241,8 +241,7 @@ fn setup_restore(test_dir: &str) -> Result<(), libwallet::Error> { 500, // max outputs 1, // num change outputs true, // select all outputs - None, - None, + None, None, )?; slate = client1.send_tx_slate_direct("wallet2", &slate_i)?; sender_api.tx_lock_outputs(&slate, lock_fn)?; diff --git a/refwallet/tests/self_send.rs b/refwallet/tests/self_send.rs index 237864cb..98e0aa3d 100644 --- a/refwallet/tests/self_send.rs +++ b/refwallet/tests/self_send.rs @@ -14,7 +14,7 @@ //! Test a wallet sending to self #[macro_use] extern crate log; -extern crate grin_refwallet as wallet; +extern crate grin_wallet_refwallet as wallet; use self::core::global; use self::core::global::ChainTypes; @@ -23,7 +23,7 @@ use self::wallet::test_framework::{self, LocalWalletClient, WalletProxy}; use grin_core as core; use grin_keychain as keychain; use grin_util as util; -use grin_libwallet as libwallet; +use grin_wallet_libwallet as libwallet; use std::fs; use std::thread; use std::time::Duration; diff --git a/refwallet/tests/transaction.rs b/refwallet/tests/transaction.rs index a26b0d72..ee972092 100644 --- a/refwallet/tests/transaction.rs +++ b/refwallet/tests/transaction.rs @@ -14,8 +14,8 @@ //! tests for transactions building within core::libtx #[macro_use] extern crate log; -extern crate grin_refwallet as wallet; -extern crate grin_libwallet as libwallet; +extern crate grin_wallet_libwallet as libwallet; +extern crate grin_wallet_refwallet as wallet; use self::core::global; use self::core::global::ChainTypes; @@ -103,8 +103,7 @@ fn basic_transaction_api(test_dir: &str) -> Result<(), libwallet::Error> { 500, // max outputs 1, // num change outputs true, // select all outputs - None, - None, + None, None, )?; slate = client1.send_tx_slate_direct("wallet2", &slate_i)?; sender_api.tx_lock_outputs(&slate, lock_fn)?; @@ -364,8 +363,7 @@ fn tx_rollback(test_dir: &str) -> Result<(), libwallet::Error> { 500, // max outputs 1, // num change outputs true, // select all outputs - None, - None, + None, None, )?; slate = client1.send_tx_slate_direct("wallet2", &slate_i)?; sender_api.tx_lock_outputs(&slate, lock_fn)?; @@ -427,7 +425,7 @@ fn tx_rollback(test_dir: &str) -> Result<(), libwallet::Error> { Ok(()) })?; - // wallet 1 is bold and doesn't ever post the transaction + // wallet 1 is bold and doesn't ever post the transaction // mine a few more blocks let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 5); diff --git a/src/bin/cmd/wallet.rs b/src/bin/cmd/wallet.rs index c5f8d17d..14608ed0 100644 --- a/src/bin/cmd/wallet.rs +++ b/src/bin/cmd/wallet.rs @@ -15,8 +15,8 @@ use crate::cmd::wallet_args; use crate::config::GlobalWalletConfig; use clap::ArgMatches; -use grin_refwallet::{self, HTTPNodeClient, WalletSeed}; use grin_wallet_config::WalletConfig; +use grin_wallet_refwallet::{self, HTTPNodeClient, WalletSeed}; use std::path::PathBuf; use std::thread; use std::time::Duration; @@ -31,7 +31,7 @@ pub fn _init_wallet_seed(wallet_config: WalletConfig, password: &str) { pub fn seed_exists(wallet_config: WalletConfig) -> bool { let mut data_file_dir = PathBuf::new(); data_file_dir.push(wallet_config.data_file_dir); - data_file_dir.push(grin_refwallet::SEED_FILE); + data_file_dir.push(grin_wallet_refwallet::SEED_FILE); if data_file_dir.exists() { true } else { diff --git a/src/bin/cmd/wallet_args.rs b/src/bin/cmd/wallet_args.rs index 9f9f1b4a..7f6543fc 100644 --- a/src/bin/cmd/wallet_args.rs +++ b/src/bin/cmd/wallet_args.rs @@ -20,9 +20,9 @@ use clap::ArgMatches; use failure::Fail; use grin_core as core; use grin_keychain as keychain; -use grin_refwallet::{command, instantiate_wallet, NodeClient, WalletInst, WalletSeed}; -use grin_refwallet::{Error, ErrorKind}; use grin_wallet_config::WalletConfig; +use grin_wallet_refwallet::{command, instantiate_wallet, NodeClient, WalletInst, WalletSeed}; +use grin_wallet_refwallet::{Error, ErrorKind}; use linefeed::terminal::Signal; use linefeed::{Interface, ReadResult}; use rpassword; @@ -399,7 +399,7 @@ pub fn parse_send_args(args: &ArgMatches) -> Result { let v = parse_required(args, "target_slate_version")?; Some(parse_u64(v, "target_slate_version")? as u16) - }, + } false => None, } }; diff --git a/src/bin/cmd/wallet_tests.rs b/src/bin/cmd/wallet_tests.rs index 8440690f..89436ebf 100644 --- a/src/bin/cmd/wallet_tests.rs +++ b/src/bin/cmd/wallet_tests.rs @@ -15,10 +15,10 @@ #[cfg(test)] mod wallet_tests { use clap; - use grin_refwallet; use grin_util as util; + use grin_wallet_refwallet; - use grin_refwallet::test_framework::{self, LocalWalletClient, WalletProxy}; + use grin_wallet_refwallet::test_framework::{self, LocalWalletClient, WalletProxy}; use clap::{App, ArgMatches}; use grin_util::Mutex; @@ -30,8 +30,8 @@ mod wallet_tests { use grin_core::global; use grin_core::global::ChainTypes; use grin_keychain::ExtKeychain; - use grin_refwallet::{LMDBBackend, WalletBackend, WalletInst, WalletSeed}; use grin_wallet_config::{GlobalWalletConfig, WalletConfig}; + use grin_wallet_refwallet::{LMDBBackend, WalletBackend, WalletInst, WalletSeed}; use super::super::wallet_args; @@ -49,7 +49,7 @@ mod wallet_tests { pub fn config_command_wallet( dir_name: &str, wallet_name: &str, - ) -> Result<(), grin_refwallet::Error> { + ) -> Result<(), grin_wallet_refwallet::Error> { let mut current_dir; let mut default_config = GlobalWalletConfig::default(); current_dir = env::current_dir().unwrap_or_else(|e| { @@ -61,7 +61,7 @@ mod wallet_tests { let mut config_file_name = current_dir.clone(); config_file_name.push("grin-wallet.toml"); if config_file_name.exists() { - return Err(grin_refwallet::ErrorKind::ArgumentError( + return Err(grin_wallet_refwallet::ErrorKind::ArgumentError( "grin-wallet.toml already exists in the target directory. Please remove it first" .to_owned(), ))?; @@ -122,7 +122,8 @@ mod wallet_tests { node_client: LocalWalletClient, passphrase: &str, account: &str, - ) -> Result>>, grin_refwallet::Error> { + ) -> Result>>, grin_wallet_refwallet::Error> + { wallet_config.chain_type = None; // First test decryption, so we can abort early if we have the wrong password let _ = WalletSeed::from_file(&wallet_config, passphrase)?; @@ -138,7 +139,7 @@ mod wallet_tests { wallet_name: &str, client: &LocalWalletClient, arg_vec: Vec<&str>, - ) -> Result { + ) -> Result { let args = app.clone().get_matches_from(arg_vec); let _ = get_wallet_subcommand(test_dir, wallet_name, args.clone()); let mut config = initial_setup_wallet(test_dir, wallet_name); @@ -148,7 +149,7 @@ mod wallet_tests { } /// command line tests - fn command_line_test_impl(test_dir: &str) -> Result<(), grin_refwallet::Error> { + fn command_line_test_impl(test_dir: &str) -> Result<(), grin_wallet_refwallet::Error> { setup(test_dir); // Create a new proxy to simulate server and wallet responses let mut wallet_proxy: WalletProxy = @@ -191,9 +192,7 @@ mod wallet_tests { }); // Create some accounts in wallet 1 - let arg_vec = vec![ - "grin-wallet", "-p", "password", "account", "-c", "mining", - ]; + let arg_vec = vec!["grin-wallet", "-p", "password", "account", "-c", "mining"]; execute_command(&app, test_dir, "wallet1", &client1, arg_vec)?; let arg_vec = vec![ @@ -240,7 +239,7 @@ mod wallet_tests { // Mine a bit into wallet 1 so we have something to send // (TODO: Be able to stop listeners so we can test this better) let wallet1 = instantiate_wallet(config1.clone(), client1.clone(), "password", "default")?; - grin_refwallet::controller::owner_single_use(wallet1.clone(), |api| { + grin_wallet_refwallet::controller::owner_single_use(wallet1.clone(), |api| { api.set_active_account("mining")?; Ok(()) })?; @@ -313,7 +312,7 @@ mod wallet_tests { let wallet1 = instantiate_wallet(config1.clone(), client1.clone(), "password", "default")?; // Check our transaction log, should have 10 entries - grin_refwallet::controller::owner_single_use(wallet1.clone(), |api| { + grin_wallet_refwallet::controller::owner_single_use(wallet1.clone(), |api| { api.set_active_account("mining")?; let (refreshed, txs) = api.retrieve_txs(true, None, None)?; assert!(refreshed); @@ -328,19 +327,12 @@ mod wallet_tests { let arg_vec = vec!["grin-wallet", "-p", "password", "-a", "mining", "info"]; execute_command(&app, test_dir, "wallet1", &client1, arg_vec)?; - let arg_vec = vec![ - "grin-wallet", - "-p", - "password", - "-a", - "account_1", - "info", - ]; + let arg_vec = vec!["grin-wallet", "-p", "password", "-a", "account_1", "info"]; execute_command(&app, test_dir, "wallet2", &client1, arg_vec)?; // check results in wallet 2 let wallet2 = instantiate_wallet(config2.clone(), client2.clone(), "password", "default")?; - grin_refwallet::controller::owner_single_use(wallet2.clone(), |api| { + grin_wallet_refwallet::controller::owner_single_use(wallet2.clone(), |api| { api.set_active_account("account_1")?; let (_, wallet1_info) = api.retrieve_summary_info(true, 1)?; assert_eq!(wallet1_info.last_confirmed_height, bh); @@ -396,7 +388,7 @@ mod wallet_tests { // Check our transaction log, should have bh entries + one for the self receive let wallet1 = instantiate_wallet(config1.clone(), client1.clone(), "password", "default")?; - grin_refwallet::controller::owner_single_use(wallet1.clone(), |api| { + grin_wallet_refwallet::controller::owner_single_use(wallet1.clone(), |api| { api.set_active_account("mining")?; let (refreshed, txs) = api.retrieve_txs(true, None, None)?; assert!(refreshed); @@ -430,7 +422,7 @@ mod wallet_tests { // Check our transaction log, should have bh entries + 2 for the self receives let wallet1 = instantiate_wallet(config1.clone(), client1.clone(), "password", "default")?; - grin_refwallet::controller::owner_single_use(wallet1.clone(), |api| { + grin_wallet_refwallet::controller::owner_single_use(wallet1.clone(), |api| { api.set_active_account("mining")?; let (refreshed, txs) = api.retrieve_txs(true, None, None)?; assert!(refreshed); @@ -478,7 +470,14 @@ mod wallet_tests { execute_command(&app, test_dir, "wallet1", &client1, arg_vec)?; let arg_vec = vec![ - "grin-wallet", "-p", "password", "-a", "mining", "cancel", "-i", "26", + "grin-wallet", + "-p", + "password", + "-a", + "mining", + "cancel", + "-i", + "26", ]; execute_command(&app, test_dir, "wallet1", &client1, arg_vec)?; @@ -488,14 +487,19 @@ mod wallet_tests { // message output (mostly spit out for a visual in test logs) let arg_vec = vec![ - "grin-wallet", "-p", "password", "-a", "mining", "txs", "-i", "10", + "grin-wallet", + "-p", + "password", + "-a", + "mining", + "txs", + "-i", + "10", ]; execute_command(&app, test_dir, "wallet1", &client1, arg_vec)?; // txs and outputs (mostly spit out for a visual in test logs) - let arg_vec = vec![ - "grin-wallet", "-p", "password", "-a", "mining", "outputs", - ]; + let arg_vec = vec!["grin-wallet", "-p", "password", "-a", "mining", "outputs"]; execute_command(&app, test_dir, "wallet1", &client1, arg_vec)?; // let logging finish