use alloc::string::String;
use alloc::sync::Arc;
use alloc::vec::Vec;
use core::str::FromStr;
use keetanetwork_bindings::account;
use keetanetwork_block::{AccountRef, BlockHash};
use wasm_bindgen::prelude::wasm_bindgen;
use crate::convert::{coded, coded_error, parse_identifier_type, JsResult};
#[wasm_bindgen]
#[derive(Clone)]
pub struct Account {
inner: AccountRef,
}
#[wasm_bindgen]
impl Account {
#[wasm_bindgen(js_name = generateSeed)]
pub fn generate_seed() -> JsResult<String> {
account::generate_seed().map_err(coded)
}
#[wasm_bindgen(js_name = generatePassphrase)]
pub fn generate_passphrase() -> JsResult<Vec<String>> {
account::generate_passphrase().map_err(coded)
}
#[wasm_bindgen(js_name = fromSeed)]
pub fn from_seed(seed: String, index: u32, algorithm: Option<String>) -> JsResult<Account> {
let algorithm = algorithm.as_deref().unwrap_or(account::DEFAULT_ALGORITHM);
account::account_from_seed(&seed, index, algorithm)
.map(Account::from)
.map_err(coded)
}
#[wasm_bindgen(js_name = fromPrivateKey)]
pub fn from_private_key(key: String, algorithm: String) -> JsResult<Account> {
account::account_from_private_key(&key, &algorithm)
.map(Account::from)
.map_err(coded)
}
#[wasm_bindgen(js_name = fromPassphrase)]
pub fn from_passphrase(words: Vec<String>, index: u32, algorithm: String) -> JsResult<Account> {
account::account_from_passphrase(words, index, &algorithm)
.map(Account::from)
.map_err(coded)
}
#[wasm_bindgen(js_name = fromPublicKey)]
pub fn from_public_key(key: String, algorithm: String) -> JsResult<Account> {
account::account_from_public_key(&key, &algorithm)
.map(Account::from)
.map_err(coded)
}
#[wasm_bindgen(js_name = fromAddress)]
pub fn from_address(address: String) -> JsResult<Account> {
account::account_from_address(&address)
.map(Account::from)
.map_err(coded)
}
#[wasm_bindgen(getter)]
pub fn address(&self) -> String {
account::account_address(&self.inner)
}
#[wasm_bindgen(getter)]
pub fn algorithm(&self) -> String {
account::account_algorithm(&self.inner)
}
#[wasm_bindgen(getter, js_name = publicKey)]
pub fn public_key(&self) -> String {
account::account_public_key(&self.inner)
}
#[wasm_bindgen(js_name = generateIdentifier)]
pub fn generate_identifier(
&self,
kind: String,
previous: Option<String>,
op_index: Option<u32>,
) -> JsResult<Account> {
let kind = parse_identifier_type(&kind)?;
let previous = previous
.map(|hash| {
BlockHash::from_str(&hash).map_err(|_| coded_error("INVALID_BLOCK_HASH", "block hash must be hex"))
})
.transpose()?;
let identifier = self
.inner
.generate_identifier(kind, previous.as_ref(), op_index.unwrap_or(0))
.map_err(|error| coded_error("IDENTIFIER", error.as_ref()))?;
Ok(Self { inner: Arc::new(identifier) })
}
pub fn sign(&self, message: Vec<u8>) -> JsResult<Vec<u8>> {
account::account_sign(&self.inner, &message).map_err(coded)
}
pub fn verify(&self, message: Vec<u8>, signature: Vec<u8>) -> bool {
account::account_verify(&self.inner, &message, &signature)
}
pub fn encrypt(&self, plaintext: Vec<u8>) -> JsResult<Vec<u8>> {
account::account_encrypt(&self.inner, &plaintext).map_err(coded)
}
pub fn decrypt(&self, ciphertext: Vec<u8>) -> JsResult<Vec<u8>> {
account::account_decrypt(&self.inner, &ciphertext).map_err(coded)
}
}
impl Account {
pub(crate) fn inner(&self) -> AccountRef {
Arc::clone(&self.inner)
}
}
impl From<AccountRef> for Account {
fn from(inner: AccountRef) -> Self {
Self { inner }
}
}