From a2e75b3259f4123f65f518909fcdd1ff63d640d9 Mon Sep 17 00:00:00 2001 From: Idogwu Chinonso Date: Tue, 8 Oct 2024 22:46:05 +0100 Subject: [PATCH 1/3] Update: Modified development folder in line with docs V2 --- .../development/building-a-dapp.md | 163 ++++++++++++++++++ .../development/building-the-application.md | 53 ------ .../version-2.0/development/cli-commands.md | 6 +- .../development/creating-application.md | 35 ---- .../{retrieve-outputs.md => query-outputs.md} | 4 +- .../{migration.md => reference.md} | 4 +- .../development/running-the-application.md | 75 -------- .../{send-requests.md => send-inputs.md} | 4 +- 8 files changed, 174 insertions(+), 170 deletions(-) create mode 100644 cartesi-rollups_versioned_docs/version-2.0/development/building-a-dapp.md delete mode 100644 cartesi-rollups_versioned_docs/version-2.0/development/building-the-application.md delete mode 100644 cartesi-rollups_versioned_docs/version-2.0/development/creating-application.md rename cartesi-rollups_versioned_docs/version-2.0/development/{retrieve-outputs.md => query-outputs.md} (99%) rename cartesi-rollups_versioned_docs/version-2.0/development/{migration.md => reference.md} (99%) delete mode 100644 cartesi-rollups_versioned_docs/version-2.0/development/running-the-application.md rename cartesi-rollups_versioned_docs/version-2.0/development/{send-requests.md => send-inputs.md} (99%) diff --git a/cartesi-rollups_versioned_docs/version-2.0/development/building-a-dapp.md b/cartesi-rollups_versioned_docs/version-2.0/development/building-a-dapp.md new file mode 100644 index 00000000..226f1523 --- /dev/null +++ b/cartesi-rollups_versioned_docs/version-2.0/development/building-a-dapp.md @@ -0,0 +1,163 @@ +--- +id: building-a-dapp +title: Building a dApp +resources: + - url: https://github.com/Calindra/nonodo + title: NoNodo + - url: https://cartesiscan.io/ + title: CartesiScan +--- + + +## Creating the application +Cartesi CLI simplifies creating dApps on Cartesi. To create a new application, run: + +```shell +cartesi create --template +``` + +For example, create a Python project. + +```shell +cartesi create new-dapp --template python +``` + +This command creates a `new-dapp` directory with essential files for your dApp development. + +- `Dockerfile`: Contains configurations to build a complete Cartesi machine with your app's dependencies. Your backend code will run in this environment. + +- `README.md`: A markdown file with basic information and instructions about your dApp. + +- `dapp.py`: A Python file with template backend code that serves as your application's entry point. + +- `requirements.txt`: Lists the Python dependencies required for your application. + +Cartesi CLI has templates for the following languages – `cpp`, `cpp-low-level`, `go`, `javascript`, `lua`, `python`, `ruby`, `rust`, and `typescript`. + +After creating your application, you can start building your dApp by adding your logic to the `dapp.py` file. + + +:::note Building with Go? +For Go applications on Cartesi, we recommend using [Rollmelette](https://github.com/rollmelette/rollmelette). It’s a high-level Go framework and an alternative template that simplifies development and enhances input management, providing a smoother and more efficient experience. +::: + + +## Building the application + +“Building” in this context compiles your application into RISC-V architecture and consequently builds a Cartesi machine containing your application. This architecture enables computation done by your application to be reproducible and verifiable. + +With the Docker engine running, change the directory to your application and build by running: + +```shell +cartesi build +``` + +The successful execution of this step will log this in your terminal: + +```shell + . + / \ + / \ +\---/---\ /----\ + \ X \ + \----/ \---/---\ + \ / CARTESI + \ / MACHINE + ' + +[INFO rollup_http_server] starting http dispatcher service... +[INFO rollup_http_server::http_service] starting http dispatcher http service! +[INFO actix_server::builder] starting 1 workers +[INFO actix_server::server] Actix runtime found; starting in Actix runtime +[INFO rollup_http_server::dapp_process] starting dapp +INFO:__main__:HTTP rollup_server url is http://127.0.0.1:5004 +INFO:__main__:Sending finish + +Manual yield rx-accepted (0x100000000 data) +Cycles: 2767791744 +2767791744: b740d27cf75b6cb10b1ab18ebd96be445ca8011143d94d8573221342108822f5 +Storing machine: please wait +Successfully copied 288MB to /Users/michaelasiedu/Code/calculator/python/.cartesi/image +``` +### Memory + +To change the default memory size for the Cartesi Machine, you can personalize it by adding a specific label in your Dockerfile. + +The line below lets you define the memory size in megabytes (MB): + +```dockerfile +LABEL io.cartesi.rollups.ram_size=128Mi +``` + +:::note environment variables +You can create a `.cartesi.env` in the project's root and override any variable controlling the rollups-node. +::: + + +## Running the Application + +Running your application starts your backend on port `8080` and local Anvil node on port `8545`. + +In essence, the node also logs all outputs received by your backend. + +Here are the prerequisites to run the node: + +- Docker Engine must be active. +- Cartesi machine snapshot successfully built with `cartesi build`. + +To start the node, run: + +```shell +cartesi run +``` + +This command runs your backend compiled to RISC-V and packages it as a Cartesi machine. + +:::troubleshoot troubleshooting common errors + +#### Error: Depth Too High + +```shell +Attaching to 2bd74695-prompt-1, 2bd74695-validator-1 +2bd74695-validator-1 | Error: DepthTooHigh { depth: 2, latest: 1 } +2bd74695-validator-1 | Error: DepthTooHigh { depth: 2, latest: 1 } +``` + +This indicates that the node is reading blocks too far behind the current blockchain state. + +#### Solution + +Create or modify a `.cartesi.env` file in your project directory and set: + +```shell +TX_DEFAULT_CONFIRMATIONS=1 +``` + +This adjustment should align the node's block reading with the blockchain's current state. + +::: + +### Overview of Node Services + +The `cartesi run` command activates several services essential for node operation: + +- **Anvil Chain**: Runs a local blockchain available at `http://localhost:8545`. + +- **GraphQL Playground**: An interactive IDE at `http://localhost:8080/graphql` for exploring the GraphQL server. + +- **Blockchain Explorer**: Monitors node activity and manages transactions via `http://localhost:8080/explorer/`. + +- **Inspect**: A diagnostic tool accessible at `http://localhost:8080/inspect/` to inspect the node’s state. + + +### CartesiScan + +[CartesiScan](https://cartesiscan.io/) is a valuable tool for developers and users alike, offering a comprehensive overview of Cartesi Rollups applications and their interactions with the blockchain. + +Additionally, it provides expandable data regarding outputs, encompassing notices, vouchers, and reports. + +When you run your application with `cartesi run` , there is a local instance of CartesiScan on `http://localhost:8080/explorer`. + +:::note Testing tools +[NoNodo](https://github.com/Calindra/nonodo) is a Cartesi Rollups testing tool that works with host machine applications, eliminating the need for Docker or RISC-V compilation. +::: diff --git a/cartesi-rollups_versioned_docs/version-2.0/development/building-the-application.md b/cartesi-rollups_versioned_docs/version-2.0/development/building-the-application.md deleted file mode 100644 index fbac5190..00000000 --- a/cartesi-rollups_versioned_docs/version-2.0/development/building-the-application.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -id: building-the-application -title: Building the application ---- - -“Building” in this context compiles your application into RISC-V architecture and consequently builds a Cartesi machine containing your application. This architecture enables computation done by your application to be reproducible and verifiable. - -With the Docker engine running, change the directory to your application and build by running: - -```shell -cartesi build -``` - -The successful execution of this step will log this in your terminal: - -```shell - . - / \ - / \ -\---/---\ /----\ - \ X \ - \----/ \---/---\ - \ / CARTESI - \ / MACHINE - ' - -[INFO rollup_http_server] starting http dispatcher service... -[INFO rollup_http_server::http_service] starting http dispatcher http service! -[INFO actix_server::builder] starting 1 workers -[INFO actix_server::server] Actix runtime found; starting in Actix runtime -[INFO rollup_http_server::dapp_process] starting dapp -INFO:__main__:HTTP rollup_server url is http://127.0.0.1:5004 -INFO:__main__:Sending finish - -Manual yield rx-accepted (0x100000000 data) -Cycles: 2767791744 -2767791744: b740d27cf75b6cb10b1ab18ebd96be445ca8011143d94d8573221342108822f5 -Storing machine: please wait -Successfully copied 288MB to /Users/michaelasiedu/Code/calculator/python/.cartesi/image -``` -## Memory - -To change the default memory size for the Cartesi Machine, you can personalize it by adding a specific label in your Dockerfile. - -The line below lets you define the memory size in megabytes (MB): - -```dockerfile -LABEL io.cartesi.rollups.ram_size=128Mi -``` - -:::note environment variables -You can create a `.cartesi.env` in the project's root and override any variable controlling the rollups-node. -::: \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/development/cli-commands.md b/cartesi-rollups_versioned_docs/version-2.0/development/cli-commands.md index fe3f5a70..6d92fdaa 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/development/cli-commands.md +++ b/cartesi-rollups_versioned_docs/version-2.0/development/cli-commands.md @@ -78,10 +78,14 @@ cartesi run [--block-time ] [--epoch-length ] [--no-backend] [-v] #### Flags: - `--block-time=`: Interval between blocks in seconds (default: 5). -- `--epoch-length=`: length of an epoch in blocks (default: 720). +- `--epoch-length=`: length of an epoch in blocks (default: 720). - `--no-backend`: Run a node without the application code. - `-v`, `--verbose`: Run node with detailed container logs. - `--listen-port=`: Port to listen for incoming connections (default: 8080). +- `--dry-run`: Shows the docker compose configuration. +- `--cpus=`: Define the number of CPUs (eg.: 1) for the rollups-node (default is not limited). +- `--memory=`: Define the amount of memory (eg.: 1024) for the rollups-node in MB (default is not limited). + --- diff --git a/cartesi-rollups_versioned_docs/version-2.0/development/creating-application.md b/cartesi-rollups_versioned_docs/version-2.0/development/creating-application.md deleted file mode 100644 index aa2c4aad..00000000 --- a/cartesi-rollups_versioned_docs/version-2.0/development/creating-application.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -id: creating-application -title: Creating an application ---- - -Cartesi CLI simplifies creating dApps on Cartesi. To create a new application, run: - -```shell -cartesi create --template -``` - -For example, create a Python project. - -```shell -cartesi create new-dapp --template python -``` - -This command creates a `new-dapp` directory with essential files for your dApp development. - -- `Dockerfile`: Contains configurations to build a complete Cartesi machine with your app's dependencies. Your backend code will run in this environment. - -- `README.md`: A markdown file with basic information and instructions about your dApp. - -- `dapp.py`: A Python file with template backend code that serves as your application's entry point. - -- `requirements.txt`: Lists the Python dependencies required for your application. - -Cartesi CLI has templates for the following languages – `cpp`, `cpp-low-level`, `go`, `javascript`, `lua`, `python`, `ruby`, `rust`, and `typescript`. - -After creating your application, you can start building your dApp by adding your logic to the `dapp.py` file. - - -:::note Building with Go? -For Go applications on Cartesi, we recommend using [Rollmelette](https://github.com/rollmelette/rollmelette). It’s a high-level Go framework and an alternative template that simplifies development and enhances input management, providing a smoother and more efficient experience. -::: \ No newline at end of file diff --git a/cartesi-rollups_versioned_docs/version-2.0/development/retrieve-outputs.md b/cartesi-rollups_versioned_docs/version-2.0/development/query-outputs.md similarity index 99% rename from cartesi-rollups_versioned_docs/version-2.0/development/retrieve-outputs.md rename to cartesi-rollups_versioned_docs/version-2.0/development/query-outputs.md index 60a90876..28eb2736 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/development/retrieve-outputs.md +++ b/cartesi-rollups_versioned_docs/version-2.0/development/query-outputs.md @@ -1,6 +1,6 @@ --- -id: retrieve-outputs -title: Retrieve outputs +id: query-outputs +title: Query outputs resources: - url: https://www.udemy.com/course/cartesi-masterclass/ title: The Cartesi dApp Developer Free Course diff --git a/cartesi-rollups_versioned_docs/version-2.0/development/migration.md b/cartesi-rollups_versioned_docs/version-2.0/development/reference.md similarity index 99% rename from cartesi-rollups_versioned_docs/version-2.0/development/migration.md rename to cartesi-rollups_versioned_docs/version-2.0/development/reference.md index 9c9e09f4..587555f4 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/development/migration.md +++ b/cartesi-rollups_versioned_docs/version-2.0/development/reference.md @@ -1,6 +1,6 @@ --- -id: migration -title: Migration guide +id: reference +title: Reference --- ## Migrating from Cartesi Rollups Node v1.4 to v1.5.x diff --git a/cartesi-rollups_versioned_docs/version-2.0/development/running-the-application.md b/cartesi-rollups_versioned_docs/version-2.0/development/running-the-application.md deleted file mode 100644 index cef98dd7..00000000 --- a/cartesi-rollups_versioned_docs/version-2.0/development/running-the-application.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -id: running-the-application -title: Running the application -resources: - - url: https://github.com/Calindra/nonodo - title: NoNodo - - url: https://cartesiscan.io/ - title: CartesiScan ---- - -Running your application starts your backend on port `8080` and local Anvil node on port `8545`. - -In essence, the node also logs all outputs received by your backend. - -Here are the prerequisites to run the node: - -- Docker Engine must be active. -- Cartesi machine snapshot successfully built with `cartesi build`. - -To start the node, run: - -```shell -cartesi run -``` - -This command runs your backend compiled to RISC-V and packages it as a Cartesi machine. - -:::troubleshoot troubleshooting common errors - -#### Error: Depth Too High - -```shell -Attaching to 2bd74695-prompt-1, 2bd74695-validator-1 -2bd74695-validator-1 | Error: DepthTooHigh { depth: 2, latest: 1 } -2bd74695-validator-1 | Error: DepthTooHigh { depth: 2, latest: 1 } -``` - -This indicates that the node is reading blocks too far behind the current blockchain state. - -#### Solution - -Create or modify a `.cartesi.env` file in your project directory and set: - -```shell -TX_DEFAULT_CONFIRMATIONS=1 -``` - -This adjustment should align the node's block reading with the blockchain's current state. - -::: - -### Overview of Node Services - -The `cartesi run` command activates several services essential for node operation: - -- **Anvil Chain**: Runs a local blockchain available at `http://localhost:8545`. - -- **GraphQL Playground**: An interactive IDE at `http://localhost:8080/graphql` for exploring the GraphQL server. - -- **Blockchain Explorer**: Monitors node activity and manages transactions via `http://localhost:8080/explorer/`. - -- **Inspect**: A diagnostic tool accessible at `http://localhost:8080/inspect/` to inspect the node’s state. - - -## CartesiScan - -[CartesiScan](https://cartesiscan.io/) is a valuable tool for developers and users alike, offering a comprehensive overview of Cartesi Rollups applications and their interactions with the blockchain. - -Additionally, it provides expandable data regarding outputs, encompassing notices, vouchers, and reports. - -When you run your application with `cartesi run` , there is a local instance of CartesiScan on `http://localhost:8080/explorer`. - -:::note Testing tools -[NoNodo](https://github.com/Calindra/nonodo) is a Cartesi Rollups testing tool that works with host machine applications, eliminating the need for Docker or RISC-V compilation. -::: diff --git a/cartesi-rollups_versioned_docs/version-2.0/development/send-requests.md b/cartesi-rollups_versioned_docs/version-2.0/development/send-inputs.md similarity index 99% rename from cartesi-rollups_versioned_docs/version-2.0/development/send-requests.md rename to cartesi-rollups_versioned_docs/version-2.0/development/send-inputs.md index 525b33b9..0ee05c14 100644 --- a/cartesi-rollups_versioned_docs/version-2.0/development/send-requests.md +++ b/cartesi-rollups_versioned_docs/version-2.0/development/send-inputs.md @@ -1,6 +1,6 @@ --- -id: send-requests -title: Send requests +id: send-inputs +title: Send inputs resources: - url: https://github.com/prototyp3-dev/frontend-web-cartesi title: React.js + Typescript template From 86cccc926a573ff60f524a61e976b9c16a27d236 Mon Sep 17 00:00:00 2001 From: Idogwu Chinonso Date: Tue, 8 Oct 2024 22:47:45 +0100 Subject: [PATCH 2/3] Update: Added account abstraction tutorial to tutorials folder --- .../tutorials/utilizing-the-cli-AA-feature.md | 438 ++++++++++++++++++ 1 file changed, 438 insertions(+) create mode 100644 cartesi-rollups_versioned_docs/version-2.0/tutorials/utilizing-the-cli-AA-feature.md diff --git a/cartesi-rollups_versioned_docs/version-2.0/tutorials/utilizing-the-cli-AA-feature.md b/cartesi-rollups_versioned_docs/version-2.0/tutorials/utilizing-the-cli-AA-feature.md new file mode 100644 index 00000000..3c3ad254 --- /dev/null +++ b/cartesi-rollups_versioned_docs/version-2.0/tutorials/utilizing-the-cli-AA-feature.md @@ -0,0 +1,438 @@ +--- +id: cli-account-abstraction-feauture +title: Utilizing the account abstraction (AA) feature of the CLI +resources: + - url: https://github.com/tuler/aa-examples + title: AA Examples +--- + +This tutorial will guide you through utilizing the account abstraction infrastructure of the CLI to interact with your dApp while testing locally. + +## Introduction + +We currently have various architectures and SDKs supporting account abstraction across multiple chains, but there’s currently no dedicated solution for testing this integration in a local environment during dApp development. The latest update to the Cartesi CLI V0.16.0 fixes this by integrating an account abstraction architecture for testing the AA functionality of your dApp on your local machine. + +This architecture relies on external SDKs from some of the popular account abstraction providers (Alchemy, Biconomy and ZeroDev), so it’s expected that the obtained behaviour on local should mirror mainnet completely as long as you’re using the same provider. For this tutorial, we’ll be using the Alchemy SDK. However, at the end of this tutorial, we’ll also provide demo applications for utilizing other supported SDK’s. + +## Architecture + +The architecture of the CLI implementation for account abstraction is pretty much the same as that of mainnet and testnet applications; the only difference is that the CLI deploys and manages some of the important contracts once you start your local Anvil network by running the `cartesi run` command. What this means is that you don't need to bother yourself with building and deploying these important contracts; you simply utilize any SDK or account abstraction framework to interact with these contracts as you would on mainnet or testnet. + +![img](../../../static/img/v1.5/AA-Architecture.jpg) + +From the architecture above, transactions from the frontend are sent to the `bundler URL`, which controls a private key with which it pays for these transactions and sends them to the `entrypoint contract`. This `entrypoint contract` is a universal contract that forwards all transactions to the `paymaster` and also to the `user's smart contract wallet` if the user has one; if the user doesn't, it calls the `account factory` to deploy a smart wallet for the user. The `paymaster` refunds the gas fees for the execution, while the `user’s smart wallet` submits the transactions to the `input box contract`. + + +You can view the addresses for some of these components, like the account factory, entrypoint address, paymaster, etc., by running the command `cartesi address-book`. While the bundler and paymaster addresses are displayed once you start your Cartesi dApp using the `cartesi run` command. Note that for mainnet/testnet integration, you’ll have to replace these with the respective URLs provided by the SDK you’re using. + +## Setting up the frontend environment + +We’ll be using React.js along with Wagmi to build this simple frontend application. We’ll also be relying heavily on some other dependencies that we’ll introduce later on. + + +To bootstrap a React project with Wagmi already configured, we’ll use the CLI command + +```shell + npm create wagmi@latest +``` + +This command would create a new React application with a simple UI and wallet connect by wagmi already integrated. + + +Next, we install other dependencies we would be using by running this code in the terminal: + +```shell + npm i permissionless@0.1.43 encoding @alchemy/aa-core @alchemy/aa-accounts @cartesi/rollups +``` + +This command instals five different dependencies this project will be utilizing. Permissionless, and the two alchemy dependencies can be replaced with the packages for any other AA SDK you decide to use. For this tutorial we’ll be using Alchemy, and as such, we’ve installed the Alchemy aa-core and the aa-accounts dependencies. + +### Configuring wagmi.ts file + +Congratulations on successfully bootstrapping a new frontend repo; next we’ll need to properly configure a wagmi client to work on localhost. Once you’re ready for mainnet or testnet, then you can update this configuration to work with any chain you intend to support. To do this, we CD into the src folder, then replace the contents of the `wagmi.ts` file with: + +```javascript + import { http, cookieStorage, createConfig, createStorage } from "wagmi"; + import { foundry } from "wagmi/chains"; + import { coinbaseWallet, injected } from "wagmi/connectors"; + + export function getConfig() { + return createConfig({ + chains: [foundry], + connectors: [injected(), coinbaseWallet()], + storage: createStorage({ + storage: cookieStorage, + }), + ssr: true, + transports: { + [foundry.id]: http(), + }, + }); + } + + declare module "wagmi" { + interface Register { + config: ReturnType; + } + } + +``` + +### Set up an Alchemy file + +Next, we setup an implementation for creating a smart account client for the connected account; this client takes in the paymaster and bundler URL, both of which are provided by the CLI once you start your Cartesi dApp, while the Entrypoint contract that’s used in the file is provided by the permissionless SDK we’re utilizing. We’ll name this file `alchemy.ts` since we’re making use of the Alchemy Smart Account client. This file should be located inside the src folder. + +```javascript + import { createLightAccount } from "@alchemy/aa-accounts"; + import { + createSmartAccountClient, + SmartAccountClient, + split, + WalletClientSigner, + } from "@alchemy/aa-core"; + import { ENTRYPOINT_ADDRESS_V06, ENTRYPOINT_ADDRESS_V07 } from "permissionless"; + import { createPimlicoPaymasterClient } from "permissionless/clients/pimlico"; + import { useEffect, useState } from "react"; + import { Chain, concat, Transport, zeroHash } from "viem"; + import { foundry } from "viem/chains"; + import { http, usePublicClient, useWalletClient } from "wagmi"; + + export type SmartAccountClientOptions = { + bundlerUrl: string; + paymasterUrl?: string; + }; + + export const useSmartAccountClient = < + TTransport extends Transport = Transport, + TChain extends Chain | undefined = undefined, + >( + options: SmartAccountClientOptions, + ) => { + const { bundlerUrl, paymasterUrl } = options; + const publicClient = usePublicClient(); + const { data: walletClient } = useWalletClient(); + + // create paymaster client + const paymasterClient = paymasterUrl + ? createPimlicoPaymasterClient({ + transport: http(paymasterUrl), + entryPoint: ENTRYPOINT_ADDRESS_V06, + }) + : undefined; + + console.log("printing paymasterClient"); + console.log(paymasterClient); + const bundlerMethods = [ + "eth_sendUserOperation", + "eth_estimateUserOperationGas", + "eth_getUserOperationReceipt", + "eth_getUserOperationByHash", + "eth_supportedEntryPoints", + ]; + + const splitTransport = split({ + overrides: [ + { + methods: bundlerMethods, + transport: http(bundlerUrl), + }, + ], + fallback: http(publicClient.transport.url), + }); + + const [smartAccountClient, setSmartAccountClient] = + useState(); + + const createClient = async () => { + if (walletClient !== undefined) { + const signer = new WalletClientSigner(walletClient, "json-rpc"); + console.log("printing signer..."); + console.log(signer); + const account = await createLightAccount({ + chain: foundry, + signer, + factoryAddress: "0x00004EC70002a32400f8ae005A26081065620D20", // CLI only supports LightAccount 1.1.0 for now + transport: http(publicClient.transport.url), + }); + console.log("printing light account..."); + console.log(account); + + const paymaster = "0x28ec0633192d0cBd9E1156CE05D5FdACAcB93947"; + const paymasterData = + "0x00000000000000000000000000000000000000000000000000000101010101010000000000000000000000000000000000000000000000000000000000000000cd91f19f0f19ce862d7bec7b7d9b95457145afc6f639c28fd0360f488937bfa41e6eedcd3a46054fd95fcd0e3ef6b0bc0a615c4d975eef55c8a3517257904d5b1c"; + const smartAccountClient = createSmartAccountClient({ + account, + chain: foundry, + transport: splitTransport, + paymasterAndData: paymasterClient + ? { + dummyPaymasterAndData: () => + concat([paymaster, paymasterData]), + paymasterAndData: async (userOperation, options) => { + const callData = await userOperation.callData; + const nonce = await userOperation.nonce; + // @ts-ignore + const initCode = await userOperation.initCode; + const { paymasterAndData } = + await paymasterClient.sponsorUserOperation({ + userOperation: { + ...userOperation, + callData, + nonce, + initCode, + }, + }); + return { + ...userOperation, + paymasterAndData, + }; + }, + } + : undefined, + }); + return smartAccountClient; + } + }; + + useEffect(() => { + if (walletClient !== undefined) { + createClient().then(setSmartAccountClient); + } + }, [walletClient, options.bundlerUrl, options.paymasterUrl]); + + return { + smartAccountClient, + }; + }; + +``` + +:::note PaymasterData Implementation +The PaymasterData implementation contained in the code block above is a dummy pre-signed data, and the paymaster itself would sponsor every transaction on localhost, while on mainnet or testnet this paymaster can be configured to only sponsor transactions under certain conditions, and the paymasterData would be different from what we’re currently using now. You can always refer to the respective documentation of the account abstraction provider SDK you’re using for more information on PaymasterData +::: + +### Set up the Cartesi Client + +The last part of this component we’ll need to set up is the Cartesi client page. This is responsible for integrating the Alchemy file we mentioned in the previous section to relay transactions to the input box; it receives the relayer URL, bunder URL, destination contract address, and the argument as a function argument. Then it uses the smart account client created in the previous section to sponsor these transactions and relay the received arguments to the input box contract. We’ll create this file also in the src folder, then call it `cartesi.ts`. + +```javascript + import { Address, encodeFunctionData, Hash, Hex } from "viem"; + import { useSmartAccountClient } from "./alchemy"; + import { useEffect, useState } from "react"; + import { contracts } from "@cartesi/rollups/export/abi/mainnet.json"; + + export type InputBoxAddInputOptions = { + bundlerUrl: string; + paymasterUrl?: string; + args: readonly [Address, Hex]; + }; + + export const useInputBoxAddInput = (options: InputBoxAddInputOptions) => { + const { smartAccountClient } = useSmartAccountClient(options); + console.log("printing useSmartAccountClient"); + console.log(smartAccountClient); + // console.log(smartAccountClient?.getAddress); + const [hash, setHash] = useState(); + const [write, setWrite] = useState<() => void>(); + + useEffect(() => { + if (smartAccountClient && smartAccountClient.account) { + setWrite(() => async () => { + const uo = await smartAccountClient.sendUserOperation({ + account: smartAccountClient.account!, + uo: { + target: contracts.InputBox.address, + data: encodeFunctionData({ + abi: contracts.InputBox.abi, + functionName: "addInput", + args: options.args, + }), + }, + }); + const hash = + await smartAccountClient.waitForUserOperationTransaction( + uo, + ); + setHash(hash); + return hash; + }); + } + }, [smartAccountClient]); + return { hash, smartAccountClient, write }; + }; + +``` + +### Set Up the Frontend UI + +At this point, we have a complete Smart Account client active, and this is ready to relay transactions to the input box contract. However, one crucial part is missing, which is a user interface for users to be able to pass in any arbitrary payload of their choice to the Cartesi dApp running on the local machine. For this, we’ll CD into the app folder, then replace the contents of `page.tsx` with: + +```javascript + "use client"; + + import { useEffect, useState } from "react"; + import { formatUnits, isHex, stringToHex } from "viem"; + import { + useAccount, + useBalance, + useBlockNumber, + useConnect, + useDisconnect, + } from "wagmi"; + import { useInputBoxAddInput } from "@/cartesi"; + import { useQueryClient } from "@tanstack/react-query"; + + function App() { + const account = useAccount(); + const { connectors, connect, status, error } = useConnect(); + const queryClient = useQueryClient(); + const { disconnect } = useDisconnect(); + const { data: blockNumber } = useBlockNumber({ watch: true }); + + const [bundlerUrl, setBundlerUrl] = useState( + "http://localhost:8080/bundler/rpc", + ); + const [paymasterUrl, setPaymasterUrl] = useState( + "http://localhost:8080/paymaster/", + ); + const [usePaymaster, setUsePaymaster] = useState(true); + + const [payload, setPayload] = useState("hello"); + + // transaction through hook + const { hash, smartAccountClient, write } = useInputBoxAddInput({ + bundlerUrl, + paymasterUrl: usePaymaster ? paymasterUrl : undefined, + args: [ + "0xab7528bb862fb57e8a2bcd567a2e929a0be56a5e", + isHex(payload) ? payload : stringToHex(payload), + ], + }); + + const { data: balance, queryKey } = useBalance({ + address: smartAccountClient?.account.address, + query: { enabled: !!smartAccountClient }, + }); + + useEffect(() => { + queryClient.invalidateQueries({ queryKey }); + }, [blockNumber, queryClient]); + + return ( + <> +
+

Account (Signer)

+ +
+ status: {account.status} +
+ addresses: {JSON.stringify(account.addresses)} +
+ chainId: {account.chainId} +
+ blockNumber: {blockNumber?.toString()} +
+ + {account.status === "connected" && ( + + )} +
+ +
+

Connect

+ {connectors.map((connector) => ( + + ))} +
{status}
+
{error?.message}
+
+ +
+

Account Abstraction

+
+ Bundler URL: + setBundlerUrl(e.target.value)} + /> +
+
+ Paymaster URL: + setPaymasterUrl(e.target.value)} + /> +
+
+ Smart Account Address: + {smartAccountClient?.account.address} +
+
+ Smart Account Balance: + {balance && ( + + {formatUnits(balance.value, balance.decimals)}{" "} + {balance.symbol} + + )} +
+
+ +
+

Transaction

+
+ payload: + setPayload(e.target.value)} + /> +
+ setUsePaymaster(!usePaymaster)} + /> + +
+ + {hash} +
+ + ); + } + + export default App; +``` + +We now have a functional frontend and account abstraction infrastructure available to interact with your Cartesi dApp running on localhost. But to complete this tutorial, we’ll need to set up and run a demo Cartesi dApp, as this will deploy all the necessary contracts like the entrypoint contract, relayer contract, and smart account factory, and without these we won't be able to test out the account abstraction implementation. + +## Setting up and running a Cartesi dApp backend on localhost + +This last section of this article is focused on setting up a Cartesi dApp on a local host; this will be the target of all user executions on the frontend. To do this, we simply run the following commands:. + +- Create a new project using the command `cartesi create AA-on-CLI --template javascript`. +- Cd into `AA-on-CLI` Build the dApp by running the command `cartesi build` +- Next, run the command `cartesi run` to start a local anvil node and deploy all necessary contracts. +- Finally, in a new terminal, navigate to our frontend repository and start the frontend by running the command `npm run dev`. + + +## Testing out the new account abstraction powered dApp +To test out the dApp, we simply visit the page our frontend is running on. We should have a simple UI available with a wallet connect feature and a text box available. First we’ll need to connect our wallet, then after a couple of seconds the frontend displays our smart contract account address; this will be the address that forwards every execution we make to the inputbox contract; therefore, the Dapp on the backend will pick this new address as the sender and not the address we connected initially. Next, we can interact with the dApp by passing in any generic message of our choice into the text box and then hitting the send input button. This should trigger our connected wallet to display a popup asking us to sign a message (which does not require us to pay gas fees) and not the regular transaction verification request. Once we sign this transaction, the message we typed in will be forwarded to our dApp running on localhost. You can check the terminal the dApp is running on to verify that the message got to our dApp and the actual address that sent the message. + +## Conclusion + +We’ve been able to build our first gasless transaction supporting dApp on Cartesi and that’s great. But it’s important to note that the above infrastructure we’ve currently setup is streamlined to localhost but can easily be configured to work with any network of your choice by simply replacing the bundler URL and also the paymaster URL with that provided by Alchemy for the chain you intend to support. You can check the [Alchemy documentation](https://docs.alchemy.com/reference/bundler-api-quickstart) for more information on how to create an account and also obtain a bundler and paymaster URL. + From 101f365ba2e547b48274a9c3ecfae0f6975c8652 Mon Sep 17 00:00:00 2001 From: Idogwu Chinonso Date: Wed, 9 Oct 2024 11:33:35 +0100 Subject: [PATCH 3/3] add: Included a new file in sidebar folder for V2.0 --- .../version-2.0-sidebars.json | 214 ++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 cartesi-rollups_versioned_sidebars/version-2.0-sidebars.json diff --git a/cartesi-rollups_versioned_sidebars/version-2.0-sidebars.json b/cartesi-rollups_versioned_sidebars/version-2.0-sidebars.json new file mode 100644 index 00000000..288c2b9d --- /dev/null +++ b/cartesi-rollups_versioned_sidebars/version-2.0-sidebars.json @@ -0,0 +1,214 @@ +{ + "rollups": [ + { + "type": "doc", + "id": "overview", + "label": "Overview" + }, + { + "type": "doc", + "id": "quickstart", + "label": "Quickstart" + }, + { + "type": "category", + "label": "Core Concepts", + "collapsed": true, + "items": [ + "core-concepts/optimistic-rollups", + "core-concepts/architecture", + "core-concepts/mainnet-considerations" + ] + }, + { + "type": "category", + "label": "Rollups APIs", + "collapsed": true, + "items": [ + "rollups-apis/http-api", + { + "type": "category", + "label": "Backend APIs", + "collapsed": true, + "items": [ + "rollups-apis/backend/introduction", + "rollups-apis/backend/notices", + "rollups-apis/backend/vouchers", + "rollups-apis/backend/reports" + ] + }, + { + "type": "category", + "label": "Frontend APIs", + "collapsed": true, + "items": [ + { + "type": "category", + "label": "Smart contracts API", + "collapsed": true, + "items": [ + "rollups-apis/json-rpc/overview", + "rollups-apis/json-rpc/input-box", + "rollups-apis/json-rpc/application", + "rollups-apis/json-rpc/application-factory", + { + "type": "category", + "label": "Portals", + "collapsed": true, + "items": [ + "rollups-apis/json-rpc/portals/ERC20Portal", + "rollups-apis/json-rpc/portals/ERC721Portal", + "rollups-apis/json-rpc/portals/ERC1155SinglePortal", + "rollups-apis/json-rpc/portals/ERC1155BatchPortal", + "rollups-apis/json-rpc/portals/EtherPortal" + ] + }, + { + "type": "category", + "label": "Relayer", + "collapsed": true, + "items": [ + "rollups-apis/json-rpc/relays/relays" + ] + } + ] + }, + { + "type": "category", + "label": "GraphQL API", + "collapsed": true, + "items": [ + "rollups-apis/graphql/overview", + { + "type": "category", + "label": "Queries", + "collapsed": true, + "items": [ + "rollups-apis/graphql/queries/inputs", + "rollups-apis/graphql/queries/notices", + "rollups-apis/graphql/queries/vouchers", + "rollups-apis/graphql/queries/reports" + ] + }, + { + "type": "category", + "label": "Objects", + "collapsed": true, + "items": [ + { + "type": "autogenerated", + "dirName": "rollups-apis/graphql/objects" + } + ] + }, + { + "type": "category", + "label": "Filters", + "collapsed": true, + "items": [ + { + "type": "autogenerated", + "dirName": "rollups-apis/graphql/inputs" + } + ] + }, + { + "type": "category", + "label": "Scalars", + "collapsed": true, + "items": [ + { + "type": "autogenerated", + "dirName": "rollups-apis/graphql/scalars" + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "category", + "label": "Development", + "collapsed": true, + "items": [ + "development/installation", + "development/building-a-dapp", + "development/cli-commands", + "development/send-inputs", + "development/query-outputs", + "development/asset-handling", + "development/reference", + "development/community-tools" + ] + }, + { + "type": "category", + "label": "Deployment", + "collapsed": true, + "items": [ + "deployment/introduction", + "deployment/self-hosted" + ] + }, + { + "type": "category", + "label": "Tutorials", + "collapsed": true, + "items": [ + "tutorials/calculator", + "tutorials/ether-wallet", + "tutorials/erc-20-token-wallet", + "tutorials/erc-721-token-wallet", + "tutorials/react-frontend-application", + "tutorials/cli-account-abstraction-feauture" + ] + }, + { + "type": "category", + "label": "References", + "collapsed": true, + "items": [ + { + "type": "category", + "label": "Releases", + "items": [ + { + "type": "link", + "label": "Cartesi CLI", + "href": "https://github.com/cartesi/cli/releases" + }, + { + "type": "link", + "label": "Rollups Node", + "href": "https://github.com/cartesi/rollups-node/releases" + }, + { + "type": "link", + "label": "Rollups Contracts", + "href": "https://github.com/cartesi/rollups-contracts/releases" + } + ] + }, + { + "type": "category", + "label": "Changelog", + "items": [ + { + "type": "link", + "label": "Rollups Node", + "href": "https://github.com/cartesi/rollups-node/blob/main/CHANGELOG.md" + }, + { + "type": "link", + "label": "Rollups Contracts", + "href": "https://github.com/cartesi/rollups-contracts/blob/main/CHANGELOG.md" + } + ] + } + ] + } + ] +} \ No newline at end of file