Struct grin_wallet_api::Foreign
source · pub struct Foreign<'a, L, C, K>{
pub wallet_inst: Arc<Mutex<Box<dyn WalletInst<'a, L, C, K>>>>,
pub doctest_mode: bool,
/* private fields */
}
Expand description
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).
Fields§
§wallet_inst: Arc<Mutex<Box<dyn WalletInst<'a, L, C, K>>>>
Wallet instance
doctest_mode: bool
Flag to normalize some output during testing. Can mostly be ignored.
Implementations§
source§impl<'a, L, C, K> Foreign<'a, L, C, K>
impl<'a, L, C, K> Foreign<'a, L, C, K>
sourcepub fn new(
wallet_inst: Arc<Mutex<Box<dyn WalletInst<'a, L, C, K>>>>,
keychain_mask: Option<SecretKey>,
middleware: Option<ForeignCheckMiddleware>,
doctest_mode: bool
) -> Self
pub fn new( wallet_inst: Arc<Mutex<Box<dyn WalletInst<'a, L, C, K>>>>, keychain_mask: Option<SecretKey>, middleware: Option<ForeignCheckMiddleware>, doctest_mode: bool ) -> Self
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 theWalletBackend
trait.keychain_mask
- Mask value stored internally to use when calling a wallet whose seed has been XORed with a token value (such as when running the foreign and owner listeners in the same instance)- middleware - Option middleware which containts the NodeVersionInfo and can call a predefined function with the slate to check if the operation should continue
§Returns
- An instance of the ForeignApi holding a reference to the provided wallet
§Example
use grin_keychain as keychain;
use grin_util as util;
use grin_core;
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 grin_core::global;
use api::Foreign;
use config::WalletConfig;
use impls::{DefaultWalletImpl, DefaultLCProvider, HTTPNodeClient};
use libwallet::WalletInst;
global::set_local_chain_type(global::ChainTypes::AutomatedTesting);
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).unwrap();
// 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_foreign = Foreign::new(wallet.clone(), None, None, false);
// .. perform wallet operations
sourcepub fn set_tor_config(&self, tor_config: Option<TorConfig>)
pub fn set_tor_config(&self, tor_config: Option<TorConfig>)
sourcepub fn check_version(&self) -> Result<VersionInfo, Error>
pub fn check_version(&self) -> Result<VersionInfo, Error>
sourcepub fn build_coinbase(&self, block_fees: &BlockFees) -> Result<CbData, Error>
pub fn build_coinbase(&self, block_fees: &BlockFees) -> Result<CbData, Error>
Builds a new unconfirmed coinbase output in the wallet, generally for inclusion in a potential new block’s coinbase output during mining.
All potential coinbase outputs are created as ‘Unconfirmed’ with the coinbase flag set.
If a potential coinbase output is found on the chain after a wallet update, it status
is set to Unsent
and a Transaction Log Entry
will be created. Note the output will be unspendable until the coinbase maturity period
has expired.
§Arguments
block_fees
- ABlockFees
struct, set up as follows:
fees
- should contain the sum of all transaction fees included in the potential
block
height
- should contain the block height being mined
key_id
- can optionally contain the corresponding keychain ID in the wallet to use
to create the output’s blinding factor. If this is not provided, the next available key
id will be assigned
§Returns
Ok
(cb_data
)
if successful. This will contain the corresponding output, kernel and keyID used to create the coinbase output.- or
libwallet::Error
if an error is encountered.
§Example
Set up as in new
method above.
let mut api_foreign = Foreign::new(wallet.clone(), None, None, false);
let block_fees = BlockFees {
fees: 800000,
height: 234323,
key_id: None,
};
// Build a new coinbase output
let res = api_foreign.build_coinbase(&block_fees);
if let Ok(cb_data) = res {
// cb_data is populated with coinbase output info
// ...
}
sourcepub fn receive_tx(
&self,
slate: &Slate,
dest_acct_name: Option<&str>,
r_addr: Option<String>
) -> Result<Slate, Error>
pub fn receive_tx( &self, slate: &Slate, dest_acct_name: Option<&str>, r_addr: Option<String> ) -> Result<Slate, Error>
Recieve a tranaction created by another party, returning the modified
Slate
object, modified with
the recipient’s output for the transaction amount, and public signature data. This slate can
then be sent back to the sender to finalize the transaction via the
Owner API’s finalize_tx
method.
This function creates a single output for the full amount, set to a status of ‘Awaiting finalization’. It will remain in this state until the wallet finds the corresponding output on the chain, at which point it will become ‘Unspent’. The slate will be updated with the results of Signing round 1 and 2, adding the recipient’s public nonce, public excess value, and partial signature to the slate.
Also creates a corresponding Transaction Log Entry in the wallet’s transaction log.
§Arguments
slate
- The transactionSlate
. The slate should contain the results of the sender’s round 1 (e.g, public nonce and public excess value).dest_acct_name
- The name of the account into which the slate should be received. IfNone
, the default account is used.r_addr
- If included, attempt to send the slate back to the sender using the slatepack sync send (TOR). If providing this argument, check thestate
field of the slate to see if the sync_send was successful (it should be S3 if the synced send sent successfully).
§Returns
- a result containing:
Ok
(slate
)
if successful, containing the new slate updated with the recipient’s output and public signing information.- or
libwallet::Error
if an error is encountered.
§Remarks
- This method will store a partially completed transaction in the wallet’s transaction log.
§Example
Set up as in new method above.
let mut api_foreign = Foreign::new(wallet.clone(), None, None, false);
// . . .
// Obtain a sent slate somehow
let result = api_foreign.receive_tx(&slate, None, None);
if let Ok(slate) = result {
// Send back to recipient somehow
// ...
}
sourcepub fn finalize_tx(
&self,
slate: &Slate,
post_automatically: bool
) -> Result<Slate, Error>
pub fn finalize_tx( &self, slate: &Slate, post_automatically: bool ) -> Result<Slate, Error>
Finalizes a (standard or invoice) transaction initiated by this wallet’s Owner api. This step assumes the paying party has completed round 1 and 2 of slate creation, and added their partial signatures. This wallet will verify and add their partial sig, then create the finalized transaction, ready to post to a node.
This function posts to the node if the post_automatically
argument is sent to true. Posting can be 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 transactionSlate
. Thepost_automatically
- If true, post the finalized transaction to the configured listening node
§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 mut api_foreign = Foreign::new(wallet.clone(), None, None, false);
// . . .
// Issue the invoice tx via the owner API
let args = IssueInvoiceTxArgs {
amount: 10_000_000_000,
..Default::default()
};
let result = api_owner.issue_invoice_tx(None, args);
// If result okay, send to payer, who will apply the transaction via their
// owner API, then send back the slate
// ...
let slate = api_foreign.finalize_tx(&slate, true);
// if okay, then post via the owner API
Trait Implementations§
source§impl<'a, L, C, K> ForeignRpc for Foreign<'a, L, C, K>
impl<'a, L, C, K> ForeignRpc for Foreign<'a, L, C, K>
source§fn check_version(&self) -> Result<VersionInfo, Error>
fn check_version(&self) -> Result<VersionInfo, Error>
source§fn build_coinbase(
&self,
block_fees: &BlockFees
) -> Result<VersionedCoinbase, Error>
fn build_coinbase( &self, block_fees: &BlockFees ) -> Result<VersionedCoinbase, Error>
source§fn receive_tx(
&self,
in_slate: VersionedSlate,
dest_acct_name: Option<String>,
dest: Option<String>
) -> Result<VersionedSlate, Error>
fn receive_tx( &self, in_slate: VersionedSlate, dest_acct_name: Option<String>, dest: Option<String> ) -> Result<VersionedSlate, Error>
source§fn finalize_tx(&self, in_slate: VersionedSlate) -> Result<VersionedSlate, Error>
fn finalize_tx(&self, in_slate: VersionedSlate) -> Result<VersionedSlate, Error>
Auto Trait Implementations§
impl<'a, L, C, K> !Freeze for Foreign<'a, L, C, K>
impl<'a, L, C, K> !RefUnwindSafe for Foreign<'a, L, C, K>
impl<'a, L, C, K> Send for Foreign<'a, L, C, K>
impl<'a, L, C, K> Sync for Foreign<'a, L, C, K>
impl<'a, L, C, K> Unpin for Foreign<'a, L, C, K>
impl<'a, L, C, K> !UnwindSafe for Foreign<'a, L, C, K>
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> Instrument for T
impl<T> Instrument for T
source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
source§impl<T> Instrument for T
impl<T> Instrument for T
source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
source§impl<T> IntoEither for T
impl<T> IntoEither for T
source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more