@@ -136,12 +136,10 @@ export async function foreignProcedureInvocation(): Promise<void> {
136136 AccountComponent,
137137 AccountId,
138138 AccountType,
139- AssemblerUtils,
139+ MidenArrays,
140+ SecretKey,
140141 StorageSlot,
141- TransactionKernel,
142142 TransactionRequestBuilder,
143- TransactionScript,
144- TransactionScriptInputPairArray,
145143 ForeignAccount,
146144 AccountStorageRequirements,
147145 WebClient,
@@ -159,62 +157,60 @@ export async function foreignProcedureInvocation(): Promise<void> {
159157
160158 // Count reader contract code in Miden Assembly (exactly from count_reader.masm)
161159 const countReaderCode = `
162- use.miden::account
160+ use.miden::active_account
161+ use miden::native_account
163162 use.miden::tx
164163 use.std::sys
165164
166165 # => [account_id_prefix, account_id_suffix, get_count_proc_hash]
167166 export.copy_count
168167 exec.tx::execute_foreign_procedure
169168 # => [count]
170-
171- debug.stack
172- # => [count]
173-
169+
174170 push.0
175171 # [index, count]
176-
177- exec.account::set_item
178- # => []
179-
180- push.1 exec.account::incr_nonce
172+
173+ debug.stack
174+
175+ exec.native_account::set_item dropw
181176 # => []
182177
183178 exec.sys::truncate_stack
184179 # => []
185180 end
186- ` ;
187-
188- // Prepare assembler (debug mode = true)
189- let assembler = TransactionKernel .assembler ().withDebugMode (true );
181+ ` ;
190182
191- let countReaderComponent = AccountComponent .compile (
183+ const builder = client .createScriptBuilder ();
184+ const countReaderComponent = AccountComponent .compile (
192185 countReaderCode ,
193- assembler ,
186+ builder ,
194187 [StorageSlot .emptyValue ()],
195188 ).withSupportsAllTypes ();
196189
197- const seed = new Uint8Array (32 );
198- crypto .getRandomValues (seed );
190+ const walletSeed = new Uint8Array (32 );
191+ crypto .getRandomValues (walletSeed );
199192
200- let countReaderContract = new AccountBuilder (seed )
193+ const secretKey = SecretKey .rpoFalconWithRNG (walletSeed );
194+ const authComponent = AccountComponent .createAuthComponent (secretKey );
195+
196+ const countReaderContract = new AccountBuilder (walletSeed )
201197 .accountType (AccountType .RegularAccountImmutableCode )
202198 .storageMode (AccountStorageMode .public ())
199+ .withAuthComponent (authComponent )
203200 .withComponent (countReaderComponent )
204201 .build ();
205202
203+ await client .addAccountSecretKeyToWebStore (secretKey );
204+ await client .syncState ();
205+
206206 // Create the count reader contract account (using available WebClient API)
207207 console .log (" Creating count reader contract account..." );
208208 console .log (
209209 " Count reader contract ID:" ,
210210 countReaderContract .account .id ().toString (),
211211 );
212212
213- await client .newAccount (
214- countReaderContract .account ,
215- countReaderContract .seed ,
216- false ,
217- );
213+ await client .newAccount (countReaderContract .account , false );
218214
219215 // -------------------------------------------------------------------------
220216 // STEP 2: Build & Get State of the Counter Contract
@@ -223,7 +219,7 @@ export async function foreignProcedureInvocation(): Promise<void> {
223219
224220 // Define the Counter Contract account id from counter contract deploy (same as Rust)
225221 const counterContractId = AccountId .fromHex (
226- " 0xb32d619dfe9e2f0000010ecb441d3f " ,
222+ " 0xe59d8cd3c9ff2a0055da0b83ed6432 " ,
227223 );
228224
229225 // Import the counter contract
@@ -250,144 +246,131 @@ export async function foreignProcedureInvocation(): Promise<void> {
250246
251247 // Counter contract code (exactly from counter.masm)
252248 const counterContractCode = `
253- use.miden::account
254- use.std::sys
255-
256- # => []
257- export.get_count
258- push.0
259- # => [index]
260-
261- exec.account::get_item
262- # => [count]
263-
264- exec.sys::truncate_stack
265- # => []
266- end
267-
268- # => []
269- export.increment_count
270- push.0
271- # => [index]
272-
273- exec.account::get_item
274- # => [count]
275-
276- push.1 add
277- # => [count+1]
278-
279- # debug statement with client
280- debug.stack
281-
282- push.0
283- # [index, count+1]
284-
285- exec.account::set_item
286- # => []
287-
288- push.1 exec.account::incr_nonce
289- # => []
290-
291- exec.sys::truncate_stack
292- # => []
293- end
294- ` ;
249+ use.miden::active_account
250+ use miden::native_account
251+ use.std::sys
252+
253+ const.COUNTER_SLOT=0
254+
255+ #! Inputs: []
256+ #! Outputs: [count]
257+ export.get_count
258+ push.COUNTER_SLOT
259+ # => [index]
260+
261+ exec.active_account::get_item
262+ # => [count]
263+
264+ # clean up stack
265+ movdn.4 dropw
266+ # => [count]
267+ end
268+
269+ #! Inputs: []
270+ #! Outputs: []
271+ export.increment_count
272+ push.COUNTER_SLOT
273+ # => [index]
274+
275+ exec.active_account::get_item
276+ # => [count]
277+
278+ add.1
279+ # => [count+1]
280+
281+ debug.stack
282+
283+ push.COUNTER_SLOT
284+ # [index, count+1]
285+
286+ exec.native_account::set_item
287+ # => [OLD_VALUE]
288+
289+ dropw
290+ # => []
291+ end
292+ ` ;
295293
296294 // Create the counter contract component to get the procedure hash (following Rust pattern)
297- let counterContractComponent = AccountComponent .compile (
295+ const counterContractComponent = AccountComponent .compile (
298296 counterContractCode ,
299- assembler ,
300- [],
297+ builder ,
298+ [StorageSlot . emptyValue () ],
301299 ).withSupportsAllTypes ();
302300
303- let getCountProcHash = counterContractComponent .getProcedureHash (" get_count" );
301+ const getCountProcHash =
302+ counterContractComponent .getProcedureHash (" get_count" );
304303
305304 // Build the script that calls the count reader contract (exactly from reader_script.masm with replacements)
306- let fpiScriptCode = `
305+ const fpiScriptCode = `
307306 use.external_contract::count_reader_contract
308307 use.std::sys
309308
310309 begin
311- push.${getCountProcHash }
312- # => [GET_COUNT_HASH]
310+ push.${getCountProcHash }
311+ # => [GET_COUNT_HASH]
313312
314- push.${counterContractAccount .id ().suffix ()}
315- # => [account_id_suffix, GET_COUNT_HASH]
313+ push.${counterContractAccount .id ().suffix ()}
314+ # => [account_id_suffix, GET_COUNT_HASH]
316315
317- push.${counterContractAccount .id ().prefix ()}
318- # => [account_id_prefix, account_id_suffix, GET_COUNT_HASH]
316+ push.${counterContractAccount .id ().prefix ()}
317+ # => [account_id_prefix, account_id_suffix, GET_COUNT_HASH]
319318
320- call.count_reader_contract::copy_count
321- # => []
319+ call.count_reader_contract::copy_count
320+ # => []
322321
323- exec.sys::truncate_stack
324- # => []
322+ exec.sys::truncate_stack
323+ # => []
325324
326325 end
327- ` ;
328-
329- console .log (" fpiScript" , fpiScriptCode );
330-
331- // Empty inputs to the transaction script
332- const inputs = new TransactionScriptInputPairArray ();
326+ ` ;
333327
334328 // Create the library for the count reader contract
335- let countReaderLib = AssemblerUtils .createAccountComponentLibrary (
336- assembler ,
329+ const countReaderLib = builder .buildLibrary (
337330 " external_contract::count_reader_contract" ,
338331 countReaderCode ,
339332 );
340-
333+ builder .linkDynamicLibrary (countReaderLib );
334+ .
341335 // Compile the transaction script with the count reader library
342- let txScript = TransactionScript .compile (
343- fpiScriptCode ,
344- assembler .withLibrary (countReaderLib ),
345- );
336+ const txScript = builder .compileTxScript (fpiScriptCode );
346337
347338 // foreign account
348- let storageRequirements = new AccountStorageRequirements ();
349-
350- let foreignAccount = ForeignAccount .public (
339+ const storageRequirements = new AccountStorageRequirements ();
340+ const foreignAccount = ForeignAccount .public (
351341 counterContractId ,
352342 storageRequirements ,
353343 );
354344
355345 // Build a transaction request with the custom script
356- let txRequest = new TransactionRequestBuilder ()
346+ const txRequest = new TransactionRequestBuilder ()
357347 .withCustomScript (txScript )
358-
359- .withForeignAccounts ([foreignAccount ])
360-
348+ .withForeignAccounts (new MidenArrays .ForeignAccountArray ([foreignAccount ]))
361349 .build ();
362350
363- console .log (" HERE" );
364-
365- // Execute the transaction locally on the count reader contract (following Rust pattern)
366- let txResult = await client .newTransaction (
351+ // Execute the transaction on the count reader contract and send it to the network (following Rust pattern)
352+ const txResult = await client .submitNewTransaction (
367353 countReaderContract .account .id (),
368354 txRequest ,
369355 );
370356
371- console .log (" HERE1" );
372357 console .log (
373358 " View transaction on MidenScan: https://testnet.midenscan.com/tx/" +
374- txResult .executedTransaction (). id (). toHex (),
359+ txResult .toHex (),
375360 );
376361
377- // Submit transaction to the network
378- await client .submitTransaction (txResult );
379362 await client .syncState ();
380363
381364 // Retrieve updated contract data to see the results (following Rust pattern)
382- let updatedCounterContract = await client .getAccount (
365+ const updatedCounterContract = await client .getAccount (
383366 counterContractAccount .id (),
384367 );
385368 console .log (
386369 " counter contract storage:" ,
387370 updatedCounterContract ?.storage ().getItem (0 )?.toHex (),
388371 );
389372
390- let updatedCountReaderContract = await client .getAccount (
373+ const updatedCountReaderContract = await client .getAccount (
391374 countReaderContract .account .id (),
392375 );
393376 console .log (
@@ -396,7 +379,7 @@ export async function foreignProcedureInvocation(): Promise<void> {
396379 );
397380
398381 // Log the count value copied via FPI
399- let countReaderStorage = updatedCountReaderContract ?.storage ().getItem (0 );
382+ const countReaderStorage = updatedCountReaderContract ?.storage ().getItem (0 );
400383 if (countReaderStorage ) {
401384 const countValue = Number (
402385 BigInt (
@@ -470,7 +453,8 @@ Foreign Procedure Invocation Transaction completed!
470453The count reader smart contract contains a ` copy_count ` procedure that uses ` tx::execute_foreign_procedure ` to call the ` get_count ` procedure in the counter contract.
471454
472455``` masm
473- use.miden::account
456+ use.miden::active_account
457+ use miden::native_account
474458use.miden::tx
475459use.std::sys
476460
@@ -479,16 +463,12 @@ export.copy_count
479463 exec.tx::execute_foreign_procedure
480464 # => [count]
481465
482- debug.stack
483- # => [count]
484-
485466 push.0
486467 # [index, count]
487468
488- exec.account::set_item
489- # => []
469+ debug.stack
490470
491- push.1 exec.account::incr_nonce
471+ exec.native_account::set_item dropw
492472 # => []
493473
494474 exec.sys::truncate_stack
@@ -561,7 +541,7 @@ let foreignAccount = ForeignAccount.public(
561541
562542let txRequest = new TransactionRequestBuilder ()
563543 .withCustomScript (txScript )
564- .withForeignAccounts ([foreignAccount ])
544+ .withForeignAccounts (new MidenArrays . ForeignAccountArray ( [foreignAccount ]) )
565545 .build ();
566546```
567547
@@ -570,11 +550,11 @@ let txRequest = new TransactionRequestBuilder()
570550We create a library for the count reader contract so our transaction script can call its procedures:
571551
572552``` ts
573- let countReaderLib = AssemblerUtils .createAccountComponentLibrary (
574- assembler ,
553+ const countReaderLib = builder .buildLibrary (
575554 " external_contract::count_reader_contract" ,
576555 countReaderCode ,
577556);
557+ builder .linkDynamicLibrary (countReaderLib );
578558```
579559
580560## Summary
0 commit comments