diff --git a/.claude/skills/rust-sdk-patterns/SKILL.md b/.claude/skills/rust-sdk-patterns/SKILL.md index ba94a5a..95d5598 100644 --- a/.claude/skills/rust-sdk-patterns/SKILL.md +++ b/.claude/skills/rust-sdk-patterns/SKILL.md @@ -1,6 +1,6 @@ --- name: rust-sdk-patterns -description: Complete guide to writing Miden smart contracts with the Rust SDK. Covers #[component], #[note], #[tx_script] macros, storage patterns, native functions, asset handling, cross-component calls, P2ID note creation, and asset receiving via component methods. Use when writing, editing, or reviewing Miden Rust contract code. +description: Complete guide to writing Miden smart contracts with the Rust SDK. Covers #[component], #[note], #[tx_script] macros, storage patterns, native functions, asset handling, cross-component calls, and P2ID note creation. Use when writing, editing, or reviewing Miden Rust contract code. --- # Miden Rust SDK Patterns @@ -45,6 +45,8 @@ fn run(_arg: Word, account: &mut Account) { | `StorageValue` | Single typed slot (flags, counters, IDs) | `.get() -> T` | `.set(T) -> T` | | `StorageMap` | Typed key-value mapping (balances, records) | `.get(K) -> V` | `.set(K, V) -> V` | +**Storage keys** are always `Word` (4 Felts). Use `Word::from_u64_unchecked(a, b, c, d)` or `Word::from([f0, f1, f2, f3])`. + ## Native Function Modules | Module | Key Functions | Purpose | @@ -62,10 +64,6 @@ fn run(_arg: Word, account: &mut Account) { `Asset` is now a two-word value: -**Constructor**: `Asset::new(word)` creates an Asset from a Word. - -See [miden-bank bank-account](https://github.com/0xMiden/tutorials/blob/main/examples/miden-bank/contracts/bank-account/src/lib.rs) for complete asset handling patterns including deposit, withdrawal, and balance tracking. - ```rust pub struct Asset { pub key: Word, @@ -82,7 +80,7 @@ let amount = asset.value[0]; // Keep the asset key if you need to persist or compare the asset class let asset_key = asset.key; -// Add asset to account vault (only from component methods, not note scripts — see pitfall P11) +// Add asset to account vault native_account::add_asset(asset); // Remove asset from account vault @@ -91,7 +89,43 @@ native_account::remove_asset(asset.clone()); ## P2ID Output Note Creation -To send assets to another account, create a P2ID (Pay-to-ID) output note. See [miden-bank bank-account](https://github.com/0xMiden/tutorials/blob/main/examples/miden-bank/contracts/bank-account/src/lib.rs) `create_p2id_note()` for a complete working implementation. +To send assets to another account, create a P2ID (Pay-to-ID) output note: + +```rust +fn create_p2id_note(&mut self, serial_num: Word, asset: &Asset, + recipient_id: AccountId, tag: Felt, note_type: Felt) { + let tag = Tag::from(tag); + let note_type = NoteType::from(note_type); + let script_root = Self::p2id_note_root(); // Hardcoded P2ID script digest + + // P2ID note storage: [recipient_suffix, recipient_prefix] + let recipient = note::build_recipient( + serial_num, + script_root, + vec![recipient_id.suffix, recipient_id.prefix], + ); + + let note_idx = output_note::create(tag, note_type, recipient); + let _remaining_value = native_account::remove_asset(asset); + output_note::add_asset(asset, note_idx); +} +``` + +`Recipient::compute(...)` was removed in `miden` 0.11. Use `note::build_recipient(...)` instead. + +## Note Storage And Attached Assets + +Notes receive explicit storage data as `Vec`, accessed with `active_note::get_storage()`. Attached assets are separate and should be read with `active_note::get_assets()`. + +```rust +let storage = active_note::get_storage(); +let serial_num = Word::from([storage[0], storage[1], storage[2], storage[3]]); +let tag = Tag::from(storage[4]); +let note_type = NoteType::from(storage[5]); + +let assets = active_note::get_assets(); +let first_asset = assets[0]; +``` ## Cross-Component Dependencies @@ -103,8 +137,8 @@ Then import the bindings in your Rust code. See [increment-note/src/lib.rs](../. ```rust // Felt from integer -let f = felt!(42); // preferred for literals in contract code -let f = Felt::new(42); // construct a Felt from a u64 +let f = felt!(42); +let f = Felt::new(42); let f = Felt::from_u32(42); let f = Felt::from_canonical_checked(42).unwrap(); @@ -133,14 +167,6 @@ extern crate alloc; use alloc::vec::Vec; ``` -## Asset Receiving via Component Methods - -Note scripts cannot call `native_account::add_asset()` directly (see pitfall P11). The canonical pattern is for an account component to expose a public method that wraps `native_account::add_asset()`, and note scripts call that method via cross-component bindings. - -See [miden-bank bank-account deposit()](https://github.com/0xMiden/tutorials/blob/main/examples/miden-bank/contracts/bank-account/src/lib.rs) for the component side: the `deposit()` method validates the deposit, updates storage, and calls `native_account::add_asset()`. - -See [miden-bank deposit-note](https://github.com/0xMiden/tutorials/blob/main/examples/miden-bank/contracts/deposit-note/src/lib.rs) for the note side: the note script calls `bank_account::deposit()` via generated bindings. - ## Validation Checklist - [ ] `#![no_std]` and `#![feature(alloc_error_handler)]` at top of every contract diff --git a/.claude/skills/rust-sdk-pitfalls/SKILL.md b/.claude/skills/rust-sdk-pitfalls/SKILL.md index c1854cf..97aac8c 100644 --- a/.claude/skills/rust-sdk-pitfalls/SKILL.md +++ b/.claude/skills/rust-sdk-pitfalls/SKILL.md @@ -1,6 +1,6 @@ --- name: rust-sdk-pitfalls -description: Critical pitfalls and safety rules for Miden Rust SDK development. Covers felt arithmetic security, comparison operators, argument limits, storage naming, no-std setup, asset layout, P2ID roots, NoteType construction, note-to-component call boundaries, and note input immutability. Use when reviewing, debugging, or writing Miden contract code. +description: Critical pitfalls and safety rules for Miden Rust SDK development. Covers felt arithmetic security, comparison operators, argument limits, storage naming, no-std setup, asset layout, and P2ID roots. Use when reviewing, debugging, or writing Miden contract code. --- # Miden SDK Pitfalls @@ -26,8 +26,6 @@ let new_balance = current_balance - withdraw_amount; **Rule**: ALWAYS check `.as_canonical_u64()` values before any Felt subtraction. -**Max Felt value**: The maximum valid Felt is `p - 1 = 18446744069414584320`, not `u64::MAX` (`18446744073709551615`). Using `u64::MAX` as a sentinel or boundary value causes silent wraparound. - ## P2: Felt Comparison Operators Are Misleading for Quantity Logic **Severity**: High — silently produces incorrect results @@ -40,6 +38,7 @@ if balance > threshold { ... } // CORRECT for business logic — compare as integers if balance.as_canonical_u64() > threshold.as_canonical_u64() { ... } +- [ ] `Recipient::compute(...)` replaced with `note::build_recipient(...)` ``` **Rule**: For quantity/business logic, ALWAYS convert to `.as_canonical_u64()` before using comparison operators. @@ -152,6 +151,8 @@ let recipient = note::build_recipient( ); ``` +`active_note::get_inputs()` also became `active_note::get_storage()`. + ## P9: P2ID Note Root Hardcoding **Severity**: Low-Medium — breaks after miden-standards updates @@ -178,32 +179,16 @@ fn p2id_note_root() -> Digest { **Mitigation**: Use `P2idNote::script_root()` from miden-standards if available, or verify the hardcoded root matches the current version after dependency updates. -**NoteType for P2ID**: P2ID output notes created in contract code should use the private note type value via `NoteType::from(felt!(2))` (see P10). Using the public note type triggers an opaque "missing details in advice provider" error at execution time. See [miden-bank withdraw](https://github.com/0xMiden/tutorials/blob/main/examples/miden-bank/contracts/bank-account/src/lib.rs) for the working pattern. - -## P10: NoteType Variants Unavailable in Compiler SDK - -**Severity**: Medium -- causes compilation errors - -Named enum variants (`NoteType::Private`, `NoteType::Public`, `NoteType::Encrypted`) don't exist in contract code. Construct via `NoteType::from()`: - -| NoteType | Value | -|----------|-------| -| Public | `NoteType::from(felt!(1))` | -| Private | `NoteType::from(felt!(2))` | -| Encrypted | `NoteType::from(felt!(3))` | - -See [miden-bank bank-account](https://github.com/0xMiden/tutorials/blob/main/examples/miden-bank/contracts/bank-account/src/lib.rs) for `NoteType::from(note_type)` usage. - -## P11: Note Scripts Cannot Call Native Account Functions - -**Severity**: High -- causes runtime failures - -Note scripts cannot call `native_account::add_asset()` or other `native_account::` functions directly. The kernel's `authenticate_account_origin` check rejects these calls from a note context. Instead, note scripts must call an account component method, which then calls `native_account::add_asset()` internally. - -See [miden-bank deposit-note](https://github.com/0xMiden/tutorials/blob/main/examples/miden-bank/contracts/deposit-note/src/lib.rs) for the correct pattern: the note script calls `bank_account::deposit()`, which internally calls `native_account::add_asset()`. - -## P12: Note Inputs Are Immutable After Creation - -**Severity**: Low -- causes incorrect architecture - -Note inputs (`active_note::get_storage()`) are baked at note creation time and cannot be modified after creation. Design note input layouts carefully before deployment. +## Quick Reference + +| Pitfall | One-Line Rule | +|---------|--------------| +| P1 Felt arithmetic | Always `.as_canonical_u64()` before subtraction | +| P2 Felt comparison | Always `.as_canonical_u64()` for `<` `>` `<=` `>=` in business logic | +| P3 Arg limit | Max 4 Words per function — pass by reference | +| P4 Storage API | Use `StorageValue` / `StorageMap` with `WordValue` / `WordKey` | +| P5 Storage names | `package_or_name::component_struct::field` | +| P6 No-std | `#![no_std]` + `#![feature(alloc_error_handler)]` | +| P7 Asset ABI | Use `asset.key` + `asset.value`, not `asset.inner` | +| P8 Recipient builder | Use `note::build_recipient(...)` | +| P9 P2ID root | Verify digest after dependency updates | diff --git a/.claude/skills/rust-sdk-source-guide/SKILL.md b/.claude/skills/rust-sdk-source-guide/SKILL.md index 14285ad..fa4777a 100644 --- a/.claude/skills/rust-sdk-source-guide/SKILL.md +++ b/.claude/skills/rust-sdk-source-guide/SKILL.md @@ -29,6 +29,7 @@ This is the single highest-leverage practice for AI-assisted Miden development. - `Recipient::compute(...)` -> `note::build_recipient(...)` - `Value` -> `StorageValue` - `StorageMap` -> `StorageMap` + - `active_note::get_inputs()` -> `active_note::get_storage()` 3. Search the source repos for a working example of the pattern that failed 4. Adapt the working pattern to your use case 5. Rebuild @@ -84,8 +85,8 @@ git clone --depth 1 --branch main https://github.com/0xMiden/compiler.git ../com # Required: contains client API for deployment and chain interaction git clone --depth 1 --branch main https://github.com/0xMiden/miden-client.git ../miden-client -# Recommended: complete working banking app with advanced patterns in the `examples/miden-bank` folder of the tutorials repo -git clone --branch main https://github.com/0xMiden/tutorials.git ../tutorials +# Recommended: complete working banking app with advanced patterns +git clone --branch main https://github.com/keinberger/miden-bank.git ../miden-bank ``` **Note**: These commands clone the stable `main` branch. Only use `--branch next` if the user explicitly requests the experimental/upcoming version of the compiler or source repos. @@ -162,8 +163,7 @@ Accounts can include standard components (BasicWallet, authentication) alongside Create output notes (like P2ID) from within contract code. Requires building a recipient with `note::build_recipient(serial_num, script_root, storage)` and then using `output_note::create(...)`. The `miden-bank/` withdraw pattern demonstrates this end-to-end. ### Note Storage Protocol -Notes receive storage data as `Vec` which is deserialized into the note object. In the `#[note_script]` method the `self` is deserialized from the note storage (`active_note::get_storage()`). -Attached assets are separate and should be read with `active_note::get_assets()`. +Pass structured data to notes via `Vec` storage. Define your storage layout, document the field ordering, and parse it with `active_note::get_storage()` in the `#[note_script]` function. Attached assets are separate and should be read with `active_note::get_assets()`. ### Atomic Swaps The standard SwapNote in `miden-base/` creates a payback P2ID note automatically when consumed. Explore the SwapNote builder to understand tag construction, storage layout, and the payback mechanism. diff --git a/.claude/skills/rust-sdk-testing-patterns/SKILL.md b/.claude/skills/rust-sdk-testing-patterns/SKILL.md index 5cceed3..d93dda0 100644 --- a/.claude/skills/rust-sdk-testing-patterns/SKILL.md +++ b/.claude/skills/rust-sdk-testing-patterns/SKILL.md @@ -1,6 +1,6 @@ --- name: rust-sdk-testing-patterns -description: Guide to testing Miden smart contracts with MockChain. Covers test setup, contract building, account/note creation, transaction execution, storage verification, faucet setup, output note verification, block numbering, multi-transaction tests, and asset-bearing notes. Use when writing, editing, or debugging Miden integration tests. +description: Guide to testing Miden smart contracts with MockChain. Covers test setup, contract building, account/note creation, transaction execution, storage verification, faucet setup, and output note verification. Use when writing, editing, or debugging Miden integration tests. --- # Miden Testing Patterns (MockChain) @@ -15,27 +15,25 @@ See [counter_test.rs](../../../integration/tests/counter_test.rs) for a complete ### 1. Initialize MockChain Builder -See [counter_test.rs](../../../integration/tests/counter_test.rs) line 21 for the pattern: `let mut builder = MockChain::builder();` +See [counter_test.rs](../../../integration/tests/counter_test.rs) line 17 for the pattern: `let mut builder = MockChain::builder();` ### 2. Create Sender/Wallet Accounts -See [counter_test.rs](../../../integration/tests/counter_test.rs) lines 24-26 for the basic wallet pattern. For wallets with pre-funded assets, use `builder.add_existing_wallet_with_assets(Auth::BasicAuth { auth_scheme: AuthSchemeId::Falcon512Poseidon2 }, [FungibleAsset::new(faucet.id(), 100)?.into()])`. +See [counter_test.rs](../../../integration/tests/counter_test.rs) line 20 for the basic wallet pattern. For wallets with pre-funded assets, use `builder.add_existing_wallet_with_assets(Auth::BasicAuth, [FungibleAsset::new(faucet.id(), 100)?.into()])`. ### 3. Set Up Faucets (for fungible assets) ```rust let faucet = builder.add_existing_basic_faucet( - Auth::BasicAuth { - auth_scheme: AuthSchemeId::Falcon512Poseidon2, - }, + Auth::BasicAuth, "TOKEN", // token symbol 1000, // max supply - Some(10), // total_issuance (None for 0) + Some(10), // decimals (None for 0) )?; ``` ### 4. Build Contracts -See [counter_test.rs](../../../integration/tests/counter_test.rs) lines 29-35 for the pattern using `build_project_in_dir`. +See [counter_test.rs](../../../integration/tests/counter_test.rs) lines 23-30 for the pattern using `build_project_in_dir`. ### 5. Create Account with Storage @@ -50,60 +48,45 @@ Examples: Rule: Replace characters outside `[A-Za-z0-9_]` with `_` in the package or component name. -See [counter_test.rs](../../../integration/tests/counter_test.rs) lines 38-54 for the current pattern: populate `InitStorageData`, build the component from the compiled package, then register the account with `builder.add_account_from_builder(...)`. - -```rust -let counter_storage_slot = counter_storage_slot()?; -let mut init_storage_data = InitStorageData::default(); -init_storage_data.insert_map_entry(counter_storage_slot.clone(), COUNTER_STORAGE_KEY, 0_u64)?; - -let counter_component = - AccountComponent::from_package(&contract_package, &init_storage_data)?; -let counter_account = builder.add_account_from_builder( - Auth::BasicAuth { - auth_scheme: AuthSchemeId::Falcon512Poseidon2, - }, - AccountBuilder::new([3_u8; 32]) - .account_type(AccountType::RegularAccountImmutableCode) - .storage_mode(AccountStorageMode::Public) - .with_component(counter_component), - AccountState::Exists, -)?; -``` +See [counter_test.rs](../../../integration/tests/counter_test.rs) lines 33-51 for a complete StorageMap example with `StorageSlotName`, `StorageSlot::with_map`, `AccountCreationConfig`, and `create_testing_account_from_package`. For a single-value contract slot (paired with `StorageValue` on-chain) instead of a map: ```rust -let mut init_storage_data = InitStorageData::default(); -init_storage_data.insert_value( - "miden_bank_account::bank_account::initialized", - 0_u64, -)?; +let value_slot_name = StorageSlotName::new("miden_bank_account::bank_account::initialized").unwrap(); +let storage_slots = vec![StorageSlot::with_value( + value_slot_name.clone(), + Word::default(), +)]; ``` ### 6. Create Notes -See [counter_test.rs](../../../integration/tests/counter_test.rs) lines 56-64 for basic note creation with `RandomCoin`, `NoteScript::from_package`, and `NoteBuilder`. +See [counter_test.rs](../../../integration/tests/counter_test.rs) lines 54-58 for basic note creation with `create_testing_note_from_package`. For notes with assets and inputs: ```rust -use miden_client::{asset::FungibleAsset, crypto::RandomCoin, note::NoteScript, Felt}; -use miden_standards::testing::note::NoteBuilder; - -let mut note_rng = RandomCoin::new(NoteScript::from_package(note_package.as_ref())?.root()); -let note = NoteBuilder::new(sender.id(), &mut note_rng) - .package((*note_package).clone()) - .add_assets([FungibleAsset::new(faucet.id(), 50)?.into()]) - .note_storage([Felt::new(42), Felt::new(0)])? - .build()?; +use miden_client::note::NoteAssets; +use miden_standards::notes::FungibleAsset; + +let note_assets = NoteAssets::new(vec![FungibleAsset::new(faucet.id(), 50)?.into()])?; +let note = create_testing_note_from_package( + note_package.clone(), + sender.id(), + NoteCreationConfig { + assets: note_assets, + inputs: vec![Felt::new(42), Felt::new(0)], + ..Default::default() + }, +)?; ``` ### 7. Add to MockChain and Build -See [counter_test.rs](../../../integration/tests/counter_test.rs) lines 66-70 for seeding the note and building the mock chain. `add_account_from_builder(...)` has already registered the account in the builder, so at this stage you usually only need to add notes. +See [counter_test.rs](../../../integration/tests/counter_test.rs) lines 61-65 for adding accounts, notes, and building the mock chain. ### 8. Execute Transaction -See [counter_test.rs](../../../integration/tests/counter_test.rs) lines 73-82 for the full execution flow: `build_tx_context` -> `execute()` -> `add_pending_executed_transaction()` -> `prove_next_block()`. For the default MockChain flow, do not call `apply_delta()`; fetch refreshed state from `mock_chain.committed_account(...)` after the block is proven. +See [counter_test.rs](../../../integration/tests/counter_test.rs) lines 67-79 for the full execution flow: `build_tx_context` -> `execute()` -> `apply_delta()` -> `add_pending_executed_transaction()` -> `prove_next_block()`. ### 9. Execute with Transaction Script ```rust @@ -116,69 +99,72 @@ let tx_script_package = Arc::new(build_project_in_dir( let program = tx_script_package.unwrap_program(); let tx_script = TransactionScript::new((*program).clone()); -let executed = mock_chain - .build_tx_context(account.clone(), &[], &[])? +let tx_context = mock_chain + .build_tx_context(account.id(), &[], &[])? .tx_script(tx_script) - .build()? - .execute() - .await?; + .build()?; +let executed = tx_context.execute().await?; +account.apply_delta(executed.account_delta())?; mock_chain.add_pending_executed_transaction(&executed)?; mock_chain.prove_next_block()?; - -let updated_account = mock_chain.committed_account(account.id())?; ``` ### 10. Verify Storage State -See [counter_test.rs](../../../integration/tests/counter_test.rs) lines 84-96 for reading the committed account state and asserting on the result. +See [counter_test.rs](../../../integration/tests/counter_test.rs) lines 82-92 for reading a StorageMap value and asserting on the result. ### 11. Verify Output Notes - -**Important**: `add_output_note()` is only available on `MockChainBuilder` (before `build()`) — use it to seed the chain with existing notes. To verify output notes from a transaction, use `extend_expected_output_notes()` on `TxContextBuilder`: - ```rust -use miden_client::{note::{Note, NoteAssets, NoteMetadata, NoteRecipient}, transaction::RawOutputNote}; +use miden_client::note::{Note, NoteAssets, NoteMetadata, NoteRecipient}; let expected_note = Note::new(expected_assets, expected_metadata, expected_recipient); let tx_context = mock_chain .build_tx_context(account.id(), &[note.id()], &[])? - .extend_expected_output_notes(vec![RawOutputNote::Full(expected_note)]) + .extend_expected_output_notes(vec![OutputNote::Full(expected_note)]) .build()?; // execute() will verify output notes match let executed = tx_context.execute().await?; ``` -## Multi-Transaction Test Pattern - -For contracts requiring initialization before use, each step usually needs its own `execute()` → `add_pending_executed_transaction()` → `prove_next_block()` cycle. Fetch the committed account or note state from `mock_chain` between steps before building the next context. - -`apply_delta()` is only needed in advanced same-block tests that intentionally reuse an in-memory `Account` across multiple transactions before proving the block. - -See [miden-bank withdraw_test.rs](https://github.com/0xMiden/tutorials/blob/main/examples/miden-bank/integration/tests/withdraw_test.rs) for a complete multi-transaction test demonstrating: initialize bank → deposit assets → withdraw assets (3 sequential transactions with state verification between each step). - -See [miden-bank deposit_test.rs](https://github.com/0xMiden/tutorials/blob/main/examples/miden-bank/integration/tests/deposit_test.rs) for an end-to-end asset-bearing note test. - -## MockChain Block Numbering +## Multi-Step Test Pattern -Genesis is block 0. Each `prove_next_block()` advances the block number by 1. In contract code, `tx::get_block_number()` returns the **reference block** — the last proven block at the time the transaction started, not the block the transaction will be included in. +For contracts requiring initialization before use: -## Note Construction - -Prefer `NoteBuilder` (or mirror its logic with compiled `.masp` package files) for creating notes in tests. Start from `NoteBuilder::new(sender.id(), &mut note_rng)`, then configure `.package(...)`, optional `.add_assets(...)`, optional `.note_storage(...)`, and finally `.build()`. See [counter_test.rs](../../../integration/tests/counter_test.rs) for the working pattern. - -## Asset-Bearing Note Example - -To create a note that carries fungible assets in tests: - -1. Create a `FungibleAsset` from a faucet ID and amount. -2. Seed a `RandomCoin` from `NoteScript::from_package(note_package.as_ref())?.root()`. -3. Pass the asset into `NoteBuilder::add_assets(...)` and any note inputs into `note_storage(...)`. -4. Finish with `.package((*note_package).clone()).build()?`. - -The faucet must be set up first (see Step 3) and the sender wallet must hold sufficient assets (see Step 2). +```rust +#[tokio::test] +async fn multi_step_test() -> anyhow::Result<()> { + let mut builder = MockChain::builder(); + // ... setup ... + let mut mock_chain = builder.build()?; + + // Step 1: Initialize (via tx script) + let init_tx_context = mock_chain + .build_tx_context(account.id(), &[], &[])? + .tx_script(init_script) + .build()?; + let executed_init = init_tx_context.execute().await?; + account.apply_delta(executed_init.account_delta())?; + mock_chain.add_pending_executed_transaction(&executed_init)?; + mock_chain.prove_next_block()?; + + // Step 2: Main operation (via note consumption) + let tx_context = mock_chain + .build_tx_context(account.id(), &[note.id()], &[])? + .build()?; + let executed = tx_context.execute().await?; + account.apply_delta(executed.account_delta())?; + mock_chain.add_pending_executed_transaction(&executed)?; + mock_chain.prove_next_block()?; + + // Step 3: Verify state + // ... + + Ok(()) +} +``` ## Key Dependencies @@ -189,8 +175,7 @@ See [integration/Cargo.toml](../../../integration/Cargo.toml) for the current de - [ ] Test function is `async` and uses `#[tokio::test]` - [ ] Storage slot names follow `package_or_name::component_struct::field_name` pattern - [ ] All contracts built before account/note creation -- [ ] Account storage seeded via `InitStorageData` +- [ ] `apply_delta()` called after each `execute()` - [ ] `prove_next_block()` called after `add_pending_executed_transaction()` -- [ ] Post-block assertions read state from `mock_chain.committed_account(...)` or other committed chain views -- [ ] Notes added to `MockChainBuilder` via `add_output_note(RawOutputNote::Full(...))` before `build()` +- [ ] Notes added to builder via `add_output_note(OutputNote::Full(...))` - [ ] Faucet set up before creating assets diff --git a/Cargo.lock b/Cargo.lock index 73a2aaa..77cc688 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -472,9 +472,9 @@ dependencies = [ [[package]] name = "cargo-miden" -version = "0.8.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30f09004aa4b92f7a56924a76aae792f4adcae3adcac46ac384e73cea3827694" +checksum = "16dd37db0856097b45d02483f9f7969d6a7d7a74f4316e0e4aab21ee2cc32389" dependencies = [ "anyhow", "cargo_metadata", @@ -2208,6 +2208,7 @@ dependencies = [ "miden-protocol", "miden-remote-prover-client", "miden-standards", + "miden-testing", "miden-tx", "miette", "prost", @@ -2223,6 +2224,7 @@ dependencies = [ "tonic-prost-build", "tonic-web-wasm-client", "tracing", + "uuid", "web-sys", ] @@ -2747,9 +2749,9 @@ dependencies = [ [[package]] name = "midenc-codegen-masm" -version = "0.8.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ddea2c6050fea142e4f8c526c55bf3656c69c80e66bd099dd79728bdccda12f" +checksum = "e8f6077b02b2a13cd32e5d8d2f9544956ff97ce620eb8a5f5bc97c45dcf415f5" dependencies = [ "anyhow", "inventory", @@ -2777,9 +2779,9 @@ dependencies = [ [[package]] name = "midenc-compile" -version = "0.8.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927ad8e3f4f47949ae63cad358bcf510634765726e57f677c4d1cddadd8233ee" +checksum = "5de61df7d6ac8e056ef19896ff967dd859d40a416f91f4f60ea7c1a0c9061664" dependencies = [ "anyhow", "clap", @@ -2800,9 +2802,9 @@ dependencies = [ [[package]] name = "midenc-dialect-arith" -version = "0.8.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "015e5132f919666624203c2a7d355a757a1265c419d385acc7ff8478b2a3edfe" +checksum = "9fa4be06a8cd187e7d9b25ab4b3c6dad83cb991383e26da00275c70d529548b6" dependencies = [ "midenc-hir", "paste", @@ -2810,9 +2812,9 @@ dependencies = [ [[package]] name = "midenc-dialect-cf" -version = "0.8.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd32b0180d00707f0d2d6050c4cd24f0fa2ef3093a643dbdbf31792ded9cdef" +checksum = "a3e229db2ad095f1f34d3a142718dc7f1ac866016e13c6efcd0bb3238d866c23" dependencies = [ "log", "midenc-dialect-arith", @@ -2821,9 +2823,9 @@ dependencies = [ [[package]] name = "midenc-dialect-hir" -version = "0.8.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb7333ca7996df3809cdbabc66b840e80bff44924570823adf218a1af4364ad0" +checksum = "b379e766985819b45322cb96faf9847ed38aa7bd6fd5a0776dc10d577e64733a" dependencies = [ "log", "midenc-dialect-arith", @@ -2835,9 +2837,9 @@ dependencies = [ [[package]] name = "midenc-dialect-scf" -version = "0.8.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32798b83efc34a7301f6fdf77c622ef5217d4dbed1fe68c62e2c7d07686964d0" +checksum = "4904a0d020c26ef4463424c300729bbb30c3f5d64dc83e00862c98c371e87670" dependencies = [ "bitvec", "log", @@ -2850,18 +2852,18 @@ dependencies = [ [[package]] name = "midenc-dialect-ub" -version = "0.8.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b3327a327fc4a13a08a2d9791b0cba5ef21e0c4ce2a4e18433d363c8c8dc47" +checksum = "f95175939c0f026e906186b77bf6ccc30667cfae8b08f365c2fa5bec98333c37" dependencies = [ "midenc-hir", ] [[package]] name = "midenc-dialect-wasm" -version = "0.8.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c3284470339b901630d30c87c7d5fff962f41dc863c8979867664040ea07552" +checksum = "89ca8945bd0a7816c7703bd07319931ca02b91f07e7e7983e640e51a8a7919e4" dependencies = [ "midenc-dialect-arith", "midenc-dialect-hir", @@ -2870,9 +2872,9 @@ dependencies = [ [[package]] name = "midenc-frontend-wasm" -version = "0.8.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cee10db6ca611ca6e829a8625e179135dc729118974ec65006f8d17120a713a1" +checksum = "43fae37430ad4c05666dd72413a4e09f6fae0dcfd536f85372ae349c361e6d11" dependencies = [ "addr2line 0.24.2", "anyhow", @@ -2887,7 +2889,6 @@ dependencies = [ "midenc-dialect-hir", "midenc-dialect-ub", "midenc-dialect-wasm", - "midenc-frontend-wasm-metadata", "midenc-hir", "midenc-hir-symbol", "midenc-session", @@ -2895,21 +2896,11 @@ dependencies = [ "wasmprinter", ] -[[package]] -name = "midenc-frontend-wasm-metadata" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6938fd4efb4a2c8937c77055a3779ddda33572728328cf4391d2f240f78be3a" -dependencies = [ - "serde", - "serde_json", -] - [[package]] name = "midenc-hir" -version = "0.8.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51141b60afe741ff47d8d95d8b7f9a8eeb32154257181aa73ef59b7f8cbaf759" +checksum = "b23578c2fe9906f459a3a1d50ea125d1093fdc43e46f5c48168b72c28ebe4743" dependencies = [ "anyhow", "base64", @@ -2939,9 +2930,9 @@ dependencies = [ [[package]] name = "midenc-hir-analysis" -version = "0.8.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc8c3b28addc2560dc4b7cf4b4297ce5119bfaf645542f96e0d9f93bcee20f0" +checksum = "a41689f2b52c1dbd03bb94d3e6d498f20cb68ae21d3f38282ec5402103acc6ab" dependencies = [ "bitvec", "blink-alloc", @@ -2951,9 +2942,9 @@ dependencies = [ [[package]] name = "midenc-hir-macros" -version = "0.8.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea4df411507d77af2b7ea70fd8e8a7e67272bbcb4a248386a647673cb9e19d97" +checksum = "0ed0413089b9139dbb888bb9aef514d9bf7d0938c024968c6c21a6cae5340a15" dependencies = [ "Inflector", "darling", @@ -2964,9 +2955,9 @@ dependencies = [ [[package]] name = "midenc-hir-symbol" -version = "0.8.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e212c781c59429229ba6a33d75151257175d88f722a60c333a855a790ca61b" +checksum = "9d6b39f97813438f6cbecfd91781f90890d869f3bf7d29c8f3ca9c5263b53b8f" dependencies = [ "Inflector", "compact_str", @@ -2980,9 +2971,9 @@ dependencies = [ [[package]] name = "midenc-hir-transform" -version = "0.8.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e1483fa0bb318eaf9b112b99280afecf917bf277a026774bf5db7db9c8964d3" +checksum = "811895c7674eb8e1d9056b4a0e6907c91546589e951d2b3318ae6113bbc7317a" dependencies = [ "log", "midenc-hir", @@ -3006,9 +2997,9 @@ dependencies = [ [[package]] name = "midenc-log" -version = "0.8.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7463ae49be6e3612436bbe6af937112a23fb27d9c4e4cfb5b49c281b3b9f1b63" +checksum = "0c254024e5cc30a4b2ac95e3d4b628a715e2de0e6d7b3fb056d9ac7e115ce301" dependencies = [ "anstream 0.6.21", "anstyle", @@ -3019,9 +3010,9 @@ dependencies = [ [[package]] name = "midenc-session" -version = "0.8.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6895a782776dbba38034f6db4869da700e6b685a147869135c0b0ba86d38bdf" +checksum = "8b1c66774ceb89d0dbbd79410c2084cb877b09d0bb62a33548a645e9b7e1886a" dependencies = [ "anyhow", "clap", @@ -5457,6 +5448,18 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "uuid" +version = "1.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9" +dependencies = [ + "getrandom 0.4.2", + "js-sys", + "serde_core", + "wasm-bindgen", +] + [[package]] name = "valuable" version = "0.1.1" diff --git a/contracts/counter-account/Cargo.lock b/contracts/counter-account/Cargo.lock index abd7dcb..1871862 100644 --- a/contracts/counter-account/Cargo.lock +++ b/contracts/counter-account/Cargo.lock @@ -945,9 +945,9 @@ checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "miden" -version = "0.12.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76174f46c7bd1aaf25163cb6c4cf6d9bdb1993d5466ba543c1d6c343a080b767" +checksum = "010a8120478c5bbffa3ff1f139a01bac789331fbfef5a30f5ee6fd467225d3a2" dependencies = [ "miden-base", "miden-base-macros", @@ -1010,9 +1010,9 @@ dependencies = [ [[package]] name = "miden-base" -version = "0.12.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45eaf65ed9fc03898e162c9ff9649079568075543a7bcac474f3befe1ec10ad2" +checksum = "c0cab3453f9574645a7e0ace17aa87998ebe9efde5ae2291ad9a310d6051aa0e" dependencies = [ "miden-base-sys", "miden-stdlib-sys", @@ -1020,14 +1020,12 @@ dependencies = [ [[package]] name = "miden-base-macros" -version = "0.12.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52bebbd631f689028da59d3c1259cb1e8309e9c59cf0a9a625a98e057bebdfe" +checksum = "e6389b82f5b125fd5c02fbf057e2d801aed3e4b3a22b73ca27601f5546343abe" dependencies = [ "heck", - "miden-formatting", "miden-protocol", - "midenc-frontend-wasm-metadata", "proc-macro2", "quote", "semver 1.0.27", @@ -1039,9 +1037,9 @@ dependencies = [ [[package]] name = "miden-base-sys" -version = "0.12.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74c8466611116cc47e620705c32624d9a4de0dd777ef95f03219d5580e93bcaf" +checksum = "842a10d5a6f4b4710356c5cd026400eb901f380e4e445e6bfb084985963b0f88" dependencies = [ "miden-field-repr", "miden-stdlib-sys", @@ -1189,9 +1187,9 @@ dependencies = [ [[package]] name = "miden-field-repr" -version = "0.12.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dba0d085dfb109ebe2a9a6b1acb014f417ae8bfebb17845991ba1c215036822" +checksum = "5c87de3a3d7535308e525fb8407defd4e7a169c6af575e148538b83800ffc6d2" dependencies = [ "miden-core", "miden-field 0.22.6", @@ -1200,9 +1198,9 @@ dependencies = [ [[package]] name = "miden-field-repr-derive" -version = "0.12.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "489216f38e837d9b9a1ad66524649b92ab0fcd7d90662e52952fc56e8703d305" +checksum = "e3f1c00fe41ffa413b0ad36236e1016a64125162703f7be985d79f8dff3f7dba" dependencies = [ "proc-macro2", "quote", @@ -1325,9 +1323,9 @@ dependencies = [ [[package]] name = "miden-sdk-alloc" -version = "0.12.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e9824b7e7297619902c6cb73d71db08434ac07a24ca5a167e8647352698c2e" +checksum = "e43d6123657c5ddd606ef3d36bb1bacd345abcfdbc2ca9b0cab8e839e63558f2" [[package]] name = "miden-serde-utils" @@ -1351,9 +1349,9 @@ dependencies = [ [[package]] name = "miden-stdlib-sys" -version = "0.12.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44231388ca9ed654bc84e71ff2daca69fb353997066bdf8ebe19b1cf80330b53" +checksum = "0c0fad7b45aa92ca52a7fb15b20cb2be0eec1472bd36a1f20cc10d649507919d" dependencies = [ "miden-field 0.22.6", ] @@ -1419,16 +1417,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "midenc-frontend-wasm-metadata" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6938fd4efb4a2c8937c77055a3779ddda33572728328cf4391d2f240f78be3a" -dependencies = [ - "serde", - "serde_json", -] - [[package]] name = "midenc-hir-type" version = "0.5.3" diff --git a/contracts/increment-note/Cargo.lock b/contracts/increment-note/Cargo.lock index ec0e6da..e42d7b9 100644 --- a/contracts/increment-note/Cargo.lock +++ b/contracts/increment-note/Cargo.lock @@ -945,9 +945,9 @@ checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "miden" -version = "0.12.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76174f46c7bd1aaf25163cb6c4cf6d9bdb1993d5466ba543c1d6c343a080b767" +checksum = "010a8120478c5bbffa3ff1f139a01bac789331fbfef5a30f5ee6fd467225d3a2" dependencies = [ "miden-base", "miden-base-macros", @@ -1010,9 +1010,9 @@ dependencies = [ [[package]] name = "miden-base" -version = "0.12.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45eaf65ed9fc03898e162c9ff9649079568075543a7bcac474f3befe1ec10ad2" +checksum = "c0cab3453f9574645a7e0ace17aa87998ebe9efde5ae2291ad9a310d6051aa0e" dependencies = [ "miden-base-sys", "miden-stdlib-sys", @@ -1020,14 +1020,12 @@ dependencies = [ [[package]] name = "miden-base-macros" -version = "0.12.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52bebbd631f689028da59d3c1259cb1e8309e9c59cf0a9a625a98e057bebdfe" +checksum = "e6389b82f5b125fd5c02fbf057e2d801aed3e4b3a22b73ca27601f5546343abe" dependencies = [ "heck", - "miden-formatting", "miden-protocol", - "midenc-frontend-wasm-metadata", "proc-macro2", "quote", "semver 1.0.27", @@ -1039,9 +1037,9 @@ dependencies = [ [[package]] name = "miden-base-sys" -version = "0.12.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74c8466611116cc47e620705c32624d9a4de0dd777ef95f03219d5580e93bcaf" +checksum = "842a10d5a6f4b4710356c5cd026400eb901f380e4e445e6bfb084985963b0f88" dependencies = [ "miden-field-repr", "miden-stdlib-sys", @@ -1189,9 +1187,9 @@ dependencies = [ [[package]] name = "miden-field-repr" -version = "0.12.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dba0d085dfb109ebe2a9a6b1acb014f417ae8bfebb17845991ba1c215036822" +checksum = "5c87de3a3d7535308e525fb8407defd4e7a169c6af575e148538b83800ffc6d2" dependencies = [ "miden-core", "miden-field 0.22.6", @@ -1200,9 +1198,9 @@ dependencies = [ [[package]] name = "miden-field-repr-derive" -version = "0.12.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "489216f38e837d9b9a1ad66524649b92ab0fcd7d90662e52952fc56e8703d305" +checksum = "e3f1c00fe41ffa413b0ad36236e1016a64125162703f7be985d79f8dff3f7dba" dependencies = [ "proc-macro2", "quote", @@ -1325,9 +1323,9 @@ dependencies = [ [[package]] name = "miden-sdk-alloc" -version = "0.12.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e9824b7e7297619902c6cb73d71db08434ac07a24ca5a167e8647352698c2e" +checksum = "e43d6123657c5ddd606ef3d36bb1bacd345abcfdbc2ca9b0cab8e839e63558f2" [[package]] name = "miden-serde-utils" @@ -1351,9 +1349,9 @@ dependencies = [ [[package]] name = "miden-stdlib-sys" -version = "0.12.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44231388ca9ed654bc84e71ff2daca69fb353997066bdf8ebe19b1cf80330b53" +checksum = "0c0fad7b45aa92ca52a7fb15b20cb2be0eec1472bd36a1f20cc10d649507919d" dependencies = [ "miden-field 0.22.6", ] @@ -1419,16 +1417,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "midenc-frontend-wasm-metadata" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6938fd4efb4a2c8937c77055a3779ddda33572728328cf4391d2f240f78be3a" -dependencies = [ - "serde", - "serde_json", -] - [[package]] name = "midenc-hir-type" version = "0.5.3" diff --git a/integration/Cargo.toml b/integration/Cargo.toml index 897b206..209bfc0 100644 --- a/integration/Cargo.toml +++ b/integration/Cargo.toml @@ -5,7 +5,7 @@ edition.workspace = true [dependencies] cargo-miden = { version = "0.8" } -miden-client = { version = "0.14", features = ["tonic"] } +miden-client = { version = "0.14", features = ["tonic", "testing"] } miden-client-sqlite-store = { version = "0.14", package = "miden-client-sqlite-store" } miden-standards = { version = "0.14", features = ["testing"] } miden-testing = "0.14" diff --git a/integration/src/bin/increment_count.rs b/integration/src/bin/increment_count.rs index 772770b..3192e18 100644 --- a/integration/src/bin/increment_count.rs +++ b/integration/src/bin/increment_count.rs @@ -7,6 +7,11 @@ use integration::helpers::{ use anyhow::{Context, Result}; use miden_client::{account::component::InitStorageData, transaction::TransactionRequestBuilder}; use miden_standards::testing::note::NoteBuilder; +use miden_client::{ + account::{StorageMap, StorageMapKey, StorageSlot, StorageSlotName}, + transaction::TransactionRequestBuilder, + Felt, Word, +}; use std::{path::Path, sync::Arc}; #[tokio::main] diff --git a/integration/src/helpers.rs b/integration/src/helpers.rs index b675f00..9ee1a00 100644 --- a/integration/src/helpers.rs +++ b/integration/src/helpers.rs @@ -1,24 +1,26 @@ //! Common helper functions for scripts and tests -use std::{path::Path, sync::Arc}; +use std::{borrow::Borrow, path::Path, sync::Arc}; use anyhow::{bail, Context, Result}; use cargo_miden::{run, OutputType}; use miden_client::{ account::{ - component::{BasicWallet, InitStorageData, NoAuth}, - Account, AccountBuilder, AccountComponent, AccountStorageMode, AccountType, - StorageSlotName, + component::{AccountComponentMetadata, BasicWallet, InitStorageData, NoAuth}, + Account, AccountBuilder, AccountComponent, AccountId, AccountStorageMode, AccountType, + StorageSlot, StorageSlotName, }, auth::{AuthSchemeId, AuthSecretKey, AuthSingleSig}, builder::ClientBuilder, keystore::{FilesystemKeyStore, Keystore}, + note::{Note, NoteMetadata, NoteRecipient, NoteScript, NoteStorage, NoteTag, NoteType}, rpc::{Endpoint, GrpcClient}, + testing::NoteBuilder, utils::Deserializable, Client, Felt, Word, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; -use miden_mast_package::Package; +use miden_mast_package::{Package, SectionId}; use rand::RngCore; /// Test setup configuration containing initialized client and keystore @@ -128,6 +130,8 @@ pub struct AccountCreationConfig { pub storage_mode: AccountStorageMode, /// Initial component storage data keyed by storage slot schema. pub init_storage_data: InitStorageData, + /// Initial storage slots to seed into the component. + pub storage_slots: Vec, } impl Default for AccountCreationConfig { diff --git a/integration/tests/counter_test.rs b/integration/tests/counter_test.rs index ae0a30a..23e922c 100644 --- a/integration/tests/counter_test.rs +++ b/integration/tests/counter_test.rs @@ -1,4 +1,19 @@ -use std::{path::Path, sync::Arc}; +use anyhow::Context; +use integration::helpers::{ + build_project_in_dir, create_testing_account_from_package, create_testing_note_from_package, + AccountCreationConfig, NoteCreationConfig, +}; + +use miden_client::{ + account::{ + component::InitStorageData, StorageMap, StorageMapKey, StorageSlot, StorageSlotName, + }, + auth::AuthSchemeId, + transaction::RawOutputNote, + Felt, Word, +}; +use miden_testing::{Auth, MockChain}; +use std::{collections::BTreeMap, path::Path, sync::Arc}; use anyhow::Context; use integration::helpers::{build_project_in_dir, counter_storage_slot, COUNTER_STORAGE_KEY}; @@ -64,6 +79,7 @@ async fn counter_test() -> anyhow::Result<()> { .context("failed to build counter note from package")?; // add counter account and note to mockchain + builder.add_account(counter_account.clone())?; builder.add_output_note(RawOutputNote::Full(counter_note.clone())); // Build the mock chain