From 2b101b35277cc7cb1454c9ce59fa188fca4f62a2 Mon Sep 17 00:00:00 2001 From: hukla <129692708+huklaa@users.noreply.github.com> Date: Tue, 11 Aug 2026 18:11:37 +0300 Subject: [PATCH 1/5] fix miden bank deposit name collision --- .../contracts/bank-account/src/lib.rs | 88 +++---------------- 1 file changed, 11 insertions(+), 77 deletions(-) diff --git a/examples/miden-bank/contracts/bank-account/src/lib.rs b/examples/miden-bank/contracts/bank-account/src/lib.rs index 2715184..7ca358b 100644 --- a/examples/miden-bank/contracts/bank-account/src/lib.rs +++ b/examples/miden-bank/contracts/bank-account/src/lib.rs @@ -91,6 +91,9 @@ trait Bank { /// Deposit an asset into the bank for a specific depositor. /// + /// Named `bank_deposit` (not `deposit`) to avoid colliding with the built-in + /// `BasicWallet::deposit` method when FPI bindings are generated. + /// /// The asset is added to the bank's vault and the depositor's /// balance is updated in the mapping. /// @@ -103,7 +106,7 @@ trait Bank { /// Panics if the deposit amount exceeds `MAX_DEPOSIT_AMOUNT`. /// Panics if the resulting balance would exceed `MAX_BALANCE` (u64 overflow). /// Panics if the bank has not been initialized. - fn deposit(&mut self, depositor: AccountId, deposit_asset: Asset); + fn bank_deposit(&mut self, depositor: AccountId, deposit_asset: Asset); /// Withdraw assets back to the depositor. /// @@ -130,64 +133,48 @@ trait Bank { #[component] impl Bank for BankStorage { fn initialize(&mut self) { - // Check not already initialized let current: Word = self.initialized.get(); assert!( current[0].as_canonical_u64() == 0, "Bank already initialized" ); - // Set initialized flag to 1 let initialized_word = Word::from([felt!(1), felt!(0), felt!(0), felt!(0)]); self.initialized.set(initialized_word); } fn get_depositor_balance(&self, depositor: AccountId, asset: Asset) -> Felt { - // Create key from depositor's AccountId and asset faucet ID let key = Word::from([ depositor.prefix, depositor.suffix, - asset.key[3], // faucet_prefix - asset.key[2], // faucet_suffix (+ metadata byte; see `balances` field docs) + asset.key[3], + asset.key[2], ]); self.balances.get(key) } - fn deposit(&mut self, depositor: AccountId, deposit_asset: Asset) { - // Ensure the bank is initialized before accepting deposits + fn bank_deposit(&mut self, depositor: AccountId, deposit_asset: Asset) { self.require_initialized(); - // Verify this is a fungible asset. - // For fungible assets, value = [amount, 0, 0, 0]; value[1] is always 0. - // Non-fungible assets encode payload data into value[1..3], so any non-zero - // cell there means this branch can't safely treat the asset as a fungible amount. assert!( deposit_asset.value[1].as_canonical_u64() == 0, "Only fungible assets are supported" ); - // Extract the fungible amount from the asset value word - // Asset value layout for fungible: [amount, 0, 0, 0] let deposit_amount = deposit_asset.value[0]; - // Validate deposit amount does not exceed maximum assert!( deposit_amount.as_canonical_u64() <= MAX_DEPOSIT_AMOUNT, "Deposit amount exceeds maximum allowed" ); - // Create key from depositor's AccountId and asset faucet ID. - // This allows tracking balances per depositor per asset type. let key = Word::from([ depositor.prefix, depositor.suffix, - deposit_asset.key[3], // faucet_prefix - deposit_asset.key[2], // faucet_suffix (+ metadata byte; see `balances` field docs) + deposit_asset.key[3], + deposit_asset.key[2], ]); - // Update balance in integer space to avoid modular Felt wraparound. - // Felt arithmetic is modular (wraps at the Goldilocks prime), so we - // validate entirely in u64 before storing the result as a Felt. let current_balance: Felt = self.balances.get(key); let current_u64 = current_balance.as_canonical_u64(); let deposit_u64 = deposit_amount.as_canonical_u64(); @@ -201,8 +188,6 @@ impl Bank for BankStorage { ); self.balances.set(key, Felt::new(new_balance_u64).unwrap()); - - // Add asset to the bank's vault native_account::add_asset(deposit_asset); } @@ -213,66 +198,41 @@ impl Bank for BankStorage { tag: Felt, note_type: Felt, ) { - // Ensure the bank is initialized before processing withdrawals self.require_initialized(); - // Identify the depositor from the note's sender — this is cryptographically - // bound to the note metadata, so it cannot be spoofed by a malicious caller. let depositor = active_note::get_sender(); - // Verify this is a fungible asset — see `deposit()` for the rationale. assert!( withdraw_asset.value[1].as_canonical_u64() == 0, "Only fungible assets are supported" ); - // Extract the fungible amount from the asset value word let withdraw_amount = withdraw_asset.value[0]; - // Create key from depositor's AccountId and asset faucet ID let key = Word::from([ depositor.prefix, depositor.suffix, - withdraw_asset.key[3], // faucet_prefix - withdraw_asset.key[2], // faucet_suffix (+ metadata byte; see `balances` field docs) + withdraw_asset.key[3], + withdraw_asset.key[2], ]); - // Get current balance and validate sufficient funds exist. - // This check is critical: Felt arithmetic is modular, so subtracting - // more than the balance would silently wrap to a large positive number. let current_balance: Felt = self.balances.get(key); assert!( current_balance.as_canonical_u64() >= withdraw_amount.as_canonical_u64(), "Withdrawal amount exceeds available balance" ); - // Update balance: current - withdraw_amount let new_balance = current_balance - withdraw_amount; self.balances.set(key, new_balance); - // Read the P2ID script root from the withdraw-request note's storage (items 10-13). - // This avoids hardcoding a version-specific MAST root constant and keeps the - // withdraw function parameter count within the WIT flat-params limit (<= 16). let storage = active_note::get_storage(); let script_root = Word::from([storage[10], storage[11], storage[12], storage[13]]); - // Create a P2ID note to send the requested asset back to the depositor self.create_p2id_note(serial_num, &withdraw_asset, depositor, tag, note_type, script_root); } } -/// Internal helpers that are not part of the component's exported WIT API. -/// -/// The `#[component]` macro exports only the methods of the `Bank` trait, so these -/// inherent methods stay private to the contract. impl BankStorage { - /// Check that the bank is initialized. - /// - /// This internal function is called at the start of operations that require - /// the bank to be initialized (e.g., deposits). - /// - /// # Panics - /// Panics if the bank has not been initialized. fn require_initialized(&self) { let current: Word = self.initialized.get(); assert!( @@ -281,15 +241,6 @@ impl BankStorage { ); } - /// Create a P2ID (Pay-to-ID) note to send assets to a recipient. - /// - /// # Arguments - /// * `serial_num` - Unique serial number for the note - /// * `asset` - The asset to include in the note - /// * `recipient_id` - The AccountId that can consume this note - /// * `tag` - The note tag (passed by caller to allow proper P2ID routing) - /// * `note_type` - Note type as Felt: 1 = Public, 2 = Private - /// * `script_root` - The P2ID note script MAST root (Poseidon2-hashed) fn create_p2id_note( &mut self, serial_num: Word, @@ -299,21 +250,9 @@ impl BankStorage { note_type: Felt, script_root: Word, ) { - // Convert the passed tag Felt to a Tag - // The caller is responsible for computing the proper P2ID tag - // (typically with_account_target for the recipient) let tag = Tag::from(tag); - - // Convert note_type Felt to NoteType - // 1 = Public (stored on-chain), 2 = Private (off-chain) let note_type = NoteType::from(note_type); - // Compute the recipient hash from: - // - serial_num: unique identifier for this note instance - // - script_root: the P2ID note script's MAST root - // - the target account ID [suffix, prefix] - // - // This matches the standard P2ID recipient format used by miden-standards. let recipient = note::build_recipient( serial_num, script_root, @@ -323,13 +262,8 @@ impl BankStorage { ], ); - // Create the output note let note_idx = output_note::create(tag, note_type, recipient); - - // Remove the asset from the bank's vault native_account::remove_asset(*asset); - - // Add the asset to the output note output_note::add_asset(*asset, note_idx); } } From 1b0a9f3963d1f87cbc84b9edcac2afe370dc5cf6 Mon Sep 17 00:00:00 2001 From: hukla <129692708+huklaa@users.noreply.github.com> Date: Tue, 11 Aug 2026 18:13:02 +0300 Subject: [PATCH 2/5] preserve bank contract comments while renaming deposit API --- .../contracts/bank-account/src/lib.rs | 87 +++++++++++++++++-- 1 file changed, 78 insertions(+), 9 deletions(-) diff --git a/examples/miden-bank/contracts/bank-account/src/lib.rs b/examples/miden-bank/contracts/bank-account/src/lib.rs index 7ca358b..a21fdf5 100644 --- a/examples/miden-bank/contracts/bank-account/src/lib.rs +++ b/examples/miden-bank/contracts/bank-account/src/lib.rs @@ -91,8 +91,8 @@ trait Bank { /// Deposit an asset into the bank for a specific depositor. /// - /// Named `bank_deposit` (not `deposit`) to avoid colliding with the built-in - /// `BasicWallet::deposit` method when FPI bindings are generated. + /// Named `bank_deposit` to avoid colliding with the built-in wallet `deposit` + /// method when FPI bindings are generated. /// /// The asset is added to the bank's vault and the depositor's /// balance is updated in the mapping. @@ -133,48 +133,64 @@ trait Bank { #[component] impl Bank for BankStorage { fn initialize(&mut self) { + // Check not already initialized let current: Word = self.initialized.get(); assert!( current[0].as_canonical_u64() == 0, "Bank already initialized" ); + // Set initialized flag to 1 let initialized_word = Word::from([felt!(1), felt!(0), felt!(0), felt!(0)]); self.initialized.set(initialized_word); } fn get_depositor_balance(&self, depositor: AccountId, asset: Asset) -> Felt { + // Create key from depositor's AccountId and asset faucet ID let key = Word::from([ depositor.prefix, depositor.suffix, - asset.key[3], - asset.key[2], + asset.key[3], // faucet_prefix + asset.key[2], // faucet_suffix (+ metadata byte; see `balances` field docs) ]); self.balances.get(key) } fn bank_deposit(&mut self, depositor: AccountId, deposit_asset: Asset) { + // Ensure the bank is initialized before accepting deposits self.require_initialized(); + // Verify this is a fungible asset. + // For fungible assets, value = [amount, 0, 0, 0]; value[1] is always 0. + // Non-fungible assets encode payload data into value[1..3], so any non-zero + // cell there means this branch can't safely treat the asset as a fungible amount. assert!( deposit_asset.value[1].as_canonical_u64() == 0, "Only fungible assets are supported" ); + // Extract the fungible amount from the asset value word + // Asset value layout for fungible: [amount, 0, 0, 0] let deposit_amount = deposit_asset.value[0]; + // Validate deposit amount does not exceed maximum assert!( deposit_amount.as_canonical_u64() <= MAX_DEPOSIT_AMOUNT, "Deposit amount exceeds maximum allowed" ); + // Create key from depositor's AccountId and asset faucet ID. + // This allows tracking balances per depositor per asset type. let key = Word::from([ depositor.prefix, depositor.suffix, - deposit_asset.key[3], - deposit_asset.key[2], + deposit_asset.key[3], // faucet_prefix + deposit_asset.key[2], // faucet_suffix (+ metadata byte; see `balances` field docs) ]); + // Update balance in integer space to avoid modular Felt wraparound. + // Felt arithmetic is modular (wraps at the Goldilocks prime), so we + // validate entirely in u64 before storing the result as a Felt. let current_balance: Felt = self.balances.get(key); let current_u64 = current_balance.as_canonical_u64(); let deposit_u64 = deposit_amount.as_canonical_u64(); @@ -188,6 +204,8 @@ impl Bank for BankStorage { ); self.balances.set(key, Felt::new(new_balance_u64).unwrap()); + + // Add asset to the bank's vault native_account::add_asset(deposit_asset); } @@ -198,41 +216,66 @@ impl Bank for BankStorage { tag: Felt, note_type: Felt, ) { + // Ensure the bank is initialized before processing withdrawals self.require_initialized(); + // Identify the depositor from the note's sender — this is cryptographically + // bound to the note metadata, so it cannot be spoofed by a malicious caller. let depositor = active_note::get_sender(); + // Verify this is a fungible asset — see `bank_deposit()` for the rationale. assert!( withdraw_asset.value[1].as_canonical_u64() == 0, "Only fungible assets are supported" ); + // Extract the fungible amount from the asset value word let withdraw_amount = withdraw_asset.value[0]; + // Create key from depositor's AccountId and asset faucet ID let key = Word::from([ depositor.prefix, depositor.suffix, - withdraw_asset.key[3], - withdraw_asset.key[2], + withdraw_asset.key[3], // faucet_prefix + withdraw_asset.key[2], // faucet_suffix (+ metadata byte; see `balances` field docs) ]); + // Get current balance and validate sufficient funds exist. + // This check is critical: Felt arithmetic is modular, so subtracting + // more than the balance would silently wrap to a large positive number. let current_balance: Felt = self.balances.get(key); assert!( current_balance.as_canonical_u64() >= withdraw_amount.as_canonical_u64(), "Withdrawal amount exceeds available balance" ); + // Update balance: current - withdraw_amount let new_balance = current_balance - withdraw_amount; self.balances.set(key, new_balance); + // Read the P2ID script root from the withdraw-request note's storage (items 10-13). + // This avoids hardcoding a version-specific MAST root constant and keeps the + // withdraw function parameter count within the WIT flat-params limit (<= 16). let storage = active_note::get_storage(); let script_root = Word::from([storage[10], storage[11], storage[12], storage[13]]); + // Create a P2ID note to send the requested asset back to the depositor self.create_p2id_note(serial_num, &withdraw_asset, depositor, tag, note_type, script_root); } } +/// Internal helpers that are not part of the component's exported WIT API. +/// +/// The `#[component]` macro exports only the methods of the `Bank` trait, so these +/// inherent methods stay private to the contract. impl BankStorage { + /// Check that the bank is initialized. + /// + /// This internal function is called at the start of operations that require + /// the bank to be initialized (e.g., deposits). + /// + /// # Panics + /// Panics if the bank has not been initialized. fn require_initialized(&self) { let current: Word = self.initialized.get(); assert!( @@ -241,6 +284,15 @@ impl BankStorage { ); } + /// Create a P2ID (Pay-to-ID) note to send assets to a recipient. + /// + /// # Arguments + /// * `serial_num` - Unique serial number for the note + /// * `asset` - The asset to include in the note + /// * `recipient_id` - The AccountId that can consume this note + /// * `tag` - The note tag (passed by caller to allow proper P2ID routing) + /// * `note_type` - Note type as Felt: 1 = Public, 2 = Private + /// * `script_root` - The P2ID note script MAST root (Poseidon2-hashed) fn create_p2id_note( &mut self, serial_num: Word, @@ -250,9 +302,21 @@ impl BankStorage { note_type: Felt, script_root: Word, ) { + // Convert the passed tag Felt to a Tag + // The caller is responsible for computing the proper P2ID tag + // (typically with_account_target for the recipient) let tag = Tag::from(tag); + + // Convert note_type Felt to NoteType + // 1 = Public (stored on-chain), 2 = Private (off-chain) let note_type = NoteType::from(note_type); + // Compute the recipient hash from: + // - serial_num: unique identifier for this note instance + // - script_root: the P2ID note script's MAST root + // - the target account ID [suffix, prefix] + // + // This matches the standard P2ID recipient format used by miden-standards. let recipient = note::build_recipient( serial_num, script_root, @@ -262,8 +326,13 @@ impl BankStorage { ], ); + // Create the output note let note_idx = output_note::create(tag, note_type, recipient); + + // Remove the asset from the bank's vault native_account::remove_asset(*asset); + + // Add the asset to the output note output_note::add_asset(*asset, note_idx); } -} +} \ No newline at end of file From 29e43c54324d64ea939fdd15abc314eed1d229b1 Mon Sep 17 00:00:00 2001 From: hukla <129692708+huklaa@users.noreply.github.com> Date: Tue, 11 Aug 2026 18:13:15 +0300 Subject: [PATCH 3/5] update deposit note FPI call --- examples/miden-bank/contracts/deposit-note/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/miden-bank/contracts/deposit-note/src/lib.rs b/examples/miden-bank/contracts/deposit-note/src/lib.rs index 5f82e3c..0ff9bc5 100644 --- a/examples/miden-bank/contracts/deposit-note/src/lib.rs +++ b/examples/miden-bank/contracts/deposit-note/src/lib.rs @@ -18,7 +18,7 @@ pub struct Wallet; /// 1. Note is created by a user with fungible assets attached /// 2. Bank account consumes this note /// 3. Note script reads the sender (depositor) and assets -/// 4. For each asset, calls `account.deposit(depositor, asset)` +/// 4. For each asset, calls `account.bank_deposit(depositor, asset)` /// 5. Bank receives the asset and updates the depositor's balance /// /// # Note Inputs @@ -38,7 +38,7 @@ impl DepositNote { // Deposit each asset into the bank for asset in assets { - account.deposit(depositor, asset); + account.bank_deposit(depositor, asset); } } } From 827f87aca21fc7b207aaa148a15e710608af5018 Mon Sep 17 00:00:00 2001 From: hukla <129692708+huklaa@users.noreply.github.com> Date: Tue, 11 Aug 2026 23:06:09 +0300 Subject: [PATCH 4/5] docs: align bank deposit note with collision-safe API --- docs/src/miden-bank/04-note-scripts.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/src/miden-bank/04-note-scripts.md b/docs/src/miden-bank/04-note-scripts.md index 14a2d63..f362854 100644 --- a/docs/src/miden-bank/04-note-scripts.md +++ b/docs/src/miden-bank/04-note-scripts.md @@ -28,7 +28,7 @@ Part 3: Part 4: ┌──────────────────┐ ┌──────────────────┐ │ Bank (complete) │ │ Bank (complete) │ │ ─────────────────│ │ ─────────────────│ -│ + deposit() │ │ + deposit() │ +│ + bank_deposit() │ │ + bank_deposit() │ │ + withdraw() │ │ + withdraw() │ └──────────────────┘ └──────────────────┘ ▲ @@ -154,14 +154,14 @@ impl DepositNote { // Deposit each asset into the bank for asset in assets { - account.deposit(depositor, asset); + account.bank_deposit(depositor, asset); } } } ``` :::info Cross-Component Calls -The `#[account(bank_account::Bank)] pub struct Wallet;` declaration and the `account.deposit(...)` call use Miden's cross-component binding system. The `#[account(...)]` macro wraps the consuming account so the note can call the bank's `Bank` methods directly. We'll explain exactly how this works in [Part 5: Cross-Component Calls](./cross-component-calls). For now, just know that building `bank-account` first generates the WIT files that `deposit-note` binds against. +The `#[account(bank_account::Bank)] pub struct Wallet;` declaration and the `account.bank_deposit(...)` call use Miden's cross-component binding system. The `#[account(...)]` macro wraps the consuming account so the note can call the bank's `Bank` methods directly. We'll explain exactly how this works in [Part 5: Cross-Component Calls](./cross-component-calls). For now, just know that building `bank-account` first generates the WIT files that `deposit-note` binds against. ::: ### The #[note] and #[note_script] Attributes @@ -258,9 +258,9 @@ The Miden compiler prints non-fatal `ERROR` lines about `MAST` serialization on 3. Note script runs depositor = get_sender() → User's AccountId assets = get_assets() → [100 tokens] - account.deposit(depositor, 100 tokens) + account.bank_deposit(depositor, 100 tokens) -4. Bank's deposit() method executes +4. Bank's bank_deposit() method executes - Validates initialization and amount - Updates balance: balances[User] += 100 - Adds asset to vault @@ -546,7 +546,7 @@ impl DepositNote { // Deposit each asset into the bank for asset in assets { - account.deposit(depositor, asset); + account.bank_deposit(depositor, asset); } } } @@ -557,7 +557,7 @@ impl DepositNote { ## Key Takeaways 1. **`#[note]`** marks the struct and impl block, with **`#[note_script]`** on the entry point method `fn run(self, _arg: Word, account: &mut Wallet)` -2. **`#[account(bank_account::Bank)] pub struct Wallet;`** wraps the consuming account so the note can call the bank's methods via `account.deposit(...)` +2. **`#[account(bank_account::Bank)] pub struct Wallet;`** wraps the consuming account so the note can call the bank's methods via `account.bank_deposit(...)` 3. **`active_note::get_sender()`** returns who created the note 4. **`active_note::get_assets()`** returns assets attached to the note 5. **`active_note::get_storage()`** returns parameterized data @@ -573,4 +573,4 @@ See the complete note script implementations: ## Next Steps -Now that you understand note scripts, let's learn how they call account methods in [Part 5: Cross-Component Calls](./cross-component-calls). +Now that you understand note scripts, let's learn how they call account methods in [Part 5: Cross-Component Calls](./cross-component-calls). \ No newline at end of file From bdbb57079ddb1a7f529a9649c0667375f167ffb0 Mon Sep 17 00:00:00 2001 From: hukla <129692708+huklaa@users.noreply.github.com> Date: Wed, 12 Aug 2026 08:02:36 +0300 Subject: [PATCH 5/5] docs: align Part 5 with bank_deposit binding --- .../src/miden-bank/05-cross-component-calls.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/src/miden-bank/05-cross-component-calls.md b/docs/src/miden-bank/05-cross-component-calls.md index d8a6e39..3cf4095 100644 --- a/docs/src/miden-bank/05-cross-component-calls.md +++ b/docs/src/miden-bank/05-cross-component-calls.md @@ -19,7 +19,7 @@ By the end of this section, you will have: ## Building on Part 4 -In Part 4, you wrote `account.deposit(depositor, asset)` in the deposit note. But how does that call actually work? This part explains the binding system: +In Part 4, you wrote `account.bank_deposit(depositor, asset)` in the deposit note. But how does that call actually work? This part explains the binding system: ```text ┌────────────────────────────────────────────────────────────┐ @@ -28,7 +28,7 @@ In Part 4, you wrote `account.deposit(depositor, asset)` in the deposit note. Bu │ │ │ bank-account/ │ │ └── src/lib.rs miden build │ -│ fn deposit() ─────────────▶ generated-wit/ │ +│ fn bank_deposit() ─────────────▶ generated-wit/ │ │ fn withdraw() miden-bank-account.wit │ │ │ ┌───────────────────────────┐ │ @@ -37,7 +37,7 @@ In Part 4, you wrote `account.deposit(depositor, asset)` in the deposit note. Bu │ └── src/lib.rs │ │ │ #[account(bank_account::Bank)] │ │ │ pub struct Wallet; │ │ -│ account.deposit(...) ────────────▶ calls via binding│ +│ account.bank_deposit(...) ─────────▶ calls via binding│ │ │ └────────────────────────────────────────────────────────────┘ ``` @@ -90,7 +90,7 @@ For our bank: - `bank_account` - The package name (derived from `bank-account` with underscores) - `Bank` - The component trait whose methods are exposed on the wrapper -The macro reads the bank account's generated WIT and generates a `Wallet` type whose methods (`deposit`, `withdraw`, `initialize`, `get_depositor_balance`) call into the bank component across the component boundary. +The macro reads the bank account's generated WIT and generates a `Wallet` type whose methods (`bank_deposit`, `withdraw`, `initialize`, `get_depositor_balance`) call into the bank component across the component boundary. ## Calling Account Methods @@ -112,7 +112,7 @@ impl DepositNote { // Deposit each asset into the bank for asset in assets { - account.deposit(depositor, asset); + account.bank_deposit(depositor, asset); } } } @@ -191,7 +191,7 @@ trait Bank { // EXPORTED: Available through bindings fn initialize(&mut self); fn get_depositor_balance(&self, depositor: AccountId, asset: Asset) -> Felt; - fn deposit(&mut self, depositor: AccountId, deposit_asset: Asset); + fn bank_deposit(&mut self, depositor: AccountId, deposit_asset: Asset); fn withdraw(&mut self, withdraw_asset: Asset, serial_num: Word, tag: Felt, note_type: Felt); } ``` @@ -221,7 +221,7 @@ interface bank-account { initialize: func(); get-depositor-balance: func(depositor: account-id, asset: asset) -> felt; - deposit: func(depositor: account-id, deposit-asset: asset); + bank-deposit: func(depositor: account-id, deposit-asset: asset); withdraw: func(withdraw-asset: asset, serial-num: word, tag: felt, note-type: felt); } ``` @@ -265,7 +265,7 @@ miden-bank-account.wit -These files enable the deposit note's `#[account(bank_account::Bank)]` wrapper to call `account.deposit()`. +These files enable the deposit note's `#[account(bank_account::Bank)]` wrapper to call `account.bank_deposit()`. ## Common Issues @@ -285,7 +285,7 @@ error: cannot find module `bindings` ### "Method not found" Error ``` -error: no method named `deposit` found +error: no method named `bank_deposit` found ``` **Cause**: The method isn't declared on the `#[component] trait Bank`. Only trait methods are exported through bindings.