2020-09-28 06:18:50 +00:00
|
|
|
use anyhow::{bail, Result};
|
|
|
|
use async_trait::async_trait;
|
|
|
|
use monero::{Address, Network, PrivateKey};
|
|
|
|
use monero_harness::Monero;
|
|
|
|
use std::str::FromStr;
|
2020-09-29 05:36:50 +00:00
|
|
|
use xmr_btc::monero::{
|
2020-10-08 00:27:54 +00:00
|
|
|
Amount, CheckTransfer, CreateWalletForOutput, PrivateViewKey, PublicKey, PublicViewKey,
|
|
|
|
Transfer, TransferProof, TxHash,
|
2020-09-29 05:36:50 +00:00
|
|
|
};
|
2020-09-28 06:18:50 +00:00
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct AliceWallet<'c>(pub &'c Monero<'c>);
|
|
|
|
|
|
|
|
#[async_trait]
|
|
|
|
impl Transfer for AliceWallet<'_> {
|
|
|
|
async fn transfer(
|
|
|
|
&self,
|
|
|
|
public_spend_key: PublicKey,
|
|
|
|
public_view_key: PublicViewKey,
|
|
|
|
amount: Amount,
|
|
|
|
) -> Result<(TransferProof, Amount)> {
|
|
|
|
let destination_address =
|
|
|
|
Address::standard(Network::Mainnet, public_spend_key, public_view_key.into());
|
|
|
|
|
|
|
|
let res = self
|
|
|
|
.0
|
2020-09-29 05:36:50 +00:00
|
|
|
.transfer_from_alice(amount.as_piconero(), &destination_address.to_string())
|
2020-09-28 06:18:50 +00:00
|
|
|
.await?;
|
|
|
|
|
|
|
|
let tx_hash = TxHash(res.tx_hash);
|
|
|
|
let tx_key = PrivateKey::from_str(&res.tx_key)?;
|
|
|
|
|
|
|
|
let fee = Amount::from_piconero(res.fee);
|
|
|
|
|
2020-09-29 05:36:50 +00:00
|
|
|
Ok((TransferProof::new(tx_hash, tx_key), fee))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[async_trait]
|
2020-10-08 00:27:54 +00:00
|
|
|
impl CreateWalletForOutput for AliceWallet<'_> {
|
|
|
|
async fn create_and_load_wallet_for_output(
|
2020-09-29 05:36:50 +00:00
|
|
|
&self,
|
|
|
|
private_spend_key: PrivateKey,
|
|
|
|
private_view_key: PrivateViewKey,
|
|
|
|
) -> Result<()> {
|
|
|
|
let public_spend_key = PublicKey::from_private_key(&private_spend_key);
|
|
|
|
let public_view_key = PublicKey::from_private_key(&private_view_key.into());
|
|
|
|
|
|
|
|
let address = Address::standard(Network::Mainnet, public_spend_key, public_view_key);
|
|
|
|
|
|
|
|
let _ = self
|
|
|
|
.0
|
|
|
|
.alice_wallet_rpc_client()
|
|
|
|
.generate_from_keys(
|
|
|
|
&address.to_string(),
|
|
|
|
&private_spend_key.to_string(),
|
|
|
|
&PrivateKey::from(private_view_key).to_string(),
|
|
|
|
)
|
|
|
|
.await?;
|
|
|
|
|
|
|
|
Ok(())
|
2020-09-28 06:18:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct BobWallet<'c>(pub &'c Monero<'c>);
|
|
|
|
|
|
|
|
#[async_trait]
|
|
|
|
impl CheckTransfer for BobWallet<'_> {
|
|
|
|
async fn check_transfer(
|
|
|
|
&self,
|
|
|
|
public_spend_key: PublicKey,
|
|
|
|
public_view_key: PublicViewKey,
|
|
|
|
transfer_proof: TransferProof,
|
|
|
|
amount: Amount,
|
|
|
|
) -> Result<()> {
|
|
|
|
let address = Address::standard(Network::Mainnet, public_spend_key, public_view_key.into());
|
|
|
|
|
|
|
|
let cli = self.0.bob_wallet_rpc_client();
|
|
|
|
|
|
|
|
let res = cli
|
|
|
|
.check_tx_key(
|
2020-09-29 05:36:50 +00:00
|
|
|
&String::from(transfer_proof.tx_hash()),
|
|
|
|
&transfer_proof.tx_key().to_string(),
|
2020-09-28 06:18:50 +00:00
|
|
|
&address.to_string(),
|
|
|
|
)
|
|
|
|
.await?;
|
|
|
|
|
|
|
|
if res.received != u64::from(amount) {
|
|
|
|
bail!(
|
|
|
|
"tx_lock doesn't pay enough: expected {:?}, got {:?}",
|
|
|
|
res.received,
|
|
|
|
amount
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[async_trait]
|
2020-10-08 00:27:54 +00:00
|
|
|
impl CreateWalletForOutput for BobWallet<'_> {
|
|
|
|
async fn create_and_load_wallet_for_output(
|
2020-09-28 06:18:50 +00:00
|
|
|
&self,
|
|
|
|
private_spend_key: PrivateKey,
|
|
|
|
private_view_key: PrivateViewKey,
|
|
|
|
) -> Result<()> {
|
|
|
|
let public_spend_key = PublicKey::from_private_key(&private_spend_key);
|
|
|
|
let public_view_key = PublicKey::from_private_key(&private_view_key.into());
|
|
|
|
|
|
|
|
let address = Address::standard(Network::Mainnet, public_spend_key, public_view_key);
|
|
|
|
|
|
|
|
let _ = self
|
|
|
|
.0
|
|
|
|
.bob_wallet_rpc_client()
|
|
|
|
.generate_from_keys(
|
|
|
|
&address.to_string(),
|
|
|
|
&private_spend_key.to_string(),
|
|
|
|
&PrivateKey::from(private_view_key).to_string(),
|
|
|
|
)
|
|
|
|
.await?;
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|