Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"printWidth": 80,
"tabWidth": 2,
"singleQuote": true,
"trailingComma": "all"
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: "Web Client"
title: 'Web Client'
sidebar_position: 1
---

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ title: 'Incrementing the Count of the Counter Contract'
sidebar_position: 5
---

# Incrementing the Count of the Counter Contract

_Using the Miden WebClient to interact with a custom smart contract_

## Overview
Expand All @@ -22,7 +20,7 @@ Using a script, we will invoke the increment function within the counter contrac

- Node `v20` or greater
- Familiarity with TypeScript
- `pnpm`
- `yarn`

This tutorial assumes you have a basic understanding of Miden assembly. To quickly get up to speed with Miden assembly (MASM), please play around with running basic Miden assembly programs in the [Miden playground](https://0xmiden.github.io/examples/).

Expand All @@ -31,7 +29,7 @@ This tutorial assumes you have a basic understanding of Miden assembly. To quick
1. Create a new Next.js app with TypeScript:

```bash
npx create-next-app@latest miden-web-app --typescript
yarn create next-app@latest miden-web-app --typescript
```

Hit enter for all terminal prompts.
Expand All @@ -44,7 +42,7 @@ This tutorial assumes you have a basic understanding of Miden assembly. To quick

3. Install the Miden WebClient SDK:
```bash
pnpm i @demox-labs/miden-sdk@0.12.3
yarn add @demox-labs/miden-sdk@0.12.3
```

**NOTE!**: Be sure to add the `--webpack` command to your `package.json` when running the `dev script`. The dev script should look like this:
Expand Down Expand Up @@ -87,7 +85,9 @@ export default function Home() {
onClick={handleIncrementCounterContract}
className="w-full px-6 py-3 text-lg cursor-pointer bg-transparent border-2 border-orange-600 text-white rounded-lg transition-all hover:bg-orange-600 hover:text-white"
>
{isIncrementCounter ? 'Working...' : 'Tutorial #3: Increment Counter Contract'}
{isIncrementCounter
? 'Working...'
: 'Tutorial #3: Increment Counter Contract'}
</button>
</div>
</div>
Expand Down Expand Up @@ -135,54 +135,56 @@ export async function incrementCounterContract(): Promise<void> {

// Counter contract code in Miden Assembly
const counterContractCode = `
use.miden::active_account
use miden::native_account
use.std::sys
use.miden::active_account
use miden::native_account
use.std::sys

const.COUNTER_SLOT=0
const.COUNTER_SLOT=0

#! Inputs: []
#! Outputs: [count]
export.get_count
push.COUNTER_SLOT
# => [index]
#! Inputs: []
#! Outputs: [count]
export.get_count
push.COUNTER_SLOT
# => [index]

exec.active_account::get_item
# => [count]
exec.active_account::get_item
# => [count]

# clean up stack
movdn.4 dropw
# => [count]
end
# clean up stack
movdn.4 dropw
# => [count]
end

#! Inputs: []
#! Outputs: []
export.increment_count
push.COUNTER_SLOT
# => [index]
#! Inputs: []
#! Outputs: []
export.increment_count
push.COUNTER_SLOT
# => [index]

exec.active_account::get_item
# => [count]
exec.active_account::get_item
# => [count]

add.1
# => [count+1]
add.1
# => [count+1]

debug.stack
debug.stack

push.COUNTER_SLOT
# [index, count+1]
push.COUNTER_SLOT
# [index, count+1]

exec.native_account::set_item
# => [OLD_VALUE]
exec.native_account::set_item
# => [OLD_VALUE]

dropw
# => []
end
dropw
# => []
end
`;

// Building the counter contract
// Counter contract account id on testnet
const counterContractId = AccountId.fromHex('0xe59d8cd3c9ff2a0055da0b83ed6432');
const counterContractId = AccountId.fromHex(
'0xe59d8cd3c9ff2a0055da0b83ed6432',
);

// Reading the public state of the counter contract from testnet,
// and importing it into the WebClient
Expand All @@ -200,9 +202,11 @@ end
const storageMap = new StorageMap();
const storageSlotMap = StorageSlot.map(storageMap);

const mappingAccountComponent = AccountComponent.compile(counterContractCode, builder, [
storageSlotMap,
]).withSupportsAllTypes();
const mappingAccountComponent = AccountComponent.compile(
counterContractCode,
builder,
[storageSlotMap],
).withSupportsAllTypes();

const walletSeed = new Uint8Array(32);
crypto.getRandomValues(walletSeed);
Expand Down Expand Up @@ -238,10 +242,15 @@ end
`;

const txScript = builder.compileTxScript(txScriptCode);
const txIncrementRequest = new TransactionRequestBuilder().withCustomScript(txScript).build();
const txIncrementRequest = new TransactionRequestBuilder()
.withCustomScript(txScript)
.build();

// Executing the transaction script against the counter contract
await client.submitNewTransaction(counterContractAccount.id(), txIncrementRequest);
await client.submitNewTransaction(
counterContractAccount.id(),
txIncrementRequest,
);

// Sync state
await client.syncState();
Expand All @@ -265,7 +274,7 @@ end
To run the code above in our frontend, run the following command:

```
pnpm run dev
yarn dev
```

Open the browser console and click the button "Increment Counter Contract".
Expand Down Expand Up @@ -345,13 +354,11 @@ end

**Note**: _It's a good habit to add comments below each line of MASM code with the expected stack state. This improves readability and helps with debugging._

### Concept of function visibility and modifiers in Miden smart contracts

The `export.increment_count` function in our Miden smart contract behaves like an "external" Solidity function without a modifier, meaning any user can call it to increment the contract's count. This is because it calls `account::incr_nonce` during execution. For internal procedures, use the `proc` keyword as opposed to `export`.
### Authentication Component

If the `increment_count` procedure did not call the `account::incr_nonce` procedure during its execution, only the deployer of the counter contract would be able to increment the count of the smart contract (if the RpoFalcon512 component was added to the account, in this case we didn't add it).
**Important**: All accounts must have an authentication component. For smart contracts that do not require authentication (like our counter contract), we use a `NoAuth` component.

In essence, if a procedure performs a state change in the Miden smart contract, and does not call `account::incr_nonce` at some point during its execution, this function can be equated to having an `onlyOwner` Solidity modifer, meaning only the user with knowledge of the private key of the account can execute transactions that result in a state change.
This `NoAuth` component allows any user to interact with the smart contract without requiring signature verification.

**Note**: _Adding the `account::incr_nonce` to a state changing procedure allows any user to call the procedure._

Expand All @@ -373,8 +380,8 @@ To run a full working example navigate to the `web-client` directory in the [mid

```bash
cd web-client
pnpm i
pnpm run start
yarn install
yarn start
```

### Resetting the `MidenClientDB`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
---
title: 'Creating Accounts and Faucets'
title: 'Creating Accounts and Deploying Faucets'
sidebar_position: 2
---

## Creating Accounts and Deploying Faucets

_Using the Miden WebClient in TypeScript to create accounts and deploy faucets_

## Overview
Expand All @@ -22,7 +20,7 @@ In this tutorial, we'll build a simple Next.js application that demonstrates the

- Node `v20` or greater
- Familiarity with TypeScript
- `pnpm`
- `yarn`

## Public vs. private accounts & notes

Expand All @@ -42,7 +40,7 @@ It is useful to think of notes on Miden as "cryptographic cashier's checks" that
1. Create a new Next.js app with TypeScript:

```bash
npx create-next-app@latest miden-web-app --typescript
yarn create next-app@latest miden-web-app --typescript
```

Hit enter for all terminal prompts.
Expand All @@ -55,7 +53,7 @@ It is useful to think of notes on Miden as "cryptographic cashier's checks" that

3. Install the Miden WebClient SDK:
```bash
pnpm install @demox-labs/miden-sdk@0.12.3
yarn add @demox-labs/miden-sdk@0.12.3
```

**NOTE!**: Be sure to add the `--webpack` command to your `package.json` when running the `dev script`. The dev script should look like this:
Expand Down Expand Up @@ -96,7 +94,7 @@ export async function createMintConsume(): Promise<void> {
);

// Connect to Miden testnet RPC endpoint
const nodeEndpoint = 'https://rpc.testnet.miden.io:443';
const nodeEndpoint = 'https://rpc.testnet.miden.io';
const client = await WebClient.createClient(nodeEndpoint);

// 1. Sync with the latest blockchain state
Expand Down Expand Up @@ -142,7 +140,9 @@ export default function Home() {
onClick={handleCreateMintConsume}
className="w-full px-6 py-3 text-lg cursor-pointer bg-transparent border-2 border-orange-600 text-white rounded-lg transition-all hover:bg-orange-600 hover:text-white"
>
{isCreatingNotes ? 'Working...' : 'Tutorial #1: Create a wallet and deploy a faucet'}
{isCreatingNotes
? 'Working...'
: 'Tutorial #1: Create a wallet and deploy a faucet'}
</button>
</div>
</div>
Expand Down Expand Up @@ -170,7 +170,7 @@ export async function createMintConsume(): Promise<void> {
"@demox-labs/miden-sdk"
);

const nodeEndpoint = 'https://rpc.testnet.miden.io:443';
const nodeEndpoint = 'https://rpc.testnet.miden.io';
const client = await WebClient.createClient(nodeEndpoint);

// 1. Sync with the latest blockchain state
Expand Down Expand Up @@ -243,9 +243,11 @@ export async function createMintConsume(): Promise<void> {
return;
}

const { WebClient, AccountStorageMode } = await import('@demox-labs/miden-sdk');
const { WebClient, AccountStorageMode } = await import(
'@demox-labs/miden-sdk'
);

const nodeEndpoint = 'https://rpc.testnet.miden.io:443';
const nodeEndpoint = 'https://rpc.testnet.miden.io';
const client = await WebClient.createClient(nodeEndpoint);

// 1. Sync with the latest blockchain state
Expand Down Expand Up @@ -277,8 +279,8 @@ export async function createMintConsume(): Promise<void> {

```bash
cd miden-web-app
npm i
npm run dev
yarn install
yarn dev
```

Open [http://localhost:3000](http://localhost:3000) in your browser, click **Tutorial #1: Create a wallet and deploy a faucet**, and check the browser console (F12 or right-click → Inspect → Console):
Expand Down
Loading