mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-04-28 03:00:18 -04:00
move parsing params functions and NetworkName enum to src/util.rs
This commit is contained in:
@@ -20,8 +20,8 @@ use drk::{
|
||||
rpcserver::{listen_and_serve, RequestHandler, RpcServerConfig},
|
||||
},
|
||||
serial::{deserialize, serialize},
|
||||
service::{bridge, bridge::Bridge, NetworkName},
|
||||
util::{expand_path, generate_id, join_config_path},
|
||||
service::{bridge, bridge::Bridge},
|
||||
util::{expand_path, generate_id, join_config_path, NetworkName},
|
||||
wallet::{CashierDb, WalletDb},
|
||||
Error, Result,
|
||||
};
|
||||
@@ -392,9 +392,7 @@ impl Cashierd {
|
||||
|
||||
let main_keypair: Keypair;
|
||||
|
||||
let main_keypairs = self
|
||||
.cashier_wallet
|
||||
.get_main_keys(&NetworkName::Solana)?;
|
||||
let main_keypairs = self.cashier_wallet.get_main_keys(&NetworkName::Solana)?;
|
||||
|
||||
if main_keypairs.is_empty() {
|
||||
main_keypair = Keypair::new();
|
||||
@@ -416,9 +414,8 @@ impl Cashierd {
|
||||
// NOTE bitcoin is not implemented yet
|
||||
//let _main_keypair: BitcoinKeys;
|
||||
|
||||
let _main_keypairs = self
|
||||
.cashier_wallet
|
||||
.get_main_keys(&NetworkName::Bitcoin)?;
|
||||
let _main_keypairs =
|
||||
self.cashier_wallet.get_main_keys(&NetworkName::Bitcoin)?;
|
||||
// if main_keypairs.is_empty() {
|
||||
// //main_keypair = BitcoinKeys::new(bitcoin::network::constants::Network::Testnet)?;
|
||||
// } else {
|
||||
|
||||
@@ -5,7 +5,6 @@ use serde_json::{json, Value};
|
||||
|
||||
use async_std::sync::{Arc, Mutex};
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
//use std::sync::Arc;
|
||||
|
||||
use drk::{
|
||||
@@ -18,17 +17,15 @@ use drk::{
|
||||
rpcserver::{listen_and_serve, RequestHandler, RpcServerConfig},
|
||||
},
|
||||
serial::{deserialize, serialize},
|
||||
service::NetworkName,
|
||||
util::{expand_path, generate_id, join_config_path},
|
||||
util::{expand_path, join_config_path, parse_network, parse_wrapped_token, search_id},
|
||||
wallet::WalletDb,
|
||||
Error, Result,
|
||||
Result,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Darkfid {
|
||||
config: DarkfidConfig,
|
||||
wallet: Arc<WalletDb>,
|
||||
tokenlist: Value,
|
||||
client: Arc<Mutex<Client>>,
|
||||
}
|
||||
|
||||
@@ -65,9 +62,7 @@ impl Darkfid {
|
||||
config.wallet_password.clone(),
|
||||
)?;
|
||||
debug!(target: "DARKFID", "INIT WALLET WITH PATH {}", config.wallet_path);
|
||||
// TODO: FIXME
|
||||
let file_contents = std::fs::read_to_string("token/solanatokenlist.json")?;
|
||||
let tokenlist: Value = serde_json::from_str(&file_contents)?;
|
||||
|
||||
let rocks = Rocks::new(expand_path(&config.database_path.clone())?.as_path())?;
|
||||
|
||||
let client = Client::new(
|
||||
@@ -87,7 +82,6 @@ impl Darkfid {
|
||||
Ok(Self {
|
||||
config,
|
||||
wallet,
|
||||
tokenlist,
|
||||
client,
|
||||
})
|
||||
}
|
||||
@@ -153,8 +147,8 @@ impl Darkfid {
|
||||
let symbol = symbol.unwrap();
|
||||
|
||||
let result: Result<Value> = async {
|
||||
let token_id = self.search_id(symbol)?;
|
||||
Ok(token_id)
|
||||
let token_id = search_id(symbol)?;
|
||||
Ok(json!(token_id))
|
||||
}
|
||||
.await;
|
||||
|
||||
@@ -164,20 +158,6 @@ impl Darkfid {
|
||||
}
|
||||
}
|
||||
|
||||
fn search_id(&self, symbol: &str) -> Result<Value> {
|
||||
debug!(target: "DARKFID", "SEARCHING FOR {}", symbol);
|
||||
let tokens = self.tokenlist["tokens"]
|
||||
.as_array()
|
||||
.ok_or_else(|| Error::TokenParseError)?;
|
||||
for item in tokens {
|
||||
if item["symbol"] == symbol.to_uppercase() {
|
||||
let address = item["address"].clone();
|
||||
return Ok(address);
|
||||
}
|
||||
}
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
// --> {""method": "features", "params": []}
|
||||
// <-- {"result": { "network": ["btc", "sol"] } }
|
||||
async fn features(&self, id: Value, _params: Value) -> JsonResult {
|
||||
@@ -229,7 +209,7 @@ impl Darkfid {
|
||||
|
||||
let network = network.as_str().unwrap();
|
||||
|
||||
let token_id = match self.parse_network(&network, &token) {
|
||||
let token_id = match parse_network(&network, &token) {
|
||||
Ok(t) => t,
|
||||
Err(_e) => {
|
||||
debug!(target: "DARKFID", "TOKEN ID IS ERR");
|
||||
@@ -348,7 +328,7 @@ impl Darkfid {
|
||||
let amount = amount.as_f64().unwrap();
|
||||
|
||||
let result: Result<()> = async {
|
||||
let token_id = self.parse_wrapped_token(token)?;
|
||||
let token_id = parse_wrapped_token(token)?;
|
||||
let address = bs58::decode(&address).into_vec()?;
|
||||
let address: jubjub::SubgroupPoint = deserialize(&address)?;
|
||||
self.client
|
||||
@@ -365,75 +345,6 @@ impl Darkfid {
|
||||
Err(err) => JsonResult::Err(jsonerr(InternalError, Some(err.to_string()), json!(id))),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_wrapped_token(&self, token: &str) -> Result<jubjub::Fr> {
|
||||
match token.to_lowercase().as_str() {
|
||||
"sol" => {
|
||||
let id = "So11111111111111111111111111111111111111112";
|
||||
let token_id = generate_id(id)?;
|
||||
Ok(token_id)
|
||||
}
|
||||
"btc" => Err(Error::TokenParseError),
|
||||
tkn => {
|
||||
let id = self.symbol_to_id(tkn)?;
|
||||
let token_id = generate_id(id.as_str().unwrap())?;
|
||||
Ok(token_id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_network(&self, network: &str, token: &str) -> Result<Value> {
|
||||
match NetworkName::from_str(network)? {
|
||||
NetworkName::Solana => match token.to_lowercase().as_str() {
|
||||
"solana" | "sol" => {
|
||||
let token_id = "So11111111111111111111111111111111111111112";
|
||||
Ok(json!(token_id))
|
||||
}
|
||||
tkn => {
|
||||
let id = self.symbol_to_id(tkn)?;
|
||||
Ok(id)
|
||||
}
|
||||
},
|
||||
NetworkName::Bitcoin => Err(Error::NetworkParseError),
|
||||
}
|
||||
}
|
||||
|
||||
// BTC has 8 decimals
|
||||
// SOL uses conversion function soltolamport()
|
||||
// or there are decimals in the token info
|
||||
// TODO: how to organize these functions more logically w less repetition?
|
||||
fn parse_params(&self, network: &str, token: &str, amount: u64 ) -> Result<Value> {
|
||||
match NetworkName::from_str(network)? {
|
||||
NetworkName::Solana => match token {
|
||||
"solana" | "sol" => {
|
||||
let token_id = "So11111111111111111111111111111111111111112";
|
||||
let amount_in_apo: u64 = amount * 10 ^ 8;
|
||||
Ok(json![(token_id, amount_in_apo)])
|
||||
}
|
||||
tkn => {
|
||||
let token_id = self.symbol_to_id(tkn)?;
|
||||
let amount_in_apo: u64 = amount * 10 ^ 8;
|
||||
Ok(json![(token_id, amount_in_apo)])
|
||||
}
|
||||
},
|
||||
NetworkName::Bitcoin => Err(Error::NetworkParseError),
|
||||
}
|
||||
}
|
||||
|
||||
fn symbol_to_id(&self, token: &str) -> Result<Value> {
|
||||
let vec: Vec<char> = token.chars().collect();
|
||||
let mut counter = 0;
|
||||
for c in vec {
|
||||
if c.is_alphabetic() {
|
||||
counter += 1;
|
||||
}
|
||||
}
|
||||
if counter == token.len() {
|
||||
self.search_id(token)
|
||||
} else {
|
||||
Ok(json!(token))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_std::main]
|
||||
|
||||
@@ -22,7 +22,7 @@ async fn run() -> Result<()> {
|
||||
println!("main keypair {:?}", main_keypair.to_bytes());
|
||||
println!("main pubkey {}", main_keypair.pubkey().to_string());
|
||||
|
||||
let network = drk::service::NetworkName::Solana;
|
||||
let network = drk::util::NetworkName::Solana;
|
||||
|
||||
let sol_client = SolClient::new(serialize(&main_keypair), "devnet").await?;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::{Error, Result};
|
||||
use super::NetworkName;
|
||||
use crate::util::NetworkName;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use futures::stream::FuturesUnordered;
|
||||
|
||||
@@ -15,53 +15,5 @@ pub use sol::{SolClient, SolFailed, SolResult};
|
||||
|
||||
pub use gateway::{GatewayClient, GatewayService, GatewaySlabsSubscriber};
|
||||
|
||||
use crate::serial::{Decodable, Encodable};
|
||||
use crate::Result;
|
||||
use std::str::FromStr;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
|
||||
pub enum NetworkName {
|
||||
Solana,
|
||||
Bitcoin,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for NetworkName {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Solana => {
|
||||
write!(f, "Solana")
|
||||
}
|
||||
Self::Bitcoin => {
|
||||
write!(f, "Bitcoin")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for NetworkName {
|
||||
type Err = crate::Error;
|
||||
|
||||
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
||||
match s.to_lowercase().as_str() {
|
||||
"sol" | "solana" => Ok(NetworkName::Solana),
|
||||
"btc" | "bitcoin" => Ok(NetworkName::Bitcoin),
|
||||
_ => Err(crate::Error::NotSupportedNetwork),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for NetworkName {
|
||||
fn encode<S: std::io::Write>(&self, s: S) -> Result<usize> {
|
||||
let name = self.to_string();
|
||||
let len = name.encode(s)?;
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for NetworkName {
|
||||
fn decode<D: std::io::Read>(mut d: D) -> Result<Self> {
|
||||
let name: String = Decodable::decode(&mut d)?;
|
||||
let name = NetworkName::from_str(&name)?;
|
||||
Ok(name)
|
||||
}
|
||||
}
|
||||
|
||||
146
src/util.rs
146
src/util.rs
@@ -1,11 +1,13 @@
|
||||
use crate::{
|
||||
serial::{deserialize, serialize, Decodable, Encodable},
|
||||
Error, Result,
|
||||
};
|
||||
|
||||
use log::debug;
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use crate::{
|
||||
serial::{deserialize, serialize},
|
||||
Result,
|
||||
};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str::FromStr;
|
||||
|
||||
pub fn expand_path(path: &str) -> Result<PathBuf> {
|
||||
let ret: PathBuf;
|
||||
@@ -37,6 +39,54 @@ pub fn join_config_path(file: &Path) -> Result<PathBuf> {
|
||||
Ok(path)
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
|
||||
pub enum NetworkName {
|
||||
Solana,
|
||||
Bitcoin,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for NetworkName {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Solana => {
|
||||
write!(f, "Solana")
|
||||
}
|
||||
Self::Bitcoin => {
|
||||
write!(f, "Bitcoin")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for NetworkName {
|
||||
type Err = crate::Error;
|
||||
|
||||
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
||||
match s.to_lowercase().as_str() {
|
||||
"sol" | "solana" => Ok(NetworkName::Solana),
|
||||
"btc" | "bitcoin" => Ok(NetworkName::Bitcoin),
|
||||
_ => Err(crate::Error::NotSupportedNetwork),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for NetworkName {
|
||||
fn encode<S: std::io::Write>(&self, s: S) -> Result<usize> {
|
||||
let name = self.to_string();
|
||||
let len = name.encode(s)?;
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for NetworkName {
|
||||
fn decode<D: std::io::Read>(mut d: D) -> Result<Self> {
|
||||
let name: String = Decodable::decode(&mut d)?;
|
||||
let name = NetworkName::from_str(&name)?;
|
||||
Ok(name)
|
||||
}
|
||||
}
|
||||
|
||||
// here we hash the alphanumeric token ID. if it fails, we change the last 4 bytes and hash it
|
||||
// again, and keep repeating until it works.
|
||||
pub fn generate_id(tkn_str: &str) -> Result<jubjub::Fr> {
|
||||
@@ -69,6 +119,92 @@ pub fn generate_id(tkn_str: &str) -> Result<jubjub::Fr> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_wrapped_token(token: &str) -> Result<jubjub::Fr> {
|
||||
match token.to_lowercase().as_str() {
|
||||
"sol" => {
|
||||
let id = "So11111111111111111111111111111111111111112";
|
||||
let token_id = generate_id(id)?;
|
||||
Ok(token_id)
|
||||
}
|
||||
"btc" => Err(Error::TokenParseError),
|
||||
tkn => {
|
||||
let id = symbol_to_id(tkn)?;
|
||||
let token_id = generate_id(&id)?;
|
||||
Ok(token_id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_network(network: &str, token: &str) -> Result<String> {
|
||||
match NetworkName::from_str(network)? {
|
||||
NetworkName::Solana => match token.to_lowercase().as_str() {
|
||||
"solana" | "sol" => {
|
||||
let token_id = "So11111111111111111111111111111111111111112";
|
||||
Ok(token_id.to_string())
|
||||
}
|
||||
tkn => {
|
||||
let id = symbol_to_id(tkn)?;
|
||||
Ok(id)
|
||||
}
|
||||
},
|
||||
NetworkName::Bitcoin => Err(Error::NetworkParseError),
|
||||
}
|
||||
}
|
||||
|
||||
// BTC has 8 decimals
|
||||
// SOL uses conversion function soltolamport()
|
||||
// or there are decimals in the token info
|
||||
// TODO: how to organize these functions more logically w less repetition?
|
||||
pub fn parse_params(network: &str, token: &str, amount: u64) -> Result<(String, u64)> {
|
||||
match NetworkName::from_str(network)? {
|
||||
NetworkName::Solana => match token {
|
||||
"solana" | "sol" => {
|
||||
let token_id = "So11111111111111111111111111111111111111112";
|
||||
let amount_in_apo: u64 = amount * 10 ^ 8;
|
||||
Ok((token_id.to_string(), amount_in_apo))
|
||||
}
|
||||
tkn => {
|
||||
let token_id = symbol_to_id(tkn)?;
|
||||
let amount_in_apo: u64 = amount * 10 ^ 8;
|
||||
Ok((token_id.to_string(), amount_in_apo))
|
||||
}
|
||||
},
|
||||
NetworkName::Bitcoin => Err(Error::NetworkParseError),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn symbol_to_id(token: &str) -> Result<String> {
|
||||
let vec: Vec<char> = token.chars().collect();
|
||||
let mut counter = 0;
|
||||
for c in vec {
|
||||
if c.is_alphabetic() {
|
||||
counter += 1;
|
||||
}
|
||||
}
|
||||
if counter == token.len() {
|
||||
search_id(token)
|
||||
} else {
|
||||
Ok(token.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn search_id(symbol: &str) -> Result<String> {
|
||||
// TODO: FIXME
|
||||
let file_contents = std::fs::read_to_string("token/solanatokenlist.json")?;
|
||||
let tokenlist: serde_json::Value = serde_json::from_str(&file_contents)?;
|
||||
let tokens = tokenlist["tokens"]
|
||||
.as_array()
|
||||
.ok_or_else(|| Error::TokenParseError)?;
|
||||
for item in tokens {
|
||||
if item["symbol"] == symbol.to_uppercase() {
|
||||
let address = item["address"].clone();
|
||||
let address = address.as_str().ok_or_else(|| Error::TokenParseError)?;
|
||||
return Ok(address.to_string());
|
||||
}
|
||||
}
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::serial::{deserialize, serialize};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use super::{Keypair, WalletApi};
|
||||
use crate::client::ClientFailed;
|
||||
use crate::{Error, Result};
|
||||
use crate::service::NetworkName;
|
||||
use crate::util::NetworkName;
|
||||
|
||||
use async_std::sync::{Arc, Mutex};
|
||||
use log::*;
|
||||
|
||||
Reference in New Issue
Block a user