[][src]Struct grin_wallet_api::Owner

pub struct Owner<L, C, K> where
    L: WalletLCProvider<'static, C, K> + 'static,
    C: NodeClient + 'static,
    K: Keychain + 'static, 
{ pub wallet_inst: Arc<Mutex<Box<dyn WalletInst<'static, L, C, K>>>>, pub doctest_mode: bool, pub shared_key: Arc<Mutex<Option<SecretKey>>>, pub updater_running: Arc<AtomicBool>, // 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_inst: Arc<Mutex<Box<dyn WalletInst<'static, L, C, K>>>>

contain all methods to manage the wallet

doctest_mode: bool

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

shared_key: Arc<Mutex<Option<SecretKey>>>

Share ECDH key

updater_running: Arc<AtomicBool>

Stop state for update thread

Implementations

impl<L, C, K> Owner<L, C, K> where
    L: WalletLCProvider<'static, C, K> + 'static,
    C: NodeClient,
    K: Keychain, 
[src]

pub fn new(
    wallet_inst: Arc<Mutex<Box<dyn WalletInst<'static, L, C, K>>>>,
    custom_channel: Option<Sender<StatusMessage>>
) -> 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
  • custom_channel - A custom MPSC Tx/Rx pair to capture status updates 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, ZeroingString};

use api::Owner;
use config::WalletConfig;
use impls::{DefaultWalletImpl, DefaultLCProvider, HTTPNodeClient};
use libwallet::WalletInst;

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

// impls::DefaultWalletImpl is provided for convenience in instantiating the wallet
// It contains the LMDBBackend, DefaultLCProvider (lifecycle) and ExtKeychain used
// by the reference wallet implementation.
// These traits can be replaced with alternative implementations if desired

let mut wallet = Box::new(DefaultWalletImpl::<'static, HTTPNodeClient>::new(node_client.clone()).unwrap())
    as Box<WalletInst<'static, DefaultLCProvider<HTTPNodeClient, ExtKeychain>, HTTPNodeClient, ExtKeychain>>;

// Wallet LifeCycle Provider provides all functions init wallet and work with seeds, etc...
let lc = wallet.lc_provider().unwrap();

// The top level wallet directory should be set manually (in the reference implementation,
// this is provided in the WalletConfig)
let _ = lc.set_top_level_directory(&wallet_config.data_file_dir);

// Wallet must be opened with the password (TBD)
let pw = ZeroingString::from("wallet_password");
lc.open_wallet(None, pw, false, false);

// All wallet functions operate on an Arc::Mutex to allow multithreading where needed
let mut wallet = Arc::new(Mutex::new(wallet));

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

pub fn set_tor_config(&self, tor_config: Option<TorConfig>)[src]

Set the TOR configuration for this instance of the OwnerAPI, used during init_send_tx when send args are present and a TOR address is specified

Arguments

Returns

  • Nothing

pub fn accounts(
    &self,
    keychain_mask: Option<&SecretKey>
) -> 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.

Arguments

  • keychain_mask - Wallet secret mask to XOR against the stored wallet seed before using, if being used.

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(), None);

let result = api_owner.accounts(None);

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

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

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

Arguments

  • keychain_mask - Wallet secret mask to XOR against the stored wallet seed before using, if being used.
  • 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(), None);

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

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

pub fn set_active_account(
    &self,
    keychain_mask: Option<&SecretKey>,
    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

  • keychain_mask - Wallet secret mask to XOR against the stored wallet seed before using, if being used.
  • 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(), None);

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

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

pub fn retrieve_outputs(
    &self,
    keychain_mask: Option<&SecretKey>,
    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

  • keychain_mask - Wallet secret mask to XOR against the stored wallet seed before using, if being used.
  • 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). Note this setting is ignored if the updater process is running via a call to start_updater
  • 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(), None);
let show_spent = false;
let update_from_node = true;
let tx_id = None;

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

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

pub fn retrieve_txs(
    &self,
    keychain_mask: Option<&SecretKey>,
    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

  • keychain_mask - Wallet secret mask to XOR against the stored wallet seed before using, if being used.
  • 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). Note this setting is ignored if the updater process is running via a call to start_updater
  • 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(), None);
let update_from_node = true;
let tx_id = None;
let tx_slate_id = None;

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

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

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

Returns summary information from the active account in the wallet.

Arguments

  • keychain_mask - Wallet secret mask to XOR against the stored wallet seed before using, if being used.
  • 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). Note this setting is ignored if the updater process is running via a call to start_updater
  • 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(), None);
let update_from_node = true;
let minimum_confirmations=10;

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

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

pub fn init_send_tx(
    &self,
    keychain_mask: Option<&SecretKey>,
    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

  • keychain_mask - Wallet secret mask to XOR against the stored wallet seed before using, if being used.
  • 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(), None);
// 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: false,
    message: Some("Have some Grins. Love, Yeastplume".to_owned()),
    ..Default::default()
};
let result = api_owner.init_send_tx(
    None,
    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(None, &slate, 0);
}

pub fn issue_invoice_tx(
    &self,
    keychain_mask: Option<&SecretKey>,
    args: IssueInvoiceTxArgs
) -> Result<Slate, Error>
[src]

Issues a new invoice transaction slate, essentially a request for payment. The slate created by this function will contain the amount, an output for the amount, as well as round 1 of singature creation complete. The slate should then be send to the payer, who should add their inputs and signature data and return the slate via the Foreign API's finalize_invoice_tx method.

Arguments

  • keychain_mask - Wallet secret mask to XOR against the stored wallet seed before using, if being used.
  • args - IssueInvoiceTxArgs, invoice transaction initialization arguments. See struct documentation for further detail.

Returns

  • ``Ok(slate)` if successful, containing the updated 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(), None);

let args = IssueInvoiceTxArgs {
    amount: 60_000_000_000,
    ..Default::default()
};
let result = api_owner.issue_invoice_tx(None, args);

if let Ok(slate) = result {
    // if okay, send to the payer to add their inputs
    // . . .
}

pub fn process_invoice_tx(
    &self,
    keychain_mask: Option<&SecretKey>,
    slate: &Slate,
    args: InitTxArgs
) -> Result<Slate, Error>
[src]

Processes an invoice tranaction created by another party, essentially a request for payment. The incoming slate should contain a requested amount, an output created by the invoicer convering the amount, and part 1 of signature creation completed. This function will add inputs equalling the amount + fees, as well as perform round 1 and 2 of signature creation.

Callers should note that no prompting of the user will be done by this function it is up to the caller to present the request for payment to the user and verify that payment should go ahead.

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

Arguments

  • keychain_mask - Wallet secret mask to XOR against the stored wallet seed before using, if being used.
  • slate - The transaction Slate. The payer should have filled in round 1 and 2.
  • args - InitTxArgs, transaction initialization arguments. See struct documentation for further detail.

Returns

  • ``Ok(slate)` if successful, containing the updated 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(), None);

// . . .
// The slate has been recieved from the invoicer, somehow
let args = InitTxArgs {
    src_acct_name: None,
    amount: slate.amount,
    minimum_confirmations: 2,
    max_outputs: 500,
    num_change_outputs: 1,
    selection_strategy_is_use_all: false,
    ..Default::default()
};

let result = api_owner.process_invoice_tx(None, &slate, args);

if let Ok(slate) = result {
// If result okay, send back to the invoicer
// . . .
}

pub fn tx_lock_outputs(
    &self,
    keychain_mask: Option<&SecretKey>,
    slate: &Slate,
    participant_id: usize
) -> 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

  • keychain_mask - Wallet secret mask to XOR against the stored wallet seed before using, if being used.
  • slate - The transaction Slate. All
  • participant_id - The participant id, generally 0 for the party putting in funds, 1 for the party receiving. 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(), None);
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: false,
    message: Some("Remember to lock this when we're happy this is sent".to_owned()),
    ..Default::default()
};
let result = api_owner.init_send_tx(
    None,
    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(None, &slate, 0);
}

pub fn finalize_tx(
    &self,
    keychain_mask: Option<&SecretKey>,
    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

  • keychain_mask - Wallet secret mask to XOR against the stored wallet seed before using, if being used.
  • 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(), None);
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: false,
    message: Some("Finalize this tx now".to_owned()),
    ..Default::default()
};
let result = api_owner.init_send_tx(
    None,
    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(None, &slate, 0);
    //
    // Retrieve slate back from recipient
    //
    let res = api_owner.finalize_tx(None, &slate);
}

pub fn post_tx(
    &self,
    keychain_mask: Option<&SecretKey>,
    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

  • keychain_mask - Wallet secret mask to XOR against the stored wallet seed before using, if being used.
  • 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(), None);
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: false,
    message: Some("Post this tx".to_owned()),
    ..Default::default()
};
let result = api_owner.init_send_tx(
    None,
    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(None, &slate, 0);
    //
    // Retrieve slate back from recipient
    //
    let res = api_owner.finalize_tx(None, &slate);
    let res = api_owner.post_tx(None, &slate.tx, true);
}

pub fn cancel_tx(
    &self,
    keychain_mask: Option<&SecretKey>,
    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

  • keychain_mask - Wallet secret mask to XOR against the stored wallet seed before using, if being used.

  • 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(), None);
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: false,
    message: Some("Cancel this tx".to_owned()),
    ..Default::default()
};
let result = api_owner.init_send_tx(
    None,
    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(None, &slate, 0);
    //
    // We didn't get the slate back, or something else went wrong
    //
    let res = api_owner.cancel_tx(None, None, Some(slate.id.clone()));
}

pub fn get_stored_tx(
    &self,
    keychain_mask: Option<&SecretKey>,
    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

  • keychain_mask - Wallet secret mask to XOR against the stored wallet seed before using, if being used.
  • tx_log_entry - A TxLogEntry

Returns

Example

Set up as in new method above.


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

// Return all TxLogEntries
let result = api_owner.retrieve_txs(None, 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(None, &tx_log_entries[0]).unwrap();
    //...
}

pub fn verify_slate_messages(
    &self,
    keychain_mask: Option<&SecretKey>,
    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

  • keychain_mask - Wallet secret mask to XOR against the stored wallet seed before using, if being used.
  • 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(), None);
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: false,
    message: Some("Just verify messages".to_owned()),
    ..Default::default()
};
let result = api_owner.init_send_tx(
    None,
    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(None, &slate, 0);
    //
    // Retrieve slate back from recipient
    //
    let res = api_owner.verify_slate_messages(None, &slate);
}

pub fn scan(
    &self,
    keychain_mask: Option<&SecretKey>,
    start_height: Option<u64>,
    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

  • keychain_mask - Wallet secret mask to XOR against the stored wallet seed before using, if being used.
  • start_height - If provided, the height of the first block from which to start scanning. The scan will start from block 1 if this is not provided.
  • delete_unconfirmed - if false, the scan 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(), None);
let result = api_owner.scan(
    None,
    Some(20000),
    false,
);

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

pub fn node_height(
    &self,
    keychain_mask: Option<&SecretKey>
) -> 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

  • keychain_mask - Wallet secret mask to XOR against the stored wallet seed before using, if being used.

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(), None);
let result = api_owner.node_height(None);

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

    }
    //...
}

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

Retrieve the top-level directory for the wallet. This directory should contain the grin-wallet.toml file and the wallet_data directory that contains the wallet seed + data files. Future versions of the wallet API will support multiple wallets within the top level directory.

The top level directory defaults to (in order of precedence):

  1. The current directory, from which grin-wallet or the main process was run, if it contains a grin-wallet.toml file.
  2. ~/.grin// otherwise

Arguments

  • None

Returns

  • Ok with a String value representing the full path to the top level wallet dierctory
  • or libwallet::Error if an error is encountered.

Example

Set up as in new method above.


let api_owner = Owner::new(wallet.clone(), None);
let result = api_owner.get_top_level_directory();

if let Ok(dir) = result {
    println!("Top level directory is: {}", dir);
    //...
}

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

Set the top-level directory for the wallet. This directory can be empty, and will be created during a subsequent calls to create_config

Set get_top_level_directory for a description of the top level directory and default paths.

Arguments

  • dir: The new top-level directory path (either relative to current directory or absolute.

Returns

Example

Set up as in new method above.


let dir = "path/to/wallet/dir";


let api_owner = Owner::new(wallet.clone(), None);
let result = api_owner.set_top_level_directory(dir);

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

pub fn create_config(
    &self,
    chain_type: &ChainTypes,
    wallet_config: Option<WalletConfig>,
    logging_config: Option<LoggingConfig>,
    tor_config: Option<TorConfig>
) -> Result<(), Error>
[src]

Create a grin-wallet.toml configuration file in the top-level directory for the specified chain type. A custom WalletConfig and/or grin LoggingConfig may optionally be provided, otherwise defaults will be used.

Paths in the configuration file will be updated to reflect the top level directory, so path-related values in the optional configuration structs will be ignored.

Arguments

  • chain_type: The chain type to use in creation of the configuration file. This can be
    • AutomatedTesting
    • UserTesting
    • Floonet
    • Mainnet

Returns

Example

Set up as in new method above.


use grin_core::global::ChainTypes;

let dir = "path/to/wallet/dir";


let api_owner = Owner::new(wallet.clone(), None);
let _ = api_owner.set_top_level_directory(dir);

let result = api_owner.create_config(&ChainTypes::Mainnet, None, None, None);

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

pub fn create_wallet(
    &self,
    name: Option<&str>,
    mnemonic: Option<ZeroingString>,
    mnemonic_length: u32,
    password: ZeroingString
) -> Result<(), Error>
[src]

Creates a new wallet seed and empty wallet database in the wallet_data directory of the top level directory.

Paths in the configuration file will be updated to reflect the top level directory, so path-related values in the optional configuration structs will be ignored.

The wallet files must not already exist, and ~The grin-wallet.toml file must exist in the top level directory (can be created via a call to create_config)

Arguments

  • name: Reserved for future use, use None for the time being.
  • mnemonic: If present, restore the wallet seed from the given mnemonic instead of creating a new random seed.
  • mnemonic_length: Desired length of mnemonic in bytes (16 or 32, either 12 or 24 words). Use 0 if mnemonic isn't being used.
  • password: The password used to encrypt/decrypt the wallet.seed file

Returns

Example

Set up as in new method above.


use grin_core::global::ChainTypes;

// note that the WalletInst struct does not necessarily need to contain an
// instantiated wallet

let dir = "path/to/wallet/dir";

let api_owner = Owner::new(wallet.clone(), None);
let _ = api_owner.set_top_level_directory(dir);

// Create configuration
let result = api_owner.create_config(&ChainTypes::Mainnet, None, None, None);

// create new wallet wirh random seed
let pw = ZeroingString::from("my_password");
let result = api_owner.create_wallet(None, None, 0, pw);

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

pub fn open_wallet(
    &self,
    name: Option<&str>,
    password: ZeroingString,
    use_mask: bool
) -> Result<Option<SecretKey>, Error>
[src]

Opens a wallet, populating the internal keychain with the encrypted seed, and optionally returning a keychain_mask token to the caller to provide in all future calls. If using a mask, the seed will be stored in-memory XORed against the keychain_mask, and will not be useable if the mask is not provided.

Arguments

  • name: Reserved for future use, use None for the time being.
  • password: The password to use to open the wallet a new random seed.
  • use_mask: Whether to create and return a mask which much be provided in all future API calls.

Returns

Example

Set up as in new method above.


use grin_core::global::ChainTypes;

// note that the WalletInst struct does not necessarily need to contain an
// instantiated wallet
let dir = "path/to/wallet/dir";

let api_owner = Owner::new(wallet.clone(), None);
let _ = api_owner.set_top_level_directory(dir);

// Create configuration
let result = api_owner.create_config(&ChainTypes::Mainnet, None, None, None);

// create new wallet wirh random seed
let pw = ZeroingString::from("my_password");
let _ = api_owner.create_wallet(None, None, 0, pw.clone());

let result = api_owner.open_wallet(None, pw, true);

if let Ok(m) = result {
    // use this mask in all subsequent calls
    let mask = m;
}

pub fn close_wallet(&self, name: Option<&str>) -> Result<(), Error>[src]

Close a wallet, removing the master seed from memory.

Arguments

  • name: Reserved for future use, use None for the time being.

Returns

Example

Set up as in new method above.


use grin_core::global::ChainTypes;

// Set up as above

let res = api_owner.close_wallet(None);

if let Ok(_) = res {
    // ...
}

pub fn get_mnemonic(
    &self,
    name: Option<&str>,
    password: ZeroingString
) -> Result<ZeroingString, Error>
[src]

Return the BIP39 mnemonic for the given wallet. This function will decrypt the wallet's seed file with the given password, and thus does not need the wallet to be open.

Arguments

  • name: Reserved for future use, use None for the time being.
  • password: The password used to encrypt the seed file.

Returns

  • Ok(BIP-39 mneminc) if successful
  • or libwallet::Error if an error is encountered.

Example

Set up as in new method above.


use grin_core::global::ChainTypes;

// Set up as above

let pw = ZeroingString::from("my_password");
let res = api_owner.get_mnemonic(None, pw);

if let Ok(mne) = res {
    // ...
}

pub fn change_password(
    &self,
    name: Option<&str>,
    old: ZeroingString,
    new: ZeroingString
) -> Result<(), Error>
[src]

Changes a wallet's password, meaning the old seed file is decrypted with the old password, and a new seed file is created with the same mnemonic and encrypted with the new password.

This function temporarily backs up the old seed file until a test-decryption of the new file is confirmed to contain the same seed as the original seed file, at which point the backup is deleted. If this operation fails for an unknown reason, the backup file will still exist in the wallet's data directory encrypted with the old password.

Arguments

  • name: Reserved for future use, use None for the time being.
  • old: The password used to encrypt the existing seed file (i.e. old password)
  • new: The password to be used to encrypt the new seed file

Returns

Example

Set up as in new method above.


use grin_core::global::ChainTypes;

// Set up as above

let old = ZeroingString::from("my_password");
let new = ZeroingString::from("new_password");
let res = api_owner.change_password(None, old, new);

if let Ok(mne) = res {
    // ...
}

pub fn delete_wallet(&self, name: Option<&str>) -> Result<(), Error>[src]

Deletes a wallet, removing the config file, seed file and all data files. Obviously, use with extreme caution and plenty of user warning

Highly recommended that the wallet be explicitly closed first via the close_wallet function.

Arguments

  • name: Reserved for future use, use None for the time being.

Returns

Example

Set up as in new method above.


use grin_core::global::ChainTypes;

// Set up as above

let res = api_owner.delete_wallet(None);

if let Ok(_) = res {
    // ...
}

pub fn start_updater(
    &self,
    keychain_mask: Option<&SecretKey>,
    frequency: Duration
) -> Result<(), Error>
[src]

Starts a background wallet update thread, which performs the wallet update process automatically at the frequency specified.

The updater process is as follows:

  • Reconcile the wallet outputs against the node's current UTXO set, confirming transactions if needs be.
  • Look up transactions by kernel in cases where it's necessary (for instance, when there are no change outputs for a transaction and transaction status can't be inferred from the output state.
  • Incrementally perform a scan of the UTXO set, correcting outputs and transactions where their local state differs from what's on-chain. The wallet stores the last position scanned, and will scan back 100 blocks worth of UTXOs on each update, to correct any differences due to forks or otherwise.

Note that an update process can take a long time, particularly when the entire UTXO set is being scanned for correctness. The wallet status can be determined by calling the get_updater_messages.

Arguments

  • keychain_mask - Wallet secret mask to XOR against the stored wallet seed before using, if being used.
  • frequency: The frequency at which to call the update process. Note this is time elapsed since the last successful update process. If calling via the JSON-RPC api, this represents milliseconds.

Returns

Example

Set up as in new method above.


use grin_core::global::ChainTypes;

use std::time::Duration;

// Set up as above

let res = api_owner.start_updater(None, Duration::from_secs(60));

if let Ok(_) = res {
  // ...
}

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

Stops the background update thread. If the updater is currently updating, the thread will stop after the next update

Arguments

  • None

Returns

Example

Set up as in new method above.


use grin_core::global::ChainTypes;

use std::time::Duration;

// Set up as above

let res = api_owner.start_updater(None, Duration::from_secs(60));

if let Ok(_) = res {
  // ...
}

let res = api_owner.stop_updater();

pub fn get_updater_messages(
    &self,
    count: usize
) -> Result<Vec<StatusMessage>, Error>
[src]

Retrieve messages from the updater thread, up to count number of messages. The resulting array will be ordered newest messages first. The updater will store a maximum of 10,000 messages, after which it will start removing the oldest messages as newer ones are created.

Messages retrieved via this method are removed from the internal queue, so calling this function at a specified interval should result in a complete message history.

Arguments

  • count - The number of messages to retrieve.

Returns

Example

Set up as in new method above.


use grin_core::global::ChainTypes;

use std::time::Duration;

// Set up as above

let res = api_owner.start_updater(None, Duration::from_secs(60));

let messages = api_owner.get_updater_messages(10000);

if let Ok(_) = res {
  // ...
}

pub fn get_public_proof_address(
    &self,
    keychain_mask: Option<&SecretKey>,
    derivation_index: u32
) -> Result<DalekPublicKey, Error>
[src]

Retrieve the public proof "addresses" associated with the active account at the given derivation path.

In this case, an "address" means a Dalek ed25519 public key corresponding to a private key derived as follows:

e.g. The default parent account is at

m/0/0

With output blinding factors created as

m/0/0/0 m/0/0/1 etc...

The corresponding public address derivation path would be at:

m/0/1

With addresses created as:

m/0/1/0 m/0/1/1 etc...

Note that these addresses correspond to the public keys used in the addresses of TOR hidden services configured by the wallet listener.

Arguments

  • keychain_mask - Wallet secret mask to XOR against the stored wallet seed before using, if
  • derivation_index - The index along the derivation path to retrieve an address for

Returns

  • Ok with a DalekPublicKey representing the address
  • or libwallet::Error if an error is encountered.

Example

Set up as in new method above.


use grin_core::global::ChainTypes;

use std::time::Duration;

// Set up as above

let res = api_owner.get_public_proof_address(None, 0);

if let Ok(_) = res {
  // ...
}

pub fn proof_address_from_onion_v3(
    &self,
    address_v3: &str
) -> Result<DalekPublicKey, Error>
[src]

Helper function to convert an Onion v3 address to a payment proof address (essentially exctacting and verifying the public key)

Arguments

  • address_v3 - An V3 Onion address

Returns

  • Ok(DalekPublicKey) representing the public key associated with the address, if successful
  • or libwallet::Error if an error is encountered or the address provided is invalid

Example

Set up as in new method above.


use grin_core::global::ChainTypes;

use std::time::Duration;

// Set up as above

let res = api_owner.proof_address_from_onion_v3(
 "2a6at2obto3uvkpkitqp4wxcg6u36qf534eucbskqciturczzc5suyid"
);

if let Ok(_) = res {
  // ...
}

let res = api_owner.stop_updater();

pub fn retrieve_payment_proof(
    &self,
    keychain_mask: Option<&SecretKey>,
    refresh_from_node: bool,
    tx_id: Option<u32>,
    tx_slate_id: Option<Uuid>
) -> Result<PaymentProof, Error>
[src]

Returns a single, exportable PaymentProof from a completed transaction within the wallet.

The transaction must have been created with a payment proof, and the transaction must be complete in order for a payment proof to be returned. Either the tx_id or tx_slate_id argument must be provided, or the function will return an error.

Arguments

  • keychain_mask - Wallet secret mask to XOR against the stored wallet seed before using, if being used.
  • 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). Note this setting is ignored if the updater process is running via a call to start_updater
  • tx_id - If Some(i) return the proof associated with the transaction with id i
  • tx_slate_id - If Some(uuid), return the proof associated with the transaction with the given uuid

Returns

Example

Set up as in new method above.


let api_owner = Owner::new(wallet.clone(), None);
let update_from_node = true;
let tx_id = None;
let tx_slate_id = Some(Uuid::parse_str("0436430c-2b02-624c-2032-570501212b00").unwrap());

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

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

pub fn verify_payment_proof(
    &self,
    keychain_mask: Option<&SecretKey>,
    proof: &PaymentProof
) -> Result<(bool, bool), Error>
[src]

Verifies a PaymentProof This process entails:

  • Ensuring the kernel identified by the proof's stored excess commitment exists in the kernel set
  • Reproducing the signed message amount|kernel_commitment|sender_address
  • Validating the proof's recipient_sig against the message using the recipient's address as the public key and
  • Validating the proof's sender_sig against the message using the senders's address as the public key

This function also checks whether the sender or recipient address belongs to the currently open wallet, and returns 2 booleans indicating whether the address belongs to the sender and whether the address belongs to the recipient respectively

Arguments

  • keychain_mask - Wallet secret mask to XOR against the stored wallet seed before using, if being used.
  • proof A PaymentProof)

Returns

  • Ok((bool, bool)) if the proof is valid. The first boolean indicates whether the sender address belongs to this wallet, the second whether the recipient address belongs to this wallet
  • or libwallet::Error if an error is encountered or the proof is not present or complete

Example

Set up as in new method above.


let api_owner = Owner::new(wallet.clone(), None);
let update_from_node = true;
let tx_id = None;
let tx_slate_id = Some(Uuid::parse_str("0436430c-2b02-624c-2032-570501212b00").unwrap());

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

// The proof will likely be exported as JSON to be provided to another party

if let Ok(p) = result {
    let valid = api_owner.verify_payment_proof(None, &p);
    if let Ok(_) = valid {
      //...
    }
}

Trait Implementations

impl<'a, L, C, K> OwnerRpc for Owner<L, C, K> where
    L: WalletLCProvider<'static, C, K>,
    C: NodeClient + 'static,
    K: Keychain + 'static, 
[src]

impl<L, C, K> OwnerRpcS for Owner<L, C, K> where
    L: WalletLCProvider<'static, C, K>,
    C: NodeClient + 'static,
    K: Keychain + 'static, 
[src]

Auto Trait Implementations

impl<L, C, K> !RefUnwindSafe for Owner<L, C, K>

impl<L, C, K> Send for Owner<L, C, K>

impl<L, C, K> Sync for Owner<L, C, K>

impl<L, C, K> Unpin for Owner<L, C, K>

impl<L, C, K> !UnwindSafe for Owner<L, C, K>

Blanket Implementations

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

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

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

impl<T> Erased for T

impl<T> From<T> for T[src]

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

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

impl<T> Same<T> for T

type Output = T

Should always be Self

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

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> 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> UnsafeAny for T where
    T: Any

impl<V, T> VZip<V> for T where
    V: MultiLane<T>,