110 lines
2.7 KiB
Rust
110 lines
2.7 KiB
Rust
use std::{collections::HashMap, str::FromStr};
|
|
|
|
use hypersdk::{Address, hypercore::PrivateKeySigner};
|
|
|
|
#[derive(Debug)]
|
|
pub struct PrivateKey(pub PrivateKeySigner, pub String);
|
|
|
|
impl FromStr for PrivateKey {
|
|
type Err = <PrivateKeySigner as FromStr>::Err;
|
|
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
Ok(Self(s.parse()?, s.to_string()))
|
|
}
|
|
}
|
|
|
|
impl std::fmt::Display for PrivateKey {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
self.1.fmt(f)
|
|
}
|
|
}
|
|
|
|
impl<'de> serde::Deserialize<'de> for PrivateKey {
|
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
where
|
|
D: serde::Deserializer<'de>,
|
|
{
|
|
let s = String::deserialize(deserializer)?;
|
|
s.parse().map_err(serde::de::Error::custom)
|
|
}
|
|
}
|
|
|
|
impl serde::Serialize for PrivateKey {
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
where
|
|
S: serde::Serializer,
|
|
{
|
|
serializer.serialize_str(&self.to_string())
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
|
pub struct Account {
|
|
pub address: Address,
|
|
pub private_key: PrivateKey,
|
|
}
|
|
|
|
#[derive(Debug, Default, serde::Serialize, serde::Deserialize)]
|
|
pub struct AccountList {
|
|
pub active: String,
|
|
|
|
#[serde(flatten)]
|
|
pub accounts: HashMap<String, Account>,
|
|
}
|
|
|
|
impl AccountList {
|
|
pub async fn new() -> tokio::io::Result<Self> {
|
|
let path = crate::store::pulse_accounts_file()?;
|
|
|
|
if !path.exists() {
|
|
let default = Self::default();
|
|
|
|
tokio::fs::create_dir_all(path.parent().unwrap()).await?;
|
|
tokio::fs::write(&path, default.to_string()?).await?;
|
|
|
|
return Ok(default);
|
|
}
|
|
|
|
let output = tokio::fs::read_to_string(path).await?;
|
|
|
|
Self::from_str(&output)
|
|
}
|
|
|
|
pub fn from_str(s: &str) -> tokio::io::Result<Self> {
|
|
toml::from_str(s)
|
|
.map_err(|v| tokio::io::Error::new(std::io::ErrorKind::InvalidInput, v.to_string()))
|
|
}
|
|
|
|
pub fn to_string(&self) -> tokio::io::Result<String> {
|
|
toml::to_string(self)
|
|
.map_err(|v| tokio::io::Error::new(std::io::ErrorKind::Other, v.to_string()))
|
|
}
|
|
|
|
pub fn get_active<'a>(&'a self) -> Option<&'a Account> {
|
|
self.accounts.get(&self.active)
|
|
}
|
|
}
|
|
|
|
impl Account {
|
|
pub fn get_truncated_address(&self) -> String {
|
|
let s = format!("{:x}", self.address);
|
|
|
|
if s.len() <= 6 {
|
|
return format!("INVALID");
|
|
}
|
|
|
|
let first: String = s.chars().take(4).collect();
|
|
|
|
let last: String = s
|
|
.chars()
|
|
.rev()
|
|
.take(4)
|
|
.collect::<Vec<char>>()
|
|
.into_iter()
|
|
.rev()
|
|
.collect();
|
|
|
|
format!("{}..{}", first, last)
|
|
}
|
|
}
|