use derive_more::{From, Into};
use ergo_lib::ergotree_ir::sigma_protocol::sigma_boolean::SigmaBoolean;
use js_sys::Uint8Array;
use wasm_bindgen::prelude::*;
pub mod derivation_path;
pub mod ext_pub_key;
pub mod ext_secret_key;
pub mod mnemonic;
use crate::address::Address;
use crate::input::Input;
use crate::transaction::TransactionHintsBag;
use crate::{
box_coll::ErgoBoxes,
ergo_state_ctx::ErgoStateContext,
error_conversion::to_js,
secret_key::{SecretKey, SecretKeys},
transaction::reduced::ReducedTransaction,
transaction::Transaction,
transaction::UnsignedTransaction,
};
#[wasm_bindgen]
#[derive(From, Into)]
pub struct Wallet(ergo_lib::wallet::Wallet);
#[wasm_bindgen]
impl Wallet {
#[wasm_bindgen]
pub fn from_mnemonic(mnemonic_phrase: &str, mnemonic_pass: &str) -> Result<Wallet, JsValue> {
ergo_lib::wallet::Wallet::from_mnemonic(mnemonic_phrase, mnemonic_pass)
.map(Wallet)
.map_err(to_js)
}
#[wasm_bindgen]
pub fn from_secrets(secret: &SecretKeys) -> Wallet {
Wallet(ergo_lib::wallet::Wallet::from_secrets(secret.into()))
}
#[wasm_bindgen]
pub fn add_secret(&mut self, secret: &SecretKey) {
self.0.add_secret(secret.clone().into());
}
#[wasm_bindgen]
pub fn sign_transaction(
&self,
_state_context: &ErgoStateContext,
tx: &UnsignedTransaction,
boxes_to_spend: &ErgoBoxes,
data_boxes: &ErgoBoxes,
) -> Result<Transaction, JsValue> {
crate::utils::set_panic_hook();
let boxes_to_spend = boxes_to_spend.clone().into();
let data_boxes = data_boxes.clone().into();
let tx_context = ergo_lib::wallet::signing::TransactionContext::new(
tx.0.clone(),
boxes_to_spend,
data_boxes,
)
.map_err(to_js)?;
self.0
.sign_transaction(tx_context, &_state_context.clone().into(), None)
.map_err(to_js)
.map(Transaction::from)
}
#[wasm_bindgen]
pub fn sign_transaction_multi(
&self,
_state_context: &ErgoStateContext,
tx: &UnsignedTransaction,
boxes_to_spend: &ErgoBoxes,
data_boxes: &ErgoBoxes,
tx_hints: &TransactionHintsBag,
) -> Result<Transaction, JsValue> {
let boxes_to_spend = boxes_to_spend.clone().into();
let data_boxes = data_boxes.clone().into();
let tx_context = ergo_lib::wallet::signing::TransactionContext::new(
tx.0.clone(),
boxes_to_spend,
data_boxes,
)
.map_err(to_js)?;
self.0
.sign_transaction(
tx_context,
&_state_context.clone().into(),
Some(&tx_hints.0),
)
.map_err(to_js)
.map(Transaction::from)
}
#[wasm_bindgen]
pub fn sign_reduced_transaction(
&self,
reduced_tx: &ReducedTransaction,
) -> Result<Transaction, JsValue> {
self.0
.sign_reduced_transaction(reduced_tx.clone().into(), None)
.map_err(to_js)
.map(Transaction::from)
}
#[wasm_bindgen]
pub fn sign_reduced_transaction_multi(
&self,
reduced_tx: &ReducedTransaction,
tx_hints: &TransactionHintsBag,
) -> Result<Transaction, JsValue> {
self.0
.sign_reduced_transaction(reduced_tx.clone().into(), Some(&tx_hints.0))
.map_err(to_js)
.map(Transaction::from)
}
#[wasm_bindgen]
pub fn generate_commitments(
&self,
_state_context: &ErgoStateContext,
tx: &UnsignedTransaction,
boxes_to_spend: &ErgoBoxes,
data_boxes: &ErgoBoxes,
) -> Result<TransactionHintsBag, JsValue> {
let boxes_to_spend = boxes_to_spend.clone().into();
let data_boxes = data_boxes.clone().into();
let tx_context = ergo_lib::wallet::signing::TransactionContext::new(
tx.0.clone(),
boxes_to_spend,
data_boxes,
)
.map_err(to_js)?;
self.0
.generate_commitments(tx_context, &_state_context.clone().into())
.map_err(to_js)
.map(TransactionHintsBag::from)
}
#[wasm_bindgen]
pub fn generate_commitments_for_reduced_transaction(
&self,
reduced_tx: &ReducedTransaction,
) -> Result<TransactionHintsBag, JsValue> {
self.0
.generate_commitments_for_reduced_transaction(reduced_tx.clone().into())
.map_err(to_js)
.map(TransactionHintsBag::from)
}
#[wasm_bindgen]
pub fn sign_message_using_p2pk(
&self,
address: &Address,
message: &[u8],
) -> Result<Uint8Array, JsValue> {
if let Address(ergo_lib::ergotree_ir::chain::address::Address::P2Pk(d)) = address.clone() {
let sb = SigmaBoolean::from(d);
self.0
.sign_message(sb, message)
.map_err(to_js)
.map(|v| Uint8Array::from(v.as_slice()))
} else {
Err(JsValue::from_str(
"wallet::sign_message_using_p2pk: Address:P2Pk expected",
))
}
}
#[wasm_bindgen]
pub fn sign_tx_input(
&self,
input_idx: usize,
state_context: &ErgoStateContext,
tx: &UnsignedTransaction,
boxes_to_spend: &ErgoBoxes,
data_boxes: &ErgoBoxes,
) -> Result<Input, JsValue> {
let boxes_to_spend = boxes_to_spend.clone().into();
let data_boxes = data_boxes.clone().into();
let tx_context = ergo_lib::wallet::signing::TransactionContext::new(
tx.0.clone(),
boxes_to_spend,
data_boxes,
)
.map_err(to_js)?;
let state_context_inner = state_context.clone().into();
self.0
.sign_tx_input(input_idx, tx_context, &state_context_inner, None)
.map_err(to_js)
.map(Input::from)
}
#[wasm_bindgen]
pub fn sign_tx_input_multi(
&self,
input_idx: usize,
state_context: &ErgoStateContext,
tx: &UnsignedTransaction,
boxes_to_spend: &ErgoBoxes,
data_boxes: &ErgoBoxes,
tx_hints: &TransactionHintsBag,
) -> Result<Input, JsValue> {
let boxes_to_spend = boxes_to_spend.clone().into();
let data_boxes = data_boxes.clone().into();
let tx_context = ergo_lib::wallet::signing::TransactionContext::new(
tx.0.clone(),
boxes_to_spend,
data_boxes,
)
.map_err(to_js)?;
let state_context_inner = state_context.clone().into();
self.0
.sign_tx_input(
input_idx,
tx_context,
&state_context_inner,
Some(&tx_hints.0),
)
.map_err(to_js)
.map(Input::from)
}
}