Skip to content

Commit

Permalink
feat: Added wasm consumable notes + improved note models (0xPolygonMi…
Browse files Browse the repository at this point in the history
…den#561)

* feat: Added wasm consumable notes + improved note models

* improved tests + cleaned up model constructors

* cleanup
  • Loading branch information
julian-demox authored Oct 30, 2024
1 parent 29a6082 commit b1c79f4
Show file tree
Hide file tree
Showing 15 changed files with 589 additions and 248 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## 0.6.0 (TBD)

* Allow to set expiration delta for `TransactionRequest` (#553).
* Added WASM consumable notes API + improved note models (#561).
* [BREAKING] Refactored `OutputNoteRecord` to use states and transitions for updates (#551).
* Added better error handling for WASM sync state (#558).
* Added WASM Input note tests + updated input note models (#554)
Expand Down
4 changes: 4 additions & 0 deletions crates/web-client/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ const {
AccountStorageMode,
AdviceMap,
AuthSecretKey,
ConsumableNoteRecord,
Felt,
FeltArray,
FungibleAsset,
InputNoteState,
Note,
NoteAssets,
NoteConsumability,
NoteExecutionHint,
NoteExecutionMode,
NoteFilter,
Expand Down Expand Up @@ -47,12 +49,14 @@ export {
AccountStorageMode,
AdviceMap,
AuthSecretKey,
ConsumableNoteRecord,
Felt,
FeltArray,
FungibleAsset,
InputNoteState,
Note,
NoteAssets,
NoteConsumability,
NoteExecutionHint,
NoteExecutionMode,
NoteFilter,
Expand Down
2 changes: 2 additions & 0 deletions crates/web-client/js/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export {
AccountStorageMode,
AdviceMap,
AuthSecretKey,
ConsumableNoteRecord,
Felt,
FeltArray,
FungibleAsset,
Expand All @@ -13,6 +14,7 @@ export {
NewTransactionResult,
Note,
NoteAssets,
NoteConsumability,
NoteExecutionHint,
NoteExecutionMode,
NoteFilter,
Expand Down
2 changes: 1 addition & 1 deletion crates/web-client/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@demox-labs/miden-sdk",
"version": "0.0.15",
"version": "0.0.16",
"description": "Polygon Miden Wasm SDK",
"collaborators": [
"Polygon Miden",
Expand Down
79 changes: 39 additions & 40 deletions crates/web-client/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import resolve from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";

// Flag that indicates if the build is meant for testing purposes.
const testing = process.env.MIDEN_WEB_TESTING === 'true';
const testing = process.env.MIDEN_WEB_TESTING === "true";

/**
* Rollup configuration file for building a Cargo project and creating a WebAssembly (WASM) module.
Expand All @@ -20,46 +20,45 @@ const testing = process.env.MIDEN_WEB_TESTING === 'true';
* Both configurations output ES module format files with source maps for easier debugging.
*/
export default [
{
input: {
wasm: "./js/wasm.js",
},
output: {
dir: `dist`,
format: "es",
sourcemap: true,
assetFileNames: "assets/[name][extname]",
},
plugins: [
rust({
cargoArgs: [
"--features", "testing",
"--config", `build.rustflags=["-C", "target-feature=+atomics,+bulk-memory,+mutable-globals", "-C", "link-arg=--max-memory=4294967296"]`,
"--no-default-features",
],
{
input: {
wasm: "./js/wasm.js",
},
output: {
dir: `dist`,
format: "es",
sourcemap: true,
assetFileNames: "assets/[name][extname]",
},
plugins: [
rust({
cargoArgs: [
"--features",
"testing",
"--config",
`build.rustflags=["-C", "target-feature=+atomics,+bulk-memory,+mutable-globals", "-C", "link-arg=--max-memory=4294967296"]`,
"--no-default-features",
],

experimental: {
typescriptDeclarationDir: "dist/crates",
},
experimental: {
typescriptDeclarationDir: "dist/crates",
},

wasmOptArgs: testing ? ["-O0"] : null,
}),
resolve(),
commonjs(),
],
wasmOptArgs: testing ? ["-O0"] : null,
}),
resolve(),
commonjs(),
],
},
{
input: {
index: "./js/index.js",
},
{
input: {
index: "./js/index.js",
},
output: {
dir: `dist`,
format: "es",
sourcemap: true,
},
plugins: [
resolve(),
commonjs(),
],
}
output: {
dir: `dist`,
format: "es",
sourcemap: true,
},
plugins: [resolve(), commonjs()],
},
];
89 changes: 89 additions & 0 deletions crates/web-client/src/models/consumable_note_record.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
use miden_client::{
notes::{NoteConsumability as NativeNoteConsumability, NoteRelevance},
store::InputNoteRecord as NativeInputNoteRecord,
};
use wasm_bindgen::prelude::*;

use super::{account_id::AccountId, input_note_record::InputNoteRecord};

#[derive(Clone)]
#[wasm_bindgen]
pub struct ConsumableNoteRecord {
input_note_record: InputNoteRecord,
note_consumability: Vec<NoteConsumability>,
}

#[derive(Clone, Copy)]
#[wasm_bindgen]
pub struct NoteConsumability {
account_id: AccountId,

// The block number after which the note can be consumed,
// if None then the note can be consumed immediately
consumable_after_block: Option<u32>,
}

#[wasm_bindgen]
impl NoteConsumability {
pub(crate) fn new(
account_id: AccountId,
consumable_after_block: Option<u32>,
) -> NoteConsumability {
NoteConsumability { account_id, consumable_after_block }
}

pub fn account_id(&self) -> AccountId {
self.account_id
}

pub fn consumable_after_block(&self) -> Option<u32> {
self.consumable_after_block
}
}

#[wasm_bindgen]
impl ConsumableNoteRecord {
#[wasm_bindgen(constructor)]
pub fn new(
input_note_record: InputNoteRecord,
note_consumability: Vec<NoteConsumability>,
) -> ConsumableNoteRecord {
ConsumableNoteRecord { input_note_record, note_consumability }
}

pub fn input_note_record(&self) -> InputNoteRecord {
self.input_note_record.clone()
}

pub fn note_consumability(&self) -> Vec<NoteConsumability> {
self.note_consumability.clone()
}
}

// CONVERSIONS
// ================================================================================================
impl From<(NativeInputNoteRecord, Vec<NativeNoteConsumability>)> for ConsumableNoteRecord {
fn from(
(input_note_record, note_consumability): (
NativeInputNoteRecord,
Vec<NativeNoteConsumability>,
),
) -> Self {
ConsumableNoteRecord::new(
input_note_record.into(),
note_consumability.into_iter().map(|c| c.into()).collect(),
)
}
}

impl From<NativeNoteConsumability> for NoteConsumability {
fn from(note_consumability: NativeNoteConsumability) -> Self {
NoteConsumability::new(
note_consumability.0.into(),
match note_consumability.1 {
NoteRelevance::After(block) => Some(block),
NoteRelevance::Always => None,
},
)
}
}
12 changes: 12 additions & 0 deletions crates/web-client/src/models/fungible_asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,15 @@ impl From<&FungibleAsset> for NativeAsset {
fungible_asset.0.into()
}
}

impl From<FungibleAssetNative> for FungibleAsset {
fn from(native_asset: FungibleAssetNative) -> Self {
FungibleAsset(native_asset)
}
}

impl From<&FungibleAssetNative> for FungibleAsset {
fn from(native_asset: &FungibleAssetNative) -> Self {
FungibleAsset(*native_asset)
}
}
1 change: 1 addition & 0 deletions crates/web-client/src/models/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub mod advice_map;
pub mod asset_vault;
pub mod auth_secret_key;
pub mod block_header;
pub mod consumable_note_record;
pub mod executed_transaction;
pub mod felt;
pub mod fungible_asset;
Expand Down
13 changes: 13 additions & 0 deletions crates/web-client/src/models/note_assets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,19 @@ impl NoteAssets {
pub fn push(&mut self, asset: &FungibleAsset) {
let _ = self.0.add_asset(asset.into());
}

pub fn assets(&self) -> Vec<FungibleAsset> {
self.0
.iter()
.filter_map(|asset| {
if asset.is_fungible() {
Some(asset.unwrap_fungible().into())
} else {
None // TODO: Support non fungible assets
}
})
.collect()
}
}

// CONVERSIONS
Expand Down
21 changes: 20 additions & 1 deletion crates/web-client/src/notes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ use wasm_bindgen::prelude::*;

use super::models::note_script::NoteScript;
use crate::{
models::{input_note_record::InputNoteRecord, note_filter::NoteFilter},
models::{
account_id::AccountId, consumable_note_record::ConsumableNoteRecord,
input_note_record::InputNoteRecord, note_filter::NoteFilter,
},
WebClient,
};

Expand Down Expand Up @@ -80,4 +83,20 @@ impl WebClient {
Err(JsValue::from_str("Client not initialized"))
}
}

pub async fn get_consumable_notes(
&mut self,
account_id: Option<AccountId>,
) -> Result<Vec<ConsumableNoteRecord>, JsValue> {
if let Some(client) = self.get_mut_inner() {
let native_account_id = account_id.map(|id| id.into());
let result = client.get_consumable_notes(native_account_id).await.map_err(|err| {
JsValue::from_str(&format!("Failed to get consumable notes: {}", err))
})?;

Ok(result.into_iter().map(|record| record.into()).collect())
} else {
Err(JsValue::from_str("Client not initialized"))
}
}
}
Loading

0 comments on commit b1c79f4

Please sign in to comment.