[][src]Struct grin_wallet_api::Owner

pub struct Owner<W: ?Sized, C, K> where
    W: WalletBackend<C, K>,
    C: NodeClient,
    K: Keychain, 
{ pub wallet: Arc<Mutex<W>>, pub doctest_mode: bool, // some fields omitted }

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.

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).

Fields

wallet: Arc<Mutex<W>>

A reference-counted mutex to an implementation of the WalletBackend trait.

doctest_mode: bool

Flag to normalize some output during testing. Can mostly be ignored.

Methods

impl<W: ?Sized, C, K> Owner<W, C, K> where
    W: WalletBackend<C, K>,
    C: NodeClient,
    K: Keychain, 
[src]

pub fn new(wallet_in: Arc<Mutex<W>>) -> Self[src]

Create a new API instance with the given wallet instance. All subsequent API calls will operate on this instance of the wallet.

Each method will call the WalletBackend's open_with_credentials (initialising a keychain with the master seed,) perform its operation, then close the keychain with a call to close

Arguments

  • wallet_in - A reference-counted mutex containing an implementation of the WalletBackend trait.

Returns

  • An instance of the OwnerApi holding a reference to the provided wallet

Example

use grin_wallet_util::grin_keychain as keychain;
use grin_wallet_util::grin_util as util;
use grin_wallet_api as api;
use grin_wallet_config as config;
use grin_wallet_impls as impls;
use grin_wallet_libwallet as libwallet;

use keychain::ExtKeychain;
use tempfile::tempdir;

use std::sync::Arc;
use util::Mutex;

use api::Owner;
use config::WalletConfig;
use impls::{HTTPNodeClient, LMDBBackend};
use libwallet::types::WalletBackend;

let mut wallet_config = WalletConfig::default();

// A NodeClient must first be created to handle communication between
// the wallet and the node.

let node_client = HTTPNodeClient::new(&wallet_config.check_node_api_http_addr, None);
let mut wallet:Arc<Mutex<WalletBackend<HTTPNodeClient, ExtKeychain>>> =
    Arc::new(Mutex::new(
        LMDBBackend::new(wallet_config.clone(), "", node_client).unwrap()
    ));

let api_owner = Owner::new(wallet.clone());
// .. perform wallet operations

pub fn accounts(&self) -> Result<Vec<AcctPathMapping>, Error>[src]

Returns a list of accounts stored in the wallet (i.e. mappings between user-specified labels and BIP32 derivation paths.

Returns

Remarks

  • A wallet should always have the path with the label 'default' path defined, with path m/0/0
  • This method does not need to use the wallet seed or keychain.

Example

Set up as in new method above.


let api_owner = Owner::new(wallet.clone());

let result = api_owner.accounts();

if let Ok(accts) = result {
    //...
}

pub fn create_account_path(&self, label: &str) -> Result<Identifier, Error>[src]

Creates a new 'account', which is a mapping of a user-specified label to a BIP32 path

Arguments

  • label - A human readable label to which to map the new BIP32 Path

Returns

Remarks

  • Wallets should be initialised with the 'default' path mapped to m/0/0

  • Each call to this function will increment the first element of the path 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 for further details.

  • This function does not need to use the root wallet seed or keychain.

Example

Set up as in new method above.


let api_owner = Owner::new(wallet.clone());

let result = api_owner.create_account_path("account1");

if let Ok(identifier) = result {
    //...
}

pub fn set_active_account(&self, label: &str) -> Result<(), Error>[src]

Sets the wallet's currently active account. This sets the BIP32 parent path used for most key-derivation operations.

Arguments

  • label - The human readable label for the account. Accounts can be retrieved via the account method

Returns

  • Result Containing:
  • Ok(()) if the path was correctly set
  • or libwallet::Error if an error is encountered.

Remarks

  • Wallet parent paths are 2 path elements long, e.g. m/0/0 is the path labelled 'default'. Keys derived from this parent path are 3 elements long, e.g. the secret keys derived from the m/0/0 path will be at paths m/0/0/0, m/0/0/1 etc...

  • This function does not need to use the root wallet seed or keychain.

Example

Set up as in new method above.


let api_owner = Owner::new(wallet.clone());

let result = api_owner.create_account_path("account1");

if let Ok(identifier) = result {
    // set the account active
    let result2 = api_owner.set_active_account("account1");
}

pub fn retrieve_outputs(
    &self,
    include_spent: bool,
    refresh_from_node: bool,
    tx_id: Option<u32>
) -> Result<(bool, Vec<OutputCommitMapping>), Error>
[src]

Returns a list of outputs from the active account in the wallet.

Arguments

  • include_spent - If true, outputs that have been marked as 'spent' in the wallet will be returned. If false, spent outputs will omitted from the results.
  • refresh_from_node - If true, the wallet will attempt to contact a node (via the NodeClient provided during wallet instantiation). If false, the results will contain output information that may be out-of-date (from the last time the wallet's output set was refreshed against the node).
  • tx_id - If Some(i), only return the outputs associated with the transaction log entry of id i.

Returns

  • (bool, Vec<OutputCommitMapping>) - A tuple:
  • The first bool element indicates whether the data was successfully refreshed from the node (note this may be false even if the refresh_from_node argument was set to true.
  • The second element contains a vector of OutputCommitMapping of which each element is a mapping between the wallet's internal OutputData and the Output commitment as identified in the chain's UTXO set

Example

Set up as in new method above.


let api_owner = Owner::new(wallet.clone());
let show_spent = false;
let update_from_node = true;
let tx_id = None;

let result = api_owner.retrieve_outputs(show_spent, update_from_node, tx_id);

if let Ok((was_updated, output_mappings)) = result {
    //...
}

pub fn retrieve_txs(
    &self,
    refresh_from_node: bool,
    tx_id: Option<u32>,
    tx_slate_id: Option<Uuid>
) -> Result<(bool, Vec<TxLogEntry>), Error>
[src]

Returns a list of Transaction Log Entries from the active account in the wallet.

Arguments

  • refresh_from_node - If true, the wallet will attempt to contact a node (via the NodeClient provided during wallet instantiation). If false, the results will contain transaction information that may be out-of-date (from the last time the wallet's output set was refreshed against the node).
  • tx_id - If Some(i), only return the transactions associated with the transaction log entry of id i.
  • tx_slate_id - If Some(uuid), only return transactions associated with the given Slate uuid.

Returns

  • (bool, Vec<TxLogEntry) - A tuple:
  • The first bool element indicates whether the data was successfully refreshed from the node (note this may be false even if the refresh_from_node argument was set to true.
  • The second element contains the set of retrieved TxLogEntries

Example

Set up as in new method above.


let api_owner = Owner::new(wallet.clone());
let update_from_node = true;
let tx_id = None;
let tx_slate_id = None;

// Return all TxLogEntries
let result = api_owner.retrieve_txs(update_from_node, tx_id, tx_slate_id);

if let Ok((was_updated, tx_log_entries)) = result {
    //...
}

pub fn retrieve_summary_info(
    &self,
    refresh_from_node: bool,
    minimum_confirmations: u64
) -> Result<(bool, WalletInfo), Error>
[src]

Returns summary information from the active account in the wallet.

Arguments

  • refresh_from_node - If true, the wallet will attempt to contact a node (via the NodeClient provided during wallet instantiation). If false, the results will contain transaction information that may be out-of-date (from the last time the wallet's output set was refreshed against the node).
  • minimum_confirmations - The minimum number of confirmations an output should have before it's included in the 'amount_currently_spendable' total

Returns

  • (bool, WalletInfo) - A tuple:
  • The first bool element indicates whether the data was successfully refreshed from the node (note this may be false even if the refresh_from_node argument was set to true.
  • The second element contains the Summary WalletInfo

Example

Set up as in new method above.


let mut api_owner = Owner::new(wallet.clone());
let update_from_node = true;
let minimum_confirmations=10;

// Return summary info for active account
let result = api_owner.retrieve_summary_info(update_from_node, minimum_confirmations);

if let Ok((was_updated, summary_info)) = result {
    //...
}

pub fn initiate_tx(&self, args: InitTxArgs) -> Result<Slate, Error>[src]

Initiates a new transaction as the sender, creating a new Slate object containing the sender's inputs, change outputs, and public signature data. This slate can then be sent to the recipient to continue the transaction via the Foreign API's receive_tx method.

When a transaction is created, the wallet must also lock inputs (and create unconfirmed outputs) corresponding to the transaction created in the slate, so that the wallet doesn't 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 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 to the recipient).

If the send_args InitTxSendArgs, of the args, field is Some, this function will attempt to perform a synchronous send to the recipient specified in the dest field according to the method field, and will also finalize and post the transaction if the finalize field is set.

Arguments

  • args - InitTxArgs, transaction initialization arguments. See struct documentation for further detail.

Returns

  • a result containing:
  • The transaction Slate, which can be forwarded to the recieving party by any means. Once the caller is relatively certain that the transaction has been sent to the recipient, the associated wallet transaction outputs should be locked via a call to tx_lock_outputs. This must be called before calling finalize_tx.
  • or libwallet::Error if an error is encountered.

Remarks

  • 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.

Example

Set up as in new method above.


let mut api_owner = Owner::new(wallet.clone());
// Attempt to create a transaction using the 'default' account
let args = InitTxArgs {
    src_acct_name: None,
    amount: 2_000_000_000,
    minimum_confirmations: 2,
    max_outputs: 500,
    num_change_outputs: 1,
    selection_strategy_is_use_all: true,
    message: Some("Have some Grins. Love, Yeastplume".to_owned()),
    ..Default::default()
};
let result = api_owner.initiate_tx(
    args,
);

if let Ok(slate) = result {
    // Send slate somehow
    // ...
    // Lock our outputs if we're happy the slate was (or is being) sent
    api_owner.tx_lock_outputs(&slate);
}

pub fn tx_lock_outputs(&self, slate: &Slate) -> Result<(), Error>[src]

Locks the outputs associated with the inputs to the transaction in the given Slate, making them unavailable for use in further transactions. This function is called by the sender, (or more generally, all parties who have put inputs into the transaction,) and must be called before the corresponding call to finalize_tx that completes the transaction.

Outputs will generally remain locked until they are removed from the chain, at which point they will become Spent. It is commonplace for transactions not to complete for various reasons over which a particular wallet has no control. For this reason, cancel_tx can be used to manually unlock outputs and return them to the Unspent state.

Arguments

  • slate - The transaction Slate. All elements in the input vector of the tx field that are found in the wallet's currently active account will be set to status Locked

Returns

Example

Set up as in new method above.


let mut api_owner = Owner::new(wallet.clone());
let args = InitTxArgs {
    src_acct_name: None,
    amount: 2_000_000_000,
    minimum_confirmations: 10,
    max_outputs: 500,
    num_change_outputs: 1,
    selection_strategy_is_use_all: true,
    message: Some("Remember to lock this when we're happy this is sent".to_owned()),
    ..Default::default()
};
let result = api_owner.initiate_tx(
    args,
);

if let Ok(slate) = result {
    // Send slate somehow
    // ...
    // Lock our outputs if we're happy the slate was (or is being) sent
    api_owner.tx_lock_outputs(&slate);
}

pub fn finalize_tx(&self, slate: &Slate) -> Result<Slate, Error>[src]

Finalizes a transaction, after all parties have filled in both rounds of Slate generation. This step adds all participants partial signatures to create the final signature, resulting in a final transaction that is ready to post to a node.

Note that this function DOES NOT POST the transaction to a node for validation. This is done in separately via the post_tx function.

This function also stores the final transaction in the user's wallet files for retrieval via the get_stored_tx function.

Arguments

  • slate - The transaction Slate. All participants must have filled in both rounds, and the sender should have locked their outputs (via the tx_lock_outputs function).

Returns

  • ``Ok(slate)` if successful, containing the new finalized slate.
  • or libwallet::Error if an error is encountered.

Example

Set up as in new method above.


let mut api_owner = Owner::new(wallet.clone());
let args = InitTxArgs {
    src_acct_name: None,
    amount: 2_000_000_000,
    minimum_confirmations: 10,
    max_outputs: 500,
    num_change_outputs: 1,
    selection_strategy_is_use_all: true,
    message: Some("Finalize this tx now".to_owned()),
    ..Default::default()
};
let result = api_owner.initiate_tx(
    args,
);

if let Ok(slate) = result {
    // Send slate somehow
    // ...
    // Lock our outputs if we're happy the slate was (or is being) sent
    let res = api_owner.tx_lock_outputs(&slate);
    //
    // Retrieve slate back from recipient
    //
    let res = api_owner.finalize_tx(&slate);
}

pub fn post_tx(&self, tx: &Transaction, fluff: bool) -> Result<(), Error>[src]

Posts a completed transaction to the listening node for validation and inclusion in a block for mining.

Arguments

  • tx - A completed Transaction, typically the tx field in the transaction Slate.

  • fluff - Instruct the node whether to use the Dandelion protocol when posting the transaction. If true, the node should skip the Dandelion phase and broadcast the transaction to all peers immediately. If false, the node will follow dandelion logic and initiate the stem phase.

Returns

Example

Set up as in new method above.


let mut api_owner = Owner::new(wallet.clone());
let args = InitTxArgs {
    src_acct_name: None,
    amount: 2_000_000_000,
    minimum_confirmations: 10,
    max_outputs: 500,
    num_change_outputs: 1,
    selection_strategy_is_use_all: true,
    message: Some("Post this tx".to_owned()),
    ..Default::default()
};
let result = api_owner.initiate_tx(
    args,
);

if let Ok(slate) = result {
    // Send slate somehow
    // ...
    // Lock our outputs if we're happy the slate was (or is being) sent
    let res = api_owner.tx_lock_outputs(&slate);
    //
    // Retrieve slate back from recipient
    //
    let res = api_owner.finalize_tx(&slate);
    let res = api_owner.post_tx(&slate.tx, true);
}

pub fn cancel_tx(
    &self,
    tx_id: Option<u32>,
    tx_slate_id: Option<Uuid>
) -> Result<(), Error>
[src]

Cancels a transaction. This entails:

  • Setting the transaction status to either TxSentCancelled or TxReceivedCancelled
  • Deleting all change outputs or recipient outputs associated with the transaction
  • Setting the status of all assocatied inputs from Locked to Spent so they can be used in new transactions.

Transactions can be cancelled by transaction log id or slate id (call with either set to Some, not both)

Arguments

  • tx_id - If present, cancel by the TxLogEntry id for the transaction.

  • tx_slate_id - If present, cancel by the Slate id.

Returns

Example

Set up as in new method above.


let mut api_owner = Owner::new(wallet.clone());
let args = InitTxArgs {
    src_acct_name: None,
    amount: 2_000_000_000,
    minimum_confirmations: 10,
    max_outputs: 500,
    num_change_outputs: 1,
    selection_strategy_is_use_all: true,
    message: Some("Cancel this tx".to_owned()),
    ..Default::default()
};
let result = api_owner.initiate_tx(
    args,
);

if let Ok(slate) = result {
    // Send slate somehow
    // ...
    // Lock our outputs if we're happy the slate was (or is being) sent
    let res = api_owner.tx_lock_outputs(&slate);
    //
    // We didn't get the slate back, or something else went wrong
    //
    let res = api_owner.cancel_tx(None, Some(slate.id.clone()));
}

pub fn get_stored_tx(
    &self,
    tx_log_entry: &TxLogEntry
) -> Result<Option<Transaction>, Error>
[src]

Retrieves the stored transaction associated with a TxLogEntry. Can be used even after the transaction has completed.

Arguments

Returns

Example

Set up as in new method above.


let api_owner = Owner::new(wallet.clone());
let update_from_node = true;
let tx_id = None;
let tx_slate_id = None;

// Return all TxLogEntries
let result = api_owner.retrieve_txs(update_from_node, tx_id, tx_slate_id);

if let Ok((was_updated, tx_log_entries)) = result {
    let stored_tx = api_owner.get_stored_tx(&tx_log_entries[0]).unwrap();
    //...
}

pub fn verify_slate_messages(&self, slate: &Slate) -> Result<(), Error>[src]

Verifies all messages in the slate match their public keys.

The optional messages themselves are part of the participant_data field within the slate. Messages are signed with the same key used to sign for the paricipant's inputs, and can thus be verified with the public key found in the public_blind_excess field. This function is a simple helper to returns whether all signatures in the participant data match their public keys.

Arguments

  • slate - The transaction Slate.

Returns

  • Ok(()) if successful and the signatures validate
  • or libwallet::Error if an error is encountered.

Example

Set up as in new method above.


let mut api_owner = Owner::new(wallet.clone());
let args = InitTxArgs {
    src_acct_name: None,
    amount: 2_000_000_000,
    minimum_confirmations: 10,
    max_outputs: 500,
    num_change_outputs: 1,
    selection_strategy_is_use_all: true,
    message: Some("Just verify messages".to_owned()),
    ..Default::default()
};
let result = api_owner.initiate_tx(
    args,
);

if let Ok(slate) = result {
    // Send slate somehow
    // ...
    // Lock our outputs if we're happy the slate was (or is being) sent
    let res = api_owner.tx_lock_outputs(&slate);
    //
    // Retrieve slate back from recipient
    //
    let res = api_owner.verify_slate_messages(&slate);
}

pub fn restore(&self) -> Result<(), Error>[src]

Scans the entire UTXO set from the node, creating outputs for each scanned output that matches the wallet's master seed. This function is intended to be called as part of a recovery process (either from BIP32 phrase or backup seed files,) and will error if the wallet is non-empty, i.e. contains any outputs at all.

This operation scans the entire chain, and is expected to be time intensive. It is imperative that no other processes should be trying to use the wallet at the same time this function is running.

A single TxLogEntry is created for all non-coinbase outputs discovered and restored during this process. A separate entry is created for each coinbase output.

Arguments

  • None

Returns

Example

Set up as in new method above.


let mut api_owner = Owner::new(wallet.clone());
let result = api_owner.restore();

if let Ok(_) = result {
    // Wallet outputs should be consistent with what's on chain
    // ...
}

pub fn check_repair(&self, delete_unconfirmed: bool) -> Result<(), Error>[src]

Scans the entire UTXO set from the node, identify which outputs belong to the given wallet update the wallet state to be consistent with what's currently in the UTXO set.

This function can be used to repair wallet state, particularly by restoring outputs that may be missing if the wallet owner has cancelled transactions locally that were then successfully posted to the chain.

This operation scans the entire chain, and is expected to be time intensive. It is imperative that no other processes should be trying to use the wallet at the same time this function is running.

When an output is found that doesn't exist in the wallet, a corresponding TxLogEntry is created.

Arguments

  • delete_unconfirmed - if false, the check_repair process will be non-destructive, and mostly limited to restoring missing outputs. It will leave unconfirmed transaction logs entries and unconfirmed outputs intact. If true, the process will unlock all locked outputs, restore all missing outputs, and mark any outputs that have been marked 'Spent' but are still in the UTXO set as 'Unspent' (as can happen during a fork). It will also attempt to cancel any transaction log entries associated with any locked outputs or outputs incorrectly marked 'Spent'. Note this completely removes all outstanding transactions, so users should be very aware what will happen if this flag is set. Note that if transactions/outputs are removed that later confirm on the chain, another call to this function will restore them.

Returns

Example

Set up as in new method above.


let mut api_owner = Owner::new(wallet.clone());
let result = api_owner.check_repair(
    false,
);

if let Ok(_) = result {
    // Wallet outputs should be consistent with what's on chain
    // ...
}

pub fn node_height(&self) -> Result<NodeHeightResult, Error>[src]

Retrieves the last known height known by the wallet. This is determined as follows:

  • If the wallet can successfully contact its configured node, the reported node height is returned, and the updated_from_node field in the response is true
  • If the wallet cannot contact the node, this function returns the maximum height of all outputs contained within the wallet, and the updated_from_node fields in the response is set to false.

Clients should generally ensure the updated_from_node field is returned as true before assuming the height for any operation.

Arguments

  • None

Returns

  • Ok with a NodeHeightResult if successful. If the height result was obtained from the configured node, updated_from_node will be set to true
  • or libwallet::Error if an error is encountered.

Example

Set up as in new method above.


let api_owner = Owner::new(wallet.clone());
let result = api_owner.node_height();

if let Ok(node_height_result) = result {
    if node_height_result.updated_from_node {
        //we can assume node_height_result.height is relatively safe to use

    }
    //...
}

Trait Implementations

impl<W: ?Sized, C, K> OwnerRpc for Owner<W, C, K> where
    W: WalletBackend<C, K>,
    C: NodeClient,
    K: Keychain, 
[src]

Auto Trait Implementations

impl<W: ?Sized, C, K> Send for Owner<W, C, K> where
    W: Send

impl<W: ?Sized, C, K> Sync for Owner<W, C, K> where
    W: Send

Blanket Implementations

impl<T, U> Into for T where
    U: From<T>, 
[src]

impl<T> From for T[src]

impl<T, U> TryFrom for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T> Borrow for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> BorrowMut for T where
    T: ?Sized
[src]

impl<T, U> TryInto for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

impl<T> Erased for T

impl<T> UnsafeAny for T where
    T: Any

impl<T> SafeBorrow for T where
    T: ?Sized

impl<T> Same for T

type Output = T

Should always be Self