Skip to content

Commit 0a41c37

Browse files
committed
chore: implement standard utility for creating P2ID notes in web client tutorials
1 parent 889b3c9 commit 0a41c37

File tree

4 files changed

+42
-437
lines changed

4 files changed

+42
-437
lines changed

docs/src/web-client/creating_multiple_notes_tutorial.md

Lines changed: 20 additions & 191 deletions
Original file line numberDiff line numberDiff line change
@@ -106,75 +106,16 @@ export default function Home() {
106106
}
107107
```
108108

109-
## Step 3 — Initalize the WebClient & Define the Note Script 
109+
## Step 3 — Initalize the WebClient
110110

111-
Create the file `lib/multiSendWithDelegatedProver.ts` and add the following code. This snippet defines the P2ID note script, implements the function `multiSendWithDelegatedProver`, and initializes the WebClient along with the delegated prover endpoint.
111+
Create the file `lib/multiSendWithDelegatedProver.ts` and add the following code. This snippet implements the function `multiSendWithDelegatedProver`, and initializes the WebClient along with the delegated prover endpoint.
112112

113113
```
114114
mkdir -p lib
115115
touch lib/multiSendWithDelegatedProver.ts
116116
```
117117

118118
```ts
119-
/**
120-
* P2ID (Pay to ID) Note Script for Miden Network
121-
* Enables creating notes that can be received by specific account IDs
122-
*/
123-
const P2ID_NOTE_SCRIPT = `
124-
use.miden::account
125-
use.miden::account_id
126-
use.miden::note
127-
128-
# ERRORS
129-
# =================================================================================================
130-
131-
const.ERR_P2ID_WRONG_NUMBER_OF_INPUTS="P2ID note expects exactly 2 note inputs"
132-
133-
const.ERR_P2ID_TARGET_ACCT_MISMATCH="P2ID's target account address and transaction address do not match"
134-
135-
#! Pay-to-ID script: adds all assets from the note to the account, assuming ID of the account
136-
#! matches target account ID specified by the note inputs.
137-
#!
138-
#! Requires that the account exposes:
139-
#! - miden::contracts::wallets::basic::receive_asset procedure.
140-
#!
141-
#! Inputs: []
142-
#! Outputs: []
143-
#!
144-
#! Note inputs are assumed to be as follows:
145-
#! - target_account_id is the ID of the account for which the note is intended.
146-
#!
147-
#! Panics if:
148-
#! - Account does not expose miden::contracts::wallets::basic::receive_asset procedure.
149-
#! - Account ID of executing account is not equal to the Account ID specified via note inputs.
150-
#! - The same non-fungible asset already exists in the account.
151-
#! - Adding a fungible asset would result in amount overflow, i.e., the total amount would be
152-
#! greater than 2^63.
153-
begin
154-
# store the note inputs to memory starting at address 0
155-
padw push.0 exec.note::get_inputs
156-
# => [num_inputs, inputs_ptr, EMPTY_WORD]
157-
158-
# make sure the number of inputs is 2
159-
eq.2 assert.err=ERR_P2ID_WRONG_NUMBER_OF_INPUTS
160-
# => [inputs_ptr, EMPTY_WORD]
161-
162-
# read the target account ID from the note inputs
163-
mem_loadw drop drop
164-
# => [target_account_id_prefix, target_account_id_suffix]
165-
166-
exec.account::get_id
167-
# => [account_id_prefix, account_id_suffix, target_account_id_prefix, target_account_id_suffix, ...]
168-
169-
# ensure account_id = target_account_id, fails otherwise
170-
exec.account_id::is_equal assert.err=ERR_P2ID_TARGET_ACCT_MISMATCH
171-
# => []
172-
173-
exec.note::add_note_assets_to_account
174-
# => []
175-
end
176-
`;
177-
178119
export async function multiSendWithDelegatedProver(): Promise<void> {
179120
// Ensure this runs only in a browser context
180121
if (typeof window === "undefined") return console.warn("Run in browser");
@@ -278,31 +219,16 @@ const recipientAddresses = [
278219
"0x67dc56bd0cbe629000006f36d81029",
279220
];
280221

281-
const script = client.compileNoteScript(P2ID_NOTE_SCRIPT);
282-
283222
const assets = new NoteAssets([new FungibleAsset(faucet.id(), BigInt(100))]);
284-
const metadata = new NoteMetadata(
285-
alice.id(),
286-
NoteType.Public,
287-
NoteTag.fromAccountId(alice.id(), NoteExecutionMode.newLocal()),
288-
NoteExecutionHint.always(),
289-
);
290223

291224
const p2idNotes = recipientAddresses.map((addr) => {
292-
let serialNumber = Word.newFromFelts([
293-
new Felt(BigInt(Math.floor(Math.random() * 0x1_0000_0000))),
294-
new Felt(BigInt(Math.floor(Math.random() * 0x1_0000_0000))),
295-
new Felt(BigInt(Math.floor(Math.random() * 0x1_0000_0000))),
296-
new Felt(BigInt(Math.floor(Math.random() * 0x1_0000_0000))),
297-
]);
298-
299-
const acct = AccountId.fromHex(addr);
300-
const inputs = new NoteInputs(new FeltArray([acct.suffix(), acct.prefix()]));
301-
302-
let note = new Note(
225+
const receiverAccountId = AccountId.fromHex(addr);
226+
let note = Note.createP2IDNote(
227+
alice.id(),
228+
receiverAccountId,
303229
assets,
304-
metadata,
305-
new NoteRecipient(serialNumber, script, inputs),
230+
NoteType.Public,
231+
new Felt(BigInt(0)),
306232
);
307233

308234
return OutputNote.full(note);
@@ -328,64 +254,11 @@ Your `lib/multiSendWithDelegatedProver.ts` file sould now look like this:
328254

329255
```ts
330256
/**
331-
* P2ID (Pay to ID) Note Script for Miden Network
332-
* Enables creating notes that can be received by specific account IDs
257+
* Demonstrates multi-send functionality using a delegated prover on the Miden Network
258+
* Creates multiple P2ID (Pay to ID) notes for different recipients
259+
*
260+
* @throws {Error} If the function cannot be executed in a browser environment
333261
*/
334-
const P2ID_NOTE_SCRIPT = `
335-
use.miden::account
336-
use.miden::account_id
337-
use.miden::note
338-
339-
# ERRORS
340-
# =================================================================================================
341-
342-
const.ERR_P2ID_WRONG_NUMBER_OF_INPUTS="P2ID note expects exactly 2 note inputs"
343-
344-
const.ERR_P2ID_TARGET_ACCT_MISMATCH="P2ID's target account address and transaction address do not match"
345-
346-
#! Pay-to-ID script: adds all assets from the note to the account, assuming ID of the account
347-
#! matches target account ID specified by the note inputs.
348-
#!
349-
#! Requires that the account exposes:
350-
#! - miden::contracts::wallets::basic::receive_asset procedure.
351-
#!
352-
#! Inputs: []
353-
#! Outputs: []
354-
#!
355-
#! Note inputs are assumed to be as follows:
356-
#! - target_account_id is the ID of the account for which the note is intended.
357-
#!
358-
#! Panics if:
359-
#! - Account does not expose miden::contracts::wallets::basic::receive_asset procedure.
360-
#! - Account ID of executing account is not equal to the Account ID specified via note inputs.
361-
#! - The same non-fungible asset already exists in the account.
362-
#! - Adding a fungible asset would result in amount overflow, i.e., the total amount would be
363-
#! greater than 2^63.
364-
begin
365-
# store the note inputs to memory starting at address 0
366-
padw push.0 exec.note::get_inputs
367-
# => [num_inputs, inputs_ptr, EMPTY_WORD]
368-
369-
# make sure the number of inputs is 2
370-
eq.2 assert.err=ERR_P2ID_WRONG_NUMBER_OF_INPUTS
371-
# => [inputs_ptr, EMPTY_WORD]
372-
373-
# read the target account ID from the note inputs
374-
mem_loadw drop drop
375-
# => [target_account_id_prefix, target_account_id_suffix]
376-
377-
exec.account::get_id
378-
# => [account_id_prefix, account_id_suffix, target_account_id_prefix, target_account_id_suffix, ...]
379-
380-
# ensure account_id = target_account_id, fails otherwise
381-
exec.account_id::is_equal assert.err=ERR_P2ID_TARGET_ACCT_MISMATCH
382-
# => []
383-
384-
exec.note::add_note_assets_to_account
385-
# => []
386-
end
387-
`;
388-
389262
export async function multiSendWithDelegatedProver(): Promise<void> {
390263
// Ensure this runs only in a browser context
391264
if (typeof window === "undefined") return console.warn("Run in browser");
@@ -413,11 +286,9 @@ export async function multiSendWithDelegatedProver(): Promise<void> {
413286
OutputNote,
414287
} = await import("@demox-labs/miden-sdk");
415288

416-
const client = await WebClient.createClient(
417-
"https://rpc.testnet.miden.io:443",
418-
);
289+
const client = await WebClient.createClient("https://rpc.testnet.miden.io");
419290
const prover = TransactionProver.newRemoteProver(
420-
"https://tx-prover.testnet.miden.io",
291+
"https://tx-prover.devnet.miden.io",
421292
);
422293

423294
console.log("Latest block:", (await client.syncState()).blockNum());
@@ -476,33 +347,16 @@ export async function multiSendWithDelegatedProver(): Promise<void> {
476347
"0x67dc56bd0cbe629000006f36d81029",
477348
];
478349

479-
const script = client.compileNoteScript(P2ID_NOTE_SCRIPT);
480-
481350
const assets = new NoteAssets([new FungibleAsset(faucet.id(), BigInt(100))]);
482-
const metadata = new NoteMetadata(
483-
alice.id(),
484-
NoteType.Public,
485-
NoteTag.fromAccountId(alice.id(), NoteExecutionMode.newLocal()),
486-
NoteExecutionHint.always(),
487-
);
488351

489352
const p2idNotes = recipientAddresses.map((addr) => {
490-
let serialNumber = Word.newFromFelts([
491-
new Felt(BigInt(Math.floor(Math.random() * 0x1_0000_0000))),
492-
new Felt(BigInt(Math.floor(Math.random() * 0x1_0000_0000))),
493-
new Felt(BigInt(Math.floor(Math.random() * 0x1_0000_0000))),
494-
new Felt(BigInt(Math.floor(Math.random() * 0x1_0000_0000))),
495-
]);
496-
497-
const acct = AccountId.fromHex(addr);
498-
const inputs = new NoteInputs(
499-
new FeltArray([acct.suffix(), acct.prefix()]),
500-
);
501-
502-
let note = new Note(
353+
const receiverAccountId = AccountId.fromHex(addr);
354+
let note = Note.createP2IDNote(
355+
alice.id(),
356+
receiverAccountId,
503357
assets,
504-
metadata,
505-
new NoteRecipient(serialNumber, script, inputs),
358+
NoteType.Public,
359+
new Felt(BigInt(0)),
506360
);
507361

508362
return OutputNote.full(note);
@@ -522,28 +376,3 @@ export async function multiSendWithDelegatedProver(): Promise<void> {
522376
console.log("All notes created ✅");
523377
}
524378
```
525-
526-
### Running the example
527-
528-
To run a full working example navigate to the `web-client` directory in the [miden-tutorials](https://github.com/0xMiden/miden-tutorials/) repository and run the web application example:
529-
530-
```bash
531-
cd web-client
532-
pnpm i
533-
pnpm run start
534-
```
535-
536-
### Resetting the `MidenClientDB`
537-
538-
The Miden webclient stores account and note data in the browser. To clear the account and node data in the browser, paste this code snippet into the browser console:
539-
540-
```javascript
541-
(async () => {
542-
const dbs = await indexedDB.databases(); // Get all database names
543-
for (const db of dbs) {
544-
await indexedDB.deleteDatabase(db.name);
545-
console.log(`Deleted database: ${db.name}`);
546-
}
547-
console.log("All databases deleted.");
548-
})();
549-
```

0 commit comments

Comments
 (0)