mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-04-28 03:00:18 -04:00
deleted old client and adapter dirs, made singular and updated Cargo.toml
This commit is contained in:
20
Cargo.toml
20
Cargo.toml
@@ -101,26 +101,6 @@ features = ["bundled", "sqlcipher"]
|
||||
default = ["bitcoin", "secp256k1", "electrum-client"]
|
||||
sol = ["solana-sdk", "solana-client", "tokio-tungstenite", "tokio", "ed25519-dalek" ]
|
||||
|
||||
[[bin]]
|
||||
name = "lisp"
|
||||
path = "lisp/lisp.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "mimc"
|
||||
path = "src/old/mimc.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "mint-classic"
|
||||
path = "src/bin/mint-classic.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "spend-classic"
|
||||
path = "src/bin/spend-classic.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "tx"
|
||||
path = "src/bin/tx.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "gatewayd"
|
||||
path = "src/bin/gatewayd.rs"
|
||||
|
||||
@@ -1,415 +0,0 @@
|
||||
use crate::blockchain::{rocks::columns, Rocks, RocksColumn, Slab};
|
||||
use crate::cli::TransferParams;
|
||||
use crate::crypto::{
|
||||
load_params,
|
||||
merkle::{CommitmentTree, IncrementalWitness},
|
||||
merkle_node::MerkleNode,
|
||||
note::{EncryptedNote, Note},
|
||||
nullifier::Nullifier,
|
||||
save_params, setup_mint_prover, setup_spend_prover,
|
||||
};
|
||||
use crate::rpc::adapters::user_adapter::UserAdapter;
|
||||
use crate::rpc::jsonserver;
|
||||
use crate::serial::Encodable;
|
||||
use crate::serial::{deserialize, Decodable};
|
||||
use crate::service::{CashierClient, GatewayClient, GatewaySlabsSubscriber};
|
||||
use crate::state::{state_transition, ProgramState, StateUpdate};
|
||||
use crate::wallet::WalletPtr;
|
||||
use crate::{tx, Result};
|
||||
|
||||
use super::{ClientFailed, ClientResult};
|
||||
|
||||
use async_executor::Executor;
|
||||
use bellman::groth16;
|
||||
use bls12_381::Bls12;
|
||||
use log::*;
|
||||
use rusqlite::Connection;
|
||||
|
||||
use async_std::sync::{Arc, Mutex};
|
||||
use futures::FutureExt;
|
||||
use std::net::SocketAddr;
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub struct Client {
|
||||
state: State,
|
||||
secret: jubjub::Fr,
|
||||
mint_params: bellman::groth16::Parameters<Bls12>,
|
||||
spend_params: bellman::groth16::Parameters<Bls12>,
|
||||
gateway: GatewayClient,
|
||||
}
|
||||
|
||||
impl Client {
|
||||
pub fn new(
|
||||
secret: jubjub::Fr,
|
||||
rocks: Arc<Rocks>,
|
||||
gateway_addrs: (SocketAddr, SocketAddr),
|
||||
params_paths: (PathBuf, PathBuf),
|
||||
wallet_path: PathBuf,
|
||||
) -> Result<Self> {
|
||||
let slabstore = RocksColumn::<columns::Slabs>::new(rocks.clone());
|
||||
let merkle_roots = RocksColumn::<columns::MerkleRoots>::new(rocks.clone());
|
||||
let nullifiers = RocksColumn::<columns::Nullifiers>::new(rocks);
|
||||
|
||||
let mint_params_path = params_paths.0.to_str().unwrap_or("mint.params");
|
||||
let spend_params_path = params_paths.1.to_str().unwrap_or("spend.params");
|
||||
|
||||
// Auto create trusted ceremony parameters if they don't exist
|
||||
if !params_paths.0.exists() {
|
||||
let params = setup_mint_prover();
|
||||
save_params(mint_params_path, ¶ms)?;
|
||||
}
|
||||
if !params_paths.1.exists() {
|
||||
let params = setup_spend_prover();
|
||||
save_params(spend_params_path, ¶ms)?;
|
||||
}
|
||||
|
||||
// Load trusted setup parameters
|
||||
let (mint_params, mint_pvk) = load_params(mint_params_path)?;
|
||||
let (spend_params, spend_pvk) = load_params(spend_params_path)?;
|
||||
|
||||
let state = State {
|
||||
tree: CommitmentTree::empty(),
|
||||
merkle_roots,
|
||||
nullifiers,
|
||||
mint_pvk,
|
||||
spend_pvk,
|
||||
wallet_path,
|
||||
};
|
||||
|
||||
// create gateway client
|
||||
debug!(target: "CLIENT", "Creating GatewayClient");
|
||||
let gateway = GatewayClient::new(gateway_addrs.0, gateway_addrs.1, slabstore)?;
|
||||
|
||||
Ok(Self {
|
||||
state,
|
||||
secret,
|
||||
mint_params,
|
||||
spend_params,
|
||||
gateway,
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn start(&mut self) -> Result<()> {
|
||||
self.gateway.start().await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn connect_to_cashier(
|
||||
&mut self,
|
||||
executor: Arc<Executor<'_>>,
|
||||
wallet: WalletPtr,
|
||||
cashier_addr: SocketAddr,
|
||||
rpc_url: SocketAddr,
|
||||
) -> Result<()> {
|
||||
// create cashier client
|
||||
debug!(target: "CLIENT", "Creating cashier client");
|
||||
let mut cashier_client = CashierClient::new(cashier_addr)?;
|
||||
|
||||
// start subscribing
|
||||
debug!(target: "CLIENT", "Start subscriber");
|
||||
let gateway_slabs_sub: GatewaySlabsSubscriber =
|
||||
self.gateway.start_subscriber(executor.clone()).await?;
|
||||
|
||||
// channels to request transfer from adapter
|
||||
let (transfer_req_send, transfer_req_recv) = async_channel::unbounded::<TransferParams>();
|
||||
let (transfer_rep_send, transfer_rep_recv) = async_channel::unbounded::<ClientResult<()>>();
|
||||
|
||||
// channels to request deposit from adapter, send DRK key and receive BTC key
|
||||
let (deposit_req_send, deposit_req_recv) =
|
||||
async_channel::unbounded::<jubjub::SubgroupPoint>();
|
||||
let (deposit_rep_send, deposit_rep_recv) =
|
||||
async_channel::unbounded::<ClientResult<bitcoin::util::address::Address>>();
|
||||
|
||||
// channel to request withdraw from adapter, send BTC key and receive DRK key
|
||||
let (withdraw_req_send, withdraw_req_recv) = async_channel::unbounded::<String>();
|
||||
let (withdraw_rep_send, withdraw_rep_recv) =
|
||||
async_channel::unbounded::<ClientResult<jubjub::SubgroupPoint>>();
|
||||
|
||||
// start cashier_client
|
||||
cashier_client.start().await?;
|
||||
|
||||
let adapter = Arc::new(UserAdapter::new(
|
||||
wallet.clone(),
|
||||
(transfer_req_send.clone(), transfer_rep_recv.clone()),
|
||||
(deposit_req_send.clone(), deposit_rep_recv.clone()),
|
||||
(withdraw_req_send.clone(), withdraw_rep_recv.clone()),
|
||||
)?);
|
||||
|
||||
// start the rpc server
|
||||
debug!(target: "CLIENT", "Start RPC server");
|
||||
let io = Arc::new(adapter.handle_input()?);
|
||||
let _ = jsonserver::start(executor.clone(), rpc_url, io).await?;
|
||||
|
||||
self.futures_broker(
|
||||
&mut cashier_client,
|
||||
wallet,
|
||||
gateway_slabs_sub.clone(),
|
||||
deposit_req_recv.clone(),
|
||||
deposit_rep_send.clone(),
|
||||
withdraw_req_recv.clone(),
|
||||
withdraw_rep_send.clone(),
|
||||
transfer_req_recv.clone(),
|
||||
transfer_rep_send.clone(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn futures_broker(
|
||||
&mut self,
|
||||
cashier_client: &mut CashierClient,
|
||||
wallet: WalletPtr,
|
||||
gateway_slabs_sub: async_channel::Receiver<Slab>,
|
||||
deposit_req: async_channel::Receiver<jubjub::SubgroupPoint>,
|
||||
deposit_rep: async_channel::Sender<ClientResult<bitcoin::util::address::Address>>,
|
||||
withdraw_req: async_channel::Receiver<String>,
|
||||
withdraw_rep: async_channel::Sender<ClientResult<jubjub::SubgroupPoint>>,
|
||||
transfer_req: async_channel::Receiver<TransferParams>,
|
||||
transfer_rep: async_channel::Sender<ClientResult<()>>,
|
||||
) -> Result<()> {
|
||||
loop {
|
||||
futures::select! {
|
||||
slab = gateway_slabs_sub.recv().fuse() => {
|
||||
let slab = slab?;
|
||||
let tx = tx::Transaction::decode(&slab.get_payload()[..])?;
|
||||
let update = state_transition(&self.state, tx)?;
|
||||
self.state.apply(update, wallet.clone()).await?;
|
||||
}
|
||||
deposit_addr = deposit_req.recv().fuse() => {
|
||||
let btc_public = cashier_client.get_address(deposit_addr?).await.map_err(|err| {ClientFailed::from(err)});
|
||||
|
||||
if let Err(err) = btc_public {
|
||||
deposit_rep.send(Err(err)).await?;
|
||||
} else {
|
||||
if let Some(btc_addr) = btc_public? {
|
||||
deposit_rep.send(Ok(btc_addr)).await?;
|
||||
}else {
|
||||
deposit_rep.send(Err(ClientFailed::UnableToGetDepositAddress)).await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
withdraw_addr = withdraw_req.recv().fuse() => {
|
||||
let drk_public = cashier_client.withdraw(withdraw_addr?).await.map_err(|err| {ClientFailed::from(err)});
|
||||
|
||||
if let Err(err) = drk_public {
|
||||
withdraw_rep.send(Err(err)).await?;
|
||||
} else {
|
||||
if let Some(drk_addr) = drk_public? {
|
||||
withdraw_rep.send(Ok(drk_addr)).await?;
|
||||
}else {
|
||||
withdraw_rep.send(Err(ClientFailed::UnableToGetWithdrawAddress)).await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
transfer_params = transfer_req.recv().fuse() => {
|
||||
|
||||
let result = self.transfer(
|
||||
transfer_params?,
|
||||
wallet.clone()
|
||||
).await;
|
||||
|
||||
if let Err(err) = result {
|
||||
transfer_rep.send(Err(err)).await?;
|
||||
} else {
|
||||
transfer_rep.send(Ok(())).await?;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn transfer(
|
||||
&mut self,
|
||||
transfer_params: TransferParams,
|
||||
wallet: WalletPtr,
|
||||
) -> ClientResult<()> {
|
||||
let pub_key = transfer_params.pub_key;
|
||||
|
||||
let address = bs58::decode(pub_key.clone())
|
||||
.into_vec()
|
||||
.map_err(|_| ClientFailed::UnvalidAddress(pub_key.clone()))?;
|
||||
|
||||
let address: jubjub::SubgroupPoint =
|
||||
deserialize(&address).map_err(|_| ClientFailed::UnvalidAddress(pub_key))?;
|
||||
|
||||
let amount = transfer_params.amount;
|
||||
|
||||
if amount <= 0.0 {
|
||||
return Err(ClientFailed::UnvalidAmount(amount as u64));
|
||||
}
|
||||
|
||||
// check if there are coins
|
||||
let own_coins = wallet.get_own_coins()?;
|
||||
|
||||
if own_coins.is_empty() {
|
||||
return Err(ClientFailed::NotEnoughValue(0));
|
||||
}
|
||||
|
||||
let witness = &own_coins[0].3;
|
||||
let merkle_path = witness.path().unwrap();
|
||||
|
||||
// Construct a new tx spending the coin
|
||||
let builder = tx::TransactionBuilder {
|
||||
clear_inputs: vec![],
|
||||
inputs: vec![tx::TransactionBuilderInputInfo {
|
||||
merkle_path,
|
||||
secret: self.secret.clone(),
|
||||
note: own_coins[0].1.clone(),
|
||||
}],
|
||||
// We can add more outputs to this list.
|
||||
// The only constraint is that sum(value in) == sum(value out)
|
||||
outputs: vec![tx::TransactionBuilderOutputInfo {
|
||||
value: amount as u64,
|
||||
asset_id: 1,
|
||||
public: address,
|
||||
}],
|
||||
};
|
||||
// Build the tx
|
||||
let mut tx_data = vec![];
|
||||
{
|
||||
let tx = builder.build(&self.mint_params, &self.spend_params);
|
||||
tx.encode(&mut tx_data).expect("encode tx");
|
||||
}
|
||||
|
||||
// build slab from the transaction
|
||||
let slab = Slab::new(tx_data);
|
||||
|
||||
self.gateway.put_slab(slab).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn connect_to_subscriber(
|
||||
client: Arc<Mutex<Client>>,
|
||||
executor: Arc<Executor<'_>>,
|
||||
wallet: WalletPtr,
|
||||
) -> Result<()> {
|
||||
// start subscribing
|
||||
debug!(target: "CLIENT", "Start subscriber");
|
||||
let gateway_slabs_sub: GatewaySlabsSubscriber = client
|
||||
.lock()
|
||||
.await
|
||||
.gateway
|
||||
.start_subscriber(executor.clone())
|
||||
.await?;
|
||||
|
||||
loop {
|
||||
let slab = gateway_slabs_sub.recv().await?;
|
||||
let tx = tx::Transaction::decode(&slab.get_payload()[..])?;
|
||||
let mut client = client.lock().await;
|
||||
let update = state_transition(&client.state, tx)?;
|
||||
client.state.apply(update, wallet.clone()).await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct State {
|
||||
// The entire merkle tree state
|
||||
pub tree: CommitmentTree<MerkleNode>,
|
||||
// List of all previous and the current merkle roots
|
||||
// This is the hashed value of all the children.
|
||||
pub merkle_roots: RocksColumn<columns::MerkleRoots>,
|
||||
// Nullifiers prevent double spending
|
||||
pub nullifiers: RocksColumn<columns::Nullifiers>,
|
||||
// Mint verifying key used by ZK
|
||||
pub mint_pvk: groth16::PreparedVerifyingKey<Bls12>,
|
||||
// Spend verifying key used by ZK
|
||||
pub spend_pvk: groth16::PreparedVerifyingKey<Bls12>,
|
||||
// TODO: remove this
|
||||
wallet_path: PathBuf,
|
||||
}
|
||||
|
||||
impl ProgramState for State {
|
||||
fn is_valid_cashier_public_key(&self, _public: &jubjub::SubgroupPoint) -> bool {
|
||||
// TODO: use walletdb instead of connecting with sqlite directly
|
||||
let conn =
|
||||
Connection::open(self.wallet_path.clone()).expect("Connect to database");
|
||||
let mut stmt = conn
|
||||
.prepare("SELECT key_public FROM cashier WHERE key_public IN (SELECT key_public)")
|
||||
.expect("Generate statement");
|
||||
stmt.exists([1i32]).expect("Read database")
|
||||
// do actual validity check
|
||||
}
|
||||
|
||||
fn is_valid_merkle(&self, merkle_root: &MerkleNode) -> bool {
|
||||
self.merkle_roots
|
||||
.key_exist(*merkle_root)
|
||||
.expect("Check if the merkle_root valid")
|
||||
}
|
||||
|
||||
fn nullifier_exists(&self, nullifier: &Nullifier) -> bool {
|
||||
self.nullifiers
|
||||
.key_exist(nullifier.repr)
|
||||
.expect("Check if nullifier exists")
|
||||
}
|
||||
|
||||
// load from disk
|
||||
fn mint_pvk(&self) -> &groth16::PreparedVerifyingKey<Bls12> {
|
||||
&self.mint_pvk
|
||||
}
|
||||
|
||||
fn spend_pvk(&self) -> &groth16::PreparedVerifyingKey<Bls12> {
|
||||
&self.spend_pvk
|
||||
}
|
||||
}
|
||||
|
||||
impl State {
|
||||
pub async fn apply(&mut self, update: StateUpdate, wallet: WalletPtr) -> Result<()> {
|
||||
// Extend our list of nullifiers with the ones from the update
|
||||
for nullifier in update.nullifiers {
|
||||
self.nullifiers.put(nullifier, vec![] as Vec<u8>)?;
|
||||
}
|
||||
|
||||
// Update merkle tree and witnesses
|
||||
for (coin, enc_note) in update.coins.into_iter().zip(update.enc_notes.into_iter()) {
|
||||
// Add the new coins to the merkle tree
|
||||
let node = MerkleNode::from_coin(&coin);
|
||||
self.tree.append(node).expect("Append to merkle tree");
|
||||
|
||||
// Keep track of all merkle roots that have existed
|
||||
self.merkle_roots.put(self.tree.root(), vec![] as Vec<u8>)?;
|
||||
|
||||
// Also update all the coin witnesses
|
||||
for witness in wallet.witnesses.lock().await.iter_mut() {
|
||||
witness.append(node).expect("Append to witness");
|
||||
}
|
||||
|
||||
if let Some((note, secret)) = self.try_decrypt_note(wallet.clone(), enc_note).await {
|
||||
// We need to keep track of the witness for this coin.
|
||||
// This allows us to prove inclusion of the coin in the merkle tree with ZK.
|
||||
// Just as we update the merkle tree with every new coin, so we do the same with
|
||||
// the witness.
|
||||
|
||||
// Derive the current witness from the current tree.
|
||||
// This is done right after we add our coin to the tree (but before any other
|
||||
// coins are added)
|
||||
|
||||
// Make a new witness for this coin
|
||||
let witness = IncrementalWitness::from_tree(&self.tree);
|
||||
|
||||
wallet.put_own_coins(coin.clone(), note.clone(), witness.clone(), secret)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn try_decrypt_note(
|
||||
&self,
|
||||
wallet: WalletPtr,
|
||||
ciphertext: EncryptedNote,
|
||||
) -> Option<(Note, jubjub::Fr)> {
|
||||
let secret = wallet.get_private().ok()?;
|
||||
match ciphertext.decrypt(&secret) {
|
||||
Ok(note) => {
|
||||
// ... and return the decrypted note for this coin.
|
||||
return Some((note, secret.clone()));
|
||||
}
|
||||
Err(_) => {}
|
||||
}
|
||||
// We weren't able to decrypt the note with our key.
|
||||
None
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
use crate::wallet::CashierDb;
|
||||
use crate::Result;
|
||||
use async_std::sync::Arc;
|
||||
|
||||
pub struct CashierAdapter {
|
||||
pub wallet: Arc<CashierDb>,
|
||||
}
|
||||
|
||||
impl CashierAdapter {
|
||||
pub fn new(wallet: Arc<CashierDb>) -> Result<Self> {
|
||||
Ok(Self { wallet })
|
||||
}
|
||||
|
||||
pub fn handle_input(self: Arc<Self>) -> Result<jsonrpc_core::IoHandler> {
|
||||
let mut io = jsonrpc_core::IoHandler::new();
|
||||
io.add_sync_method("cashier_hello", |_| {
|
||||
Ok(jsonrpc_core::Value::String("hello world!".into()))
|
||||
});
|
||||
Ok(io)
|
||||
// let self1 = self.clone();
|
||||
// io.add_method("get_key", move |_| {
|
||||
// let self2 = self1.clone();
|
||||
// async move {
|
||||
// let pub_key = self2.get_key()?;
|
||||
// Ok(jsonrpc_core::Value::String(pub_key))
|
||||
// }
|
||||
// });
|
||||
|
||||
// let self1 = self.clone();
|
||||
// io.add_method("get_cash_public", move |_| {
|
||||
// let self2 = self1.clone();
|
||||
// async move {
|
||||
// let cash_key = self2.get_cash_public()?;
|
||||
// Ok(jsonrpc_core::Value::String(cash_key))
|
||||
// }
|
||||
// });
|
||||
|
||||
// let self1 = self.clone();
|
||||
// io.add_method("get_info", move |_| {
|
||||
// let self2 = self1.clone();
|
||||
// async move {
|
||||
// self2.get_info();
|
||||
// Ok(jsonrpc_core::Value::Null)
|
||||
// }
|
||||
// });
|
||||
|
||||
// let self1 = self.clone();
|
||||
// io.add_method("stop", move |_| {
|
||||
// let self2 = self1.clone();
|
||||
// async move {
|
||||
// self2.stop();
|
||||
// Ok(jsonrpc_core::Value::Null)
|
||||
// }
|
||||
// });
|
||||
// let self1 = self.clone();
|
||||
|
||||
// io.add_method("create_wallet", move |_| {
|
||||
// let self2 = self1.clone();
|
||||
// async move {
|
||||
// self2.init_db()?;
|
||||
// Ok(jsonrpc_core::Value::String(
|
||||
// "wallet creation successful".into(),
|
||||
// ))
|
||||
// }
|
||||
// });
|
||||
|
||||
// let self1 = self.clone();
|
||||
// io.add_method("key_gen", move |_| {
|
||||
// let self2 = self1.clone();
|
||||
// async move {
|
||||
// self2.key_gen()?;
|
||||
// Ok(jsonrpc_core::Value::String(
|
||||
// "key generation successful".into(),
|
||||
// ))
|
||||
// }
|
||||
// });
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
pub mod cashier_adapter;
|
||||
pub mod user_adapter;
|
||||
|
||||
pub use user_adapter::{UserAdapter, UserAdapterPtr};
|
||||
@@ -1,245 +0,0 @@
|
||||
use crate::cli::{TransferParams, WithdrawParams};
|
||||
use crate::client::ClientResult;
|
||||
use crate::serial::serialize;
|
||||
use crate::service::btc::PubAddress;
|
||||
use crate::wallet::WalletDb;
|
||||
use crate::{Error, Result};
|
||||
|
||||
use log::*;
|
||||
|
||||
use async_std::sync::Arc;
|
||||
|
||||
pub type UserAdapterPtr = Arc<UserAdapter>;
|
||||
|
||||
pub type TransferChannel = (
|
||||
async_channel::Sender<TransferParams>,
|
||||
async_channel::Receiver<ClientResult<()>>,
|
||||
);
|
||||
|
||||
pub type DepositChannel = (
|
||||
async_channel::Sender<jubjub::SubgroupPoint>,
|
||||
async_channel::Receiver<ClientResult<bitcoin::util::address::Address>>,
|
||||
);
|
||||
|
||||
pub type WithdrawChannel = (
|
||||
async_channel::Sender<String>,
|
||||
async_channel::Receiver<ClientResult<jubjub::SubgroupPoint>>,
|
||||
);
|
||||
|
||||
pub struct UserAdapter {
|
||||
pub wallet: Arc<WalletDb>,
|
||||
transfer_channel: TransferChannel,
|
||||
deposit_channel: DepositChannel,
|
||||
withdraw_channel: WithdrawChannel,
|
||||
}
|
||||
|
||||
impl UserAdapter {
|
||||
pub fn new(
|
||||
wallet: Arc<WalletDb>,
|
||||
transfer_channel: TransferChannel,
|
||||
deposit_channel: DepositChannel,
|
||||
withdraw_channel: WithdrawChannel,
|
||||
) -> Result<Self> {
|
||||
debug!(target: "RPC USER ADAPTER", "new() [CREATING NEW WALLET]");
|
||||
Ok(Self {
|
||||
wallet,
|
||||
transfer_channel,
|
||||
deposit_channel,
|
||||
withdraw_channel,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn handle_input(self: Arc<Self>) -> Result<jsonrpc_core::IoHandler> {
|
||||
let mut io = jsonrpc_core::IoHandler::new();
|
||||
|
||||
io.add_sync_method("say_hello", |_| {
|
||||
Ok(jsonrpc_core::Value::String("hello world!".into()))
|
||||
});
|
||||
|
||||
let self1 = self.clone();
|
||||
io.add_method("get_key", move |_| {
|
||||
let self2 = self1.clone();
|
||||
async move {
|
||||
let pub_key = self2.get_key()?;
|
||||
Ok(jsonrpc_core::Value::String(pub_key))
|
||||
}
|
||||
});
|
||||
|
||||
let self1 = self.clone();
|
||||
io.add_method("get_cash_public", move |_| {
|
||||
let self2 = self1.clone();
|
||||
async move {
|
||||
let cash_key = self2.get_cash_public()?;
|
||||
Ok(jsonrpc_core::Value::String(cash_key))
|
||||
}
|
||||
});
|
||||
|
||||
let self1 = self.clone();
|
||||
io.add_method("get_info", move |_| {
|
||||
let self2 = self1.clone();
|
||||
async move {
|
||||
self2.get_info();
|
||||
Ok(jsonrpc_core::Value::Null)
|
||||
}
|
||||
});
|
||||
|
||||
let self1 = self.clone();
|
||||
io.add_method("stop", move |_| {
|
||||
let self2 = self1.clone();
|
||||
async move {
|
||||
self2.stop();
|
||||
Ok(jsonrpc_core::Value::Null)
|
||||
}
|
||||
});
|
||||
let self1 = self.clone();
|
||||
|
||||
io.add_method("create_wallet", move |_| {
|
||||
let self2 = self1.clone();
|
||||
async move {
|
||||
self2.init_db()?;
|
||||
Ok(jsonrpc_core::Value::String(
|
||||
"wallet creation successful".into(),
|
||||
))
|
||||
}
|
||||
});
|
||||
|
||||
let self1 = self.clone();
|
||||
io.add_method("key_gen", move |_| {
|
||||
let self2 = self1.clone();
|
||||
async move {
|
||||
self2.key_gen()?;
|
||||
Ok(jsonrpc_core::Value::String(
|
||||
"key generation successful".into(),
|
||||
))
|
||||
}
|
||||
});
|
||||
|
||||
let self1 = self.clone();
|
||||
io.add_method("deposit", move |_| {
|
||||
let self2 = self1.clone();
|
||||
async move {
|
||||
let btckey = self2.deposit().await?;
|
||||
Ok(jsonrpc_core::Value::String(format!("{}", btckey)))
|
||||
}
|
||||
});
|
||||
|
||||
let self1 = self.clone();
|
||||
io.add_method("transfer", move |params: jsonrpc_core::Params| {
|
||||
let self2 = self1.clone();
|
||||
async move {
|
||||
let parsed: TransferParams = params.parse().unwrap();
|
||||
let amount = parsed.amount.clone();
|
||||
let address = parsed.pub_key.clone();
|
||||
self2.transfer(parsed).await?;
|
||||
Ok(jsonrpc_core::Value::String(format!(
|
||||
"transfered {} DRK to {}",
|
||||
amount, address
|
||||
)))
|
||||
}
|
||||
});
|
||||
|
||||
let self1 = self.clone();
|
||||
io.add_method("withdraw", move |params: jsonrpc_core::Params| {
|
||||
let self2 = self1.clone();
|
||||
async move {
|
||||
let parsed: WithdrawParams = params.parse().unwrap();
|
||||
let amount = parsed.amount;
|
||||
let address = self2.withdraw(parsed).await?;
|
||||
Ok(jsonrpc_core::Value::String(format!(
|
||||
"sending {} dbtc to provided address for withdrawing: {} ",
|
||||
amount, address
|
||||
)))
|
||||
}
|
||||
});
|
||||
|
||||
Ok(io)
|
||||
}
|
||||
|
||||
pub fn init_db(&self) -> Result<()> {
|
||||
debug!(target: "RPC USER ADAPTER", "init_db() [START]");
|
||||
self.wallet.init_db()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn key_gen(&self) -> Result<()> {
|
||||
debug!(target: "RPC USER ADAPTER", "key_gen() [START]");
|
||||
let (public, private) = self.wallet.key_gen();
|
||||
debug!(target: "RPC USER ADAPTER", "Created keypair...");
|
||||
debug!(target: "RPC USER ADAPTER", "Attempting to write to database...");
|
||||
self.wallet.put_keypair(public, private)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_key(&self) -> Result<String> {
|
||||
debug!(target: "RPC USER ADAPTER", "get_key() [START]");
|
||||
let key_public = self.wallet.get_public()?;
|
||||
let bs58_address = bs58::encode(serialize(&key_public)).into_string();
|
||||
Ok(bs58_address)
|
||||
}
|
||||
|
||||
pub fn get_cash_public(&self) -> Result<String> {
|
||||
debug!(target: "RPC USER ADAPTER", "get_cash_public() [START]");
|
||||
let cashier_public = self.wallet.get_cashier_public()?;
|
||||
let bs58_address = bs58::encode(serialize(&cashier_public)).into_string();
|
||||
Ok(bs58_address)
|
||||
}
|
||||
|
||||
pub async fn deposit(&self) -> Result<PubAddress> {
|
||||
debug!(target: "RPC USER ADAPTER", "deposit: START");
|
||||
let (public, private) = self.wallet.key_gen();
|
||||
self.wallet.put_keypair(public, private)?;
|
||||
let dkey = self.wallet.get_public()?;
|
||||
self.deposit_channel.0.send(dkey).await?;
|
||||
self.deposit_channel
|
||||
.1
|
||||
.recv()
|
||||
.await?
|
||||
.map_err(|err| Error::from(err))
|
||||
}
|
||||
|
||||
async fn transfer(&self, transfer_params: TransferParams) -> Result<()> {
|
||||
self.transfer_channel.0.send(transfer_params).await?;
|
||||
|
||||
self.transfer_channel
|
||||
.1
|
||||
.recv()
|
||||
.await?
|
||||
.map_err(|err| Error::from(err))
|
||||
}
|
||||
|
||||
async fn withdraw(&self, withdraw_params: WithdrawParams) -> Result<String> {
|
||||
debug!(target: "RPC USER ADAPTER", "withdraw: START");
|
||||
self.withdraw_channel
|
||||
.0
|
||||
.send(withdraw_params.pub_key)
|
||||
.await?;
|
||||
|
||||
// receive dbtc address
|
||||
let key = self
|
||||
.withdraw_channel
|
||||
.1
|
||||
.recv()
|
||||
.await?
|
||||
.map_err(|err| Error::from(err))?;
|
||||
|
||||
// transfer the dbtc
|
||||
let key = bs58::encode(serialize(&key)).into_string();
|
||||
let mut transfer_params = TransferParams::new();
|
||||
transfer_params.pub_key = key.clone();
|
||||
transfer_params.amount = withdraw_params.amount;
|
||||
self.transfer_channel.0.send(transfer_params).await?;
|
||||
self.transfer_channel
|
||||
.1
|
||||
.recv()
|
||||
.await?
|
||||
.map_err(|err| Error::from(err))?;
|
||||
|
||||
Ok(key)
|
||||
}
|
||||
|
||||
pub fn get_info(&self) {}
|
||||
|
||||
pub fn say_hello(&self) {}
|
||||
|
||||
pub fn stop(&self) {}
|
||||
}
|
||||
Reference in New Issue
Block a user