Skip to content

Commit 7d91e9f

Browse files
TomasArracheaigamigommagician
authored
feat: webstore settings table (0xMiden#1294)
* feat: add migrations and settings tables * feat: add settings table to web store * chore: lint * docs: update web-client docs * review: use Uint8Array instead of blob * review: refactor account cmd * chore: bump web client version * chore: lint * review: address comments * review: add method to list settings keys * merge: add comment * feat: add listKeys * chore: bump sdk version * chore: fix merge * review: rename settings accessors * review: rename settings accessors * chore: bump sdk version * chore: bump sdk version * review: add doc comments * review: docs * Update crates/web-client/package.json --------- Co-authored-by: igamigo <[email protected]> Co-authored-by: Marti <[email protected]>
1 parent 848747a commit 7d91e9f

File tree

19 files changed

+503
-55
lines changed

19 files changed

+503
-55
lines changed

crates/idxdb-store/src/js/schema.d.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ export interface IForeignAccountCode {
9797
accountId: string;
9898
codeRoot: string;
9999
}
100+
export interface ISetting {
101+
key: string;
102+
value: Uint8Array;
103+
}
100104
declare const db: Dexie & {
101105
accountCodes: Dexie.Table<IAccountCode, string>;
102106
accountStorages: Dexie.Table<IAccountStorage, string>;
@@ -114,6 +118,7 @@ declare const db: Dexie & {
114118
partialBlockchainNodes: Dexie.Table<IPartialBlockchainNode, string>;
115119
tags: Dexie.Table<ITag, number>;
116120
foreignAccountCode: Dexie.Table<IForeignAccountCode, string>;
121+
settings: Dexie.Table<ISetting, string>;
117122
};
118123
declare const accountCodes: import("dexie").Table<IAccountCode, string, IAccountCode>;
119124
declare const accountStorages: import("dexie").Table<IAccountStorage, string, IAccountStorage>;
@@ -131,4 +136,5 @@ declare const blockHeaders: import("dexie").Table<IBlockHeader, string, IBlockHe
131136
declare const partialBlockchainNodes: import("dexie").Table<IPartialBlockchainNode, string, IPartialBlockchainNode>;
132137
declare const tags: import("dexie").Table<ITag, number, ITag>;
133138
declare const foreignAccountCode: import("dexie").Table<IForeignAccountCode, string, IForeignAccountCode>;
134-
export { db, accountCodes, accountStorages, storageMapEntries, accountAssets, accountAuths, accounts, transactions, transactionScripts, inputNotes, outputNotes, notesScripts, stateSync, blockHeaders, partialBlockchainNodes, tags, foreignAccountCode, };
139+
declare const settings: import("dexie").Table<ISetting, string, ISetting>;
140+
export { db, accountCodes, accountStorages, storageMapEntries, accountAssets, accountAuths, accounts, transactions, transactionScripts, inputNotes, outputNotes, notesScripts, stateSync, blockHeaders, partialBlockchainNodes, tags, foreignAccountCode, settings, };

crates/idxdb-store/src/js/schema.js

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/idxdb-store/src/js/schema.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export declare function getSetting(key: string): Promise<{
2+
key: string;
3+
value: string;
4+
} | null | undefined>;
5+
export declare function insertSetting(key: string, value: Uint8Array): Promise<void>;
6+
export declare function removeSetting(key: string): Promise<void>;
7+
export declare function listSettingKeys(): Promise<string[] | undefined>;

crates/idxdb-store/src/js/settings.js

Lines changed: 58 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/idxdb-store/src/js/settings.js.map

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/idxdb-store/src/lib.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ pub mod export;
4242
pub mod import;
4343
pub mod note;
4444
mod promise;
45+
pub mod settings;
4546
pub mod sync;
4647
pub mod transaction;
4748

@@ -253,20 +254,20 @@ impl Store for WebStore {
253254
// SETTINGS
254255
// --------------------------------------------------------------------------------------------
255256

256-
async fn set_setting(&self, _key: String, _value: Vec<u8>) -> Result<(), StoreError> {
257-
unimplemented!()
257+
async fn set_setting(&self, key: String, value: Vec<u8>) -> Result<(), StoreError> {
258+
self.set_setting(key, value).await
258259
}
259260

260-
async fn get_setting(&self, _key: String) -> Result<Option<Vec<u8>>, StoreError> {
261-
unimplemented!()
261+
async fn get_setting(&self, key: String) -> Result<Option<Vec<u8>>, StoreError> {
262+
self.get_setting(key).await
262263
}
263264

264-
async fn remove_setting(&self, _key: String) -> Result<(), StoreError> {
265-
unimplemented!()
265+
async fn remove_setting(&self, key: String) -> Result<(), StoreError> {
266+
self.remove_setting(key).await
266267
}
267268

268269
async fn list_setting_keys(&self) -> Result<Vec<String>, StoreError> {
269-
unimplemented!()
270+
self.list_setting_keys().await
270271
}
271272
}
272273

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
use alloc::string::String;
2+
use alloc::vec::Vec;
3+
4+
use wasm_bindgen::prelude::*;
5+
use wasm_bindgen_futures::{js_sys, wasm_bindgen};
6+
7+
// Settings IndexedDB Operations
8+
#[wasm_bindgen(module = "/src/js/settings.js")]
9+
extern "C" {
10+
#[wasm_bindgen(js_name = getSetting)]
11+
pub fn idxdb_get_setting(key: String) -> js_sys::Promise;
12+
13+
#[wasm_bindgen(js_name = insertSetting)]
14+
pub fn idxdb_insert_setting(key: String, value: Vec<u8>) -> js_sys::Promise;
15+
16+
#[wasm_bindgen(js_name = removeSetting)]
17+
pub fn idxdb_remove_setting(key: String) -> js_sys::Promise;
18+
19+
#[wasm_bindgen(js_name = listSettingKeys)]
20+
pub fn idxdb_list_setting_keys() -> js_sys::Promise;
21+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
use alloc::string::String;
2+
use alloc::vec::Vec;
3+
4+
use miden_client::store::StoreError;
5+
use serde_wasm_bindgen::from_value;
6+
use wasm_bindgen_futures::JsFuture;
7+
8+
mod js_bindings;
9+
mod models;
10+
11+
use js_bindings::{
12+
idxdb_get_setting,
13+
idxdb_insert_setting,
14+
idxdb_list_setting_keys,
15+
idxdb_remove_setting,
16+
};
17+
18+
use crate::WebStore;
19+
use crate::settings::models::SettingValueIdxdbObject;
20+
21+
impl WebStore {
22+
pub(crate) async fn set_setting(&self, key: String, value: Vec<u8>) -> Result<(), StoreError> {
23+
let promise = idxdb_insert_setting(key, value);
24+
JsFuture::from(promise).await.map_err(|js_error| {
25+
StoreError::DatabaseError(format!("failed to set setting value: {js_error:?}",))
26+
})?;
27+
Ok(())
28+
}
29+
30+
pub(crate) async fn get_setting(&self, key: String) -> Result<Option<Vec<u8>>, StoreError> {
31+
let promise = idxdb_get_setting(key);
32+
let value = JsFuture::from(promise).await.map_err(|js_error| {
33+
StoreError::DatabaseError(format!(
34+
"failed to get setting value from idxdb: {js_error:?}",
35+
))
36+
})?;
37+
let setting: Option<SettingValueIdxdbObject> = from_value(value).map_err(|err| {
38+
StoreError::DatabaseError(format!("failed to deserialize value from idxdb: {err:?}"))
39+
})?;
40+
Ok(setting.map(|setting| setting.value))
41+
}
42+
43+
pub(crate) async fn remove_setting(&self, key: String) -> Result<(), StoreError> {
44+
let promise = idxdb_remove_setting(key);
45+
JsFuture::from(promise).await.map_err(|js_error| {
46+
StoreError::DatabaseError(format!("failed to delete setting value: {js_error:?}",))
47+
})?;
48+
Ok(())
49+
}
50+
51+
pub(crate) async fn list_setting_keys(&self) -> Result<Vec<String>, StoreError> {
52+
let promise = idxdb_list_setting_keys();
53+
let keys = JsFuture::from(promise).await.map_err(|js_error| {
54+
StoreError::DatabaseError(format!("failed to list setting keys: {js_error:?}",))
55+
})?;
56+
let keys: Vec<String> = from_value(keys).map_err(|err| {
57+
StoreError::DatabaseError(format!("failed to deserialize setting keys: {err:?}"))
58+
})?;
59+
Ok(keys)
60+
}
61+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
use alloc::string::String;
2+
use alloc::vec::Vec;
3+
4+
use base64::Engine as _;
5+
use base64::engine::general_purpose;
6+
use serde::de::Error;
7+
use serde::{Deserialize, Deserializer, Serialize};
8+
9+
#[derive(Serialize, Deserialize)]
10+
#[serde(rename_all = "camelCase")]
11+
pub struct SettingValueIdxdbObject {
12+
pub key: String,
13+
#[serde(deserialize_with = "base64_to_vec_u8_required", default)]
14+
pub value: Vec<u8>,
15+
}
16+
17+
fn base64_to_vec_u8_required<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
18+
where
19+
D: Deserializer<'de>,
20+
{
21+
let base64_str: String = Deserialize::deserialize(deserializer)?;
22+
general_purpose::STANDARD
23+
.decode(&base64_str)
24+
.map_err(|e| Error::custom(format!("Base64 decode error: {e}")))
25+
}

0 commit comments

Comments
 (0)