Skip to content

Commit

Permalink
feat: use serde_json for serialization
Browse files Browse the repository at this point in the history
  • Loading branch information
riverKanies committed Dec 13, 2024
1 parent 1ad389c commit 604590e
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 47 deletions.
53 changes: 19 additions & 34 deletions examples/wasm/js/index.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,17 @@
import { WalletWrapper, greet } from '../rust/pkg';

// --8<-- [start:store]
// needed to handle js Map serialization
// simple string storage example
const Store = {
save: data => {
if (!data) {
console.log("No data to save");
return;
}
const serializedStaged = JSON.stringify(data, (key, value) => {
if (value instanceof Map) {
return {
dataType: 'Map',
value: Array.from(value.entries())
};
}
return value;
});
localStorage.setItem("walletData", serializedStaged);
localStorage.setItem("walletData", data); // data is already a JSON string
},
load: () => {
const walletDataString = localStorage.getItem("walletData");
// Convert serialized Maps back to Map objects when loading
const walletData = JSON.parse(walletDataString, (key, value) => {
if (value?.dataType === 'Map') {
return new Map(value.value);
}
return value;
});
return walletData;
return localStorage.getItem("walletData"); // return the JSON string directly
}
}
// --8<-- [end:store]
Expand All @@ -42,11 +25,11 @@ async function run() {
console.log(greet()); // Should print "Hello, bdk-wasm!"

// --8<-- [start:wallet]
let walletData = Store.load();
console.log("Wallet data:", walletData);
let walletDataString = Store.load();
console.log("Wallet data:", walletDataString);

let wallet;
if (!walletData) {
if (!walletDataString) {
console.log("Creating new wallet");
wallet = new WalletWrapper(
"signet",
Expand All @@ -58,16 +41,16 @@ async function run() {
console.log("Performing Full Scan...");
await wallet.scan(2);

const stagedData = wallet.take_staged();
console.log("Staged:", stagedData);
const stagedDataString = wallet.take_staged();
console.log("Staged:", stagedDataString);

Store.save(stagedData);
Store.save(stagedDataString);
console.log("Wallet data saved to local storage");
walletData = stagedData;
walletDataString = stagedDataString;
} else {
console.log("Loading wallet");
wallet = WalletWrapper.load(
walletData,
walletDataString,
"https://mutinynet.com/api",
externalDescriptor,
internalDescriptor
Expand All @@ -76,10 +59,10 @@ async function run() {
console.log("Syncing...");
await wallet.sync(2);

const stagedData = wallet.take_staged();
console.log("Staged:", stagedData);
const stagedDataString = wallet.take_staged();
console.log("Staged:", stagedDataString);

Store.save(stagedData);
Store.save(stagedDataString);
console.log("Wallet data saved to local storage");
}
// --8<-- [end:wallet]
Expand All @@ -91,10 +74,12 @@ async function run() {
// Test address generation
console.log("New address:", wallet.get_new_address());

const mergedData = wallet.take_merged(walletData);
console.log("Merged:", mergedData);
// handle changeset merge on rust side
const mergedDataString = wallet.take_merged(walletDataString);

console.log("Merged:", mergedDataString);

Store.save(mergedData);
Store.save(mergedDataString);
console.log("new address saved");
// --8<-- [end:utils]
}
Expand Down
1 change: 1 addition & 0 deletions examples/wasm/rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ wasm-bindgen-futures = "0.4.45"
js-sys = "0.3.72"
web-sys = { version = "0.3.72", features = ["console"] }
serde-wasm-bindgen = "0.6.5"
serde_json = "1.0"

# The `console_error_panic_hook` crate provides better debugging of panics by
# logging them with `console.error`. This is great for development, but requires
Expand Down
31 changes: 18 additions & 13 deletions examples/wasm/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ use bdk_esplora::{
use bdk_wallet::{chain::Merge, bitcoin::Network, ChangeSet, KeychainKind, Wallet};
use js_sys::Date;
use wasm_bindgen::prelude::*;
use serde_wasm_bindgen::{from_value, to_value};
// use serde_wasm_bindgen::{from_value, to_value};
use serde_json::{self, Value};

const PARALLEL_REQUESTS: usize = 1;

Expand Down Expand Up @@ -71,15 +72,16 @@ impl WalletWrapper {
})
}

pub fn load(changeset: JsValue, url: &str, external_descriptor: &str, internal_descriptor: &str) -> JsResult<WalletWrapper> {
let changeset = from_value(changeset)?;
pub fn load(changeset_str: &str, url: &str, external_descriptor: &str, internal_descriptor: &str) -> JsResult<WalletWrapper> {
let changeset_value: Value = serde_json::from_str(changeset_str)?;
let changeset: ChangeSet = serde_json::from_value(changeset_value)?;

let wallet_opt = Wallet::load()
.descriptor(KeychainKind::External, Some(external_descriptor.to_string()))
.descriptor(KeychainKind::Internal, Some(internal_descriptor.to_string()))
.extract_keys()
.load_wallet_no_persist(changeset)?;


let wallet = match wallet_opt {
Some(wallet) => wallet,
None => return Err(JsError::new("Failed to load wallet, check the changeset")),
Expand Down Expand Up @@ -144,24 +146,27 @@ impl WalletWrapper {
}

// --8<-- [start:store]
pub fn take_staged(&mut self) -> JsResult<JsValue> {
pub fn take_staged(&mut self) -> JsResult<String> {
match self.wallet.take_staged() {
Some(changeset) => {
Ok(to_value(&changeset)?)
let value = serde_json::to_value(&changeset)?;
Ok(serde_json::to_string(&value)?)
}
None => Ok(JsValue::null()),
None => Ok("null".to_string()),
}
}

pub fn take_merged(&mut self, previous: JsValue) -> JsResult<JsValue> {
pub fn take_merged(&mut self, previous: String) -> JsResult<String> {
match self.wallet.take_staged() {
Some(curr_changeset) => {
let mut changeset: ChangeSet = from_value(previous)?;
changeset.merge(curr_changeset);
Ok(to_value(&changeset)?)
let previous_value: Value = serde_json::from_str(&previous)?;
let mut previous_changeset: ChangeSet = serde_json::from_value(previous_value)?;
previous_changeset.merge(curr_changeset);
let final_value = serde_json::to_value(&previous_changeset)?;
Ok(serde_json::to_string(&final_value)?)
}
None => Ok(JsValue::null()),
None => Ok("null".to_string()),
}
}
// --8<-- [end:store]
}
}

0 comments on commit 604590e

Please sign in to comment.