use crate::{AddressResult, Error, Network, Transaction, WebSocketSerial};
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub struct Amp0 {
inner: lwk_wollet::amp0::Amp0<WebSocketSerial>,
network: Network,
}
#[wasm_bindgen]
impl Amp0 {
#[wasm_bindgen(js_name = newWithNetwork)]
pub async fn new_with_network(
network: Network,
username: &str,
password: &str,
amp_id: &str,
) -> Result<Self, Error> {
let url = lwk_wollet::amp0::default_url(network.into())?;
let websocket_serial = WebSocketSerial::new_wamp(url).await?;
let inner = lwk_wollet::amp0::Amp0::new(
websocket_serial,
network.into(),
username,
password,
amp_id,
)
.await?;
Ok(Self { inner, network })
}
#[wasm_bindgen(js_name = netTestnet)]
pub async fn new_testnet(username: &str, password: &str, amp_id: &str) -> Result<Self, Error> {
Self::new_with_network(Network::testnet(), username, password, amp_id).await
}
#[wasm_bindgen(js_name = newMainnet)]
pub async fn new_mainnet(username: &str, password: &str, amp_id: &str) -> Result<Self, Error> {
Self::new_with_network(Network::mainnet(), username, password, amp_id).await
}
#[wasm_bindgen(js_name = lastIndex)]
pub fn last_index(&self) -> u32 {
self.inner.last_index()
}
#[wasm_bindgen(js_name = ampId)]
pub fn amp_id(&self) -> String {
self.inner.amp_id().into()
}
pub async fn address(&mut self, index: Option<u32>) -> Result<AddressResult, Error> {
let address_result = self.inner.address(index).await?;
Ok(address_result.into())
}
pub fn wollet(&self) -> Result<crate::Wollet, Error> {
Ok(crate::Wollet::new(
&self.network,
&self.inner.wollet_descriptor().into(),
)?)
}
pub async fn sign(&self, amp0pset: &Amp0Pset) -> Result<Transaction, Error> {
let tx = self.inner.sign(amp0pset.as_ref()).await?;
Ok(tx.into())
}
}
#[wasm_bindgen]
pub struct Amp0Pset {
inner: lwk_wollet::amp0::Amp0Pset,
}
impl From<lwk_wollet::amp0::Amp0Pset> for Amp0Pset {
fn from(inner: lwk_wollet::amp0::Amp0Pset) -> Self {
Self { inner }
}
}
impl From<Amp0Pset> for lwk_wollet::amp0::Amp0Pset {
fn from(pset: Amp0Pset) -> Self {
pset.inner
}
}
impl AsRef<lwk_wollet::amp0::Amp0Pset> for Amp0Pset {
fn as_ref(&self) -> &lwk_wollet::amp0::Amp0Pset {
&self.inner
}
}
#[wasm_bindgen]
impl Amp0Pset {
#[wasm_bindgen(constructor)]
pub fn new(pset: crate::Pset, blinding_nonces: Vec<String>) -> Result<Self, Error> {
let inner = lwk_wollet::amp0::Amp0Pset::new(pset.into(), blinding_nonces)?;
Ok(Self { inner })
}
pub fn pset(&self) -> crate::Pset {
self.inner.pset().clone().into()
}
#[wasm_bindgen(js_name = blindingNonces)]
pub fn blinding_nonces(&self) -> Vec<String> {
self.inner.blinding_nonces().to_vec()
}
}
#[cfg(all(test, target_arch = "wasm32"))]
mod tests {
use super::*;
use wasm_bindgen_test::*;
wasm_bindgen_test_configure!(run_in_browser);
#[wasm_bindgen_test]
async fn test_amp0ext() {
let mut amp0 = Amp0::new_mainnet("userleo456", "userleo456", "")
.await
.unwrap();
let last_index = amp0.last_index();
assert!(last_index > 20);
let addr = amp0.address(None).await.unwrap();
assert_eq!(addr.index(), last_index + 1);
assert_eq!(amp0.last_index(), last_index + 1);
let mut wollet = amp0.wollet().unwrap();
let network = Network::mainnet();
let mut client = network.default_esplora_client();
let update = client.full_scan(&wollet).await.unwrap().unwrap();
wollet.apply_update(&update).unwrap();
let balance = wollet.balance().unwrap();
use std::collections::HashMap;
let balance: HashMap<lwk_wollet::elements::AssetId, u64> =
serde_wasm_bindgen::from_value(balance).unwrap();
let lbtc = lwk_wollet::ElementsNetwork::Liquid.policy_asset();
let mut expected = HashMap::new();
expected.insert(lbtc, 0);
assert_eq!(balance, expected);
}
#[wasm_bindgen_test]
#[ignore] async fn test_amp0_e2e() {
use crate::{Mnemonic, Signer, TxBuilder};
use std::collections::HashMap;
let network = Network::testnet();
let mut amp0 = Amp0::new_testnet("userleo345678", "userleo345678", "")
.await
.unwrap();
let addr = amp0.address(Some(1)).await.unwrap().address();
let mut wollet = amp0.wollet().unwrap();
let mut client = network.default_esplora_client();
let last_index = amp0.last_index();
let update = client
.full_scan_to_index(&wollet, last_index)
.await
.unwrap()
.unwrap();
wollet.apply_update(&update).unwrap();
let balance = wollet.balance().unwrap();
let balance: HashMap<lwk_wollet::elements::AssetId, u64> =
serde_wasm_bindgen::from_value(balance).unwrap();
let lbtc = lwk_wollet::ElementsNetwork::LiquidTestnet.policy_asset();
let lbtc_balance = balance.get(&lbtc).unwrap_or(&0);
if *lbtc_balance < 500 {
println!(
"Balance is insufficient to make a transaction, send some tLBTC to {}",
addr
);
return;
}
let amp0pset = TxBuilder::new(&network)
.drain_lbtc_wallet()
.finish_for_amp0(&wollet)
.unwrap();
let mnemonic = Mnemonic::new(
"student lady today genius gentle zero satoshi book just link gauge tooth",
)
.unwrap();
let signer = Signer::new(&mnemonic, &network).unwrap();
let pset = signer.sign(amp0pset.pset()).unwrap();
let amp0pset = Amp0Pset::new(pset, amp0pset.blinding_nonces()).unwrap();
let tx = amp0.sign(&0pset).await.unwrap();
let _txid = client.broadcast_tx(&tx).await.unwrap();
}
}