From 6dd8d2cdf80b48174cb425f861483413152c5644 Mon Sep 17 00:00:00 2001
From: Chase Fleming <1666730+chasefleming@users.noreply.github.com>
Date: Thu, 24 Oct 2024 09:47:12 -0700
Subject: [PATCH 01/18] Add sending transaction to getting started
---
docs/build/getting-started/fcl-quickstart.md | 479 ++++++++++++++++---
1 file changed, 412 insertions(+), 67 deletions(-)
diff --git a/docs/build/getting-started/fcl-quickstart.md b/docs/build/getting-started/fcl-quickstart.md
index bd532d649a..1a1457d5e9 100644
--- a/docs/build/getting-started/fcl-quickstart.md
+++ b/docs/build/getting-started/fcl-quickstart.md
@@ -5,157 +5,502 @@ sidebar_label: Simple Frontend
# Simple Frontend
-[Flow Client Library] (FCL), is a JavaScript library developed to facilitate interactions with the Flow blockchain. It provides developers with tools to build, integrate, and interact with Flow directly from web applications. This web app quickstart will get you interacting with a contract already deployed to Flow.
+[Flow Client Library] (FCL) is a JavaScript library developed to facilitate interactions with the Flow blockchain. It provides developers with tools to build, integrate, and interact with Flow directly from web applications. This quickstart will guide you through interacting with a contract already deployed on Flow, reading and mutating its state, and setting up wallet authentication using FCL's Discovery UI.
-For this tutorial, we're going to be making a [React] app with [Create React App]. We'll try and keep the code as simple as possible in case you're coming from another framework.
+For this tutorial, we're going to create a [React] app using [Create React App]. We'll keep the code as simple as possible, so even if you're coming from another framework, you can follow along.
## Objectives
After completing this guide, you'll be able to:
-* Display data from a [Cadence] smart contract on a React frontend using the [Flow Client Library]
+- Display data from a [Cadence] smart contract on a React frontend using the [Flow Client Library].
+- Mutate the state of a smart contract by sending transactions using FCL and a wallet.
+- Set up the Discovery UI to use a wallet for authentication.
## Creating the App
-First, let's create our app and then navigate to it with the following terminal commands. From the root of where you keep your source code:
+First, let's create our app and navigate to it with the following terminal commands. From the root of where you keep your source code:
-```zsh
+```bash
npx create-react-app fcl-app-quickstart
cd fcl-app-quickstart
```
-Open the new project in a new window in your editor.
+This command uses sets up a new React project named `fcl-app-quickstart`. Then, we navigate into the project directory.
-It comes with a default layout, but let's remove it in `src/App.js` with something simple. Copy and paste this:
+Open the new project in your editor.
-```tsx
+The default layout includes some boilerplate code that we don't need. Let's simplify `src/App.js` to start with a clean slate. Replace the contents of `src/App.js` with:
+
+```jsx
// src/App.js
import './App.css';
function App() {
- return (
-
-
FCL App Quickstart
-
- );
+ return (
+
+
FCL App Quickstart
+
+ );
}
export default App;
```
-Now let's run our app with the following `npm` command:
+This code defines a simple `App` component that displays the text "FCL App Quickstart".
-```zsh
+Now, let's run our app with the following `npm` command:
+
+```bash
npm start
```
-You'll see a blank page with `FCL App Quickstart` at the top.
+This will start the development server and open your app in the browser. You should see a page displaying `FCL App Quickstart`.
## Setting Up FCL
-In order to use FCL, we need to install it. Shut the server down then run the following to download the library and set it as a dependency in our project:
+To interact with the Flow blockchain, we need to install the Flow Client Library (FCL). Stop the development server by pressing `Ctrl+C` in the terminal, and then run the following command to install FCL:
-```
+```bash
npm install @onflow/fcl --save
```
-Next we'll want to add to our FCL configuration. There's a lot you can do here, but for this simple example, let's configure `accessNode.api` to talk to the Testnet Flow Access Node. An Access Node serves as the primary point of interaction for clients, such as wallets, dapps, and other services, to communicate with the Flow network. It provides a gateway for these clients to submit transactions, query data, and retrieve information without having to connect to the entire network or maintain a full copy of the blockchain.
+This command installs FCL and adds it to your project's dependencies.
-For our example, we are going to point at a free Access Node provided by Flow. Add the following config code to your `src/App.js`:
+Next, we'll configure FCL to connect to the Flow Testnet. An Access Node serves as the primary point of interaction for clients to communicate with the Flow network. It provides a gateway for submitting transactions, querying data, and retrieving information.
-```tsx
+In `src/App.js`, import FCL and add the configuration code:
+
+```jsx
// src/App.js
import * as fcl from '@onflow/fcl';
fcl.config({
- 'accessNode.api': 'https://rest-testnet.onflow.org'
+ 'accessNode.api': 'https://rest-testnet.onflow.org',
+});
+```
+
+This configuration sets the access node endpoint to the Flow Testnet.
+
+Your `src/App.js` should now look like this:
+
+```jsx
+import './App.css';
+import * as fcl from '@onflow/fcl';
+
+fcl.config({
+ 'accessNode.api': 'https://rest-testnet.onflow.org',
});
+
+function App() {
+ return (
+
+
FCL App Quickstart
+
+ );
+}
+
+export default App;
```
## Querying the Chain
-On Flow, you can interact with a contract by reading from the chain with a script or changing its state with a transaction. Reading is free and is done with FCL by passing a [Cadence] script to `fcl.query`.
+Now, let's read data from a smart contract deployed on the Flow Testnet. We'll use a `HelloWorld` contract deployed to the account `0xa1296b1e2e90ca5b` (you can [view the contract here] to see what it looks like).
+
+This contract has a public variable `greeting` that we can read.
+
+First, we'll set up state in our app to store the greeting and manage component updates. We'll use React's `useState` and `useEffect` hooks.
-For our example we are going to read from a `HelloWorld` contract deployed to the account `0xa1296b1e2e90ca5b` on `testnet` (you can [view the contract here] to see what it looks like).
+Update your imports in `src/App.js` to include `useState` and `useEffect`:
-In the same `src/App.js` file, let's create app state to store our greeting and query the chain when the component renders in order to fetch the greeting state from the `HelloWorld` contract.
+```jsx
+import { useEffect, useState } from 'react';
+```
+
+Next, initialize the `greeting` state variable inside your `App` component:
+
+```jsx
+const [greeting, setGreeting] = useState('');
+```
+
+Now, let's create a function to query the greeting from the blockchain:
+
+```jsx
+const queryGreeting = async () => {
+ const res = await fcl.query({
+ cadence: `
+ import HelloWorld from 0xa1296b1e2e90ca5b
+
+ pub fun main(): String {
+ return HelloWorld.greeting
+ }
+ `,
+ });
+ setGreeting(res);
+};
+```
-```tsx
-const [greeting, setGreeting] = useState("");
+- **Explanation**:
+ - We use `fcl.query` to send a script to the Flow blockchain.
+ - The Cadence script imports the `HelloWorld` contract and defines a `main` function that returns the `greeting` variable.
+ - The result of the query is stored in `res`, and we update the `greeting` state with `setGreeting(res)`.
+Next, use the `useEffect` hook to call `queryGreeting` when the component mounts:
+
+```jsx
useEffect(() => {
- const queryChain = async () => {
+ queryGreeting();
+}, []);
+```
+
+The empty array `[]` ensures that `queryGreeting` is called only once when the component first renders.
+
+Finally, update the `return` statement to display the greeting:
+
+```jsx
+return (
+
+
FCL App Quickstart
+
Greeting: {greeting}
+
+);
+```
+
+At this point, your `src/App.js` file should look like this:
+
+```jsx
+import { useEffect, useState } from 'react';
+import './App.css';
+import * as fcl from '@onflow/fcl';
+
+fcl.config({
+ 'accessNode.api': 'https://rest-testnet.onflow.org',
+});
+
+function App() {
+ const [greeting, setGreeting] = useState('');
+
+ const queryGreeting = async () => {
const res = await fcl.query({
cadence: `
import HelloWorld from 0xa1296b1e2e90ca5b
- access(all) fun main(): String {
+ pub fun main(): String {
return HelloWorld.greeting
}
- `
+ `,
});
-
- console.log(res);
setGreeting(res);
- }
+ };
+
+ useEffect(() => {
+ queryGreeting();
+ }, []);
+
+ return (
+
+
FCL App Quickstart
+
Greeting: {greeting}
+
+ );
+}
+
+export default App;
+```
+
+Now, run `npm start` again. After a moment, the greeting from the `HelloWorld` contract should appear on your page!
+
+## Mutating the Chain State
+
+Now that we've successfully read data from the Flow blockchain, let's modify the state by changing the `greeting` in the `HelloWorld` contract. To do this, we'll need to send a transaction to the blockchain, which requires user authentication through a wallet.
- queryChain();
+### Setting Up Wallet Authentication with Discovery
+
+Before we can send a transaction, we need to set up wallet authentication. We'll use FCL's Discovery UI to allow users to connect their wallet with minimal setup.
+
+Add the following line to your FCL configuration in `src/App.js`:
+
+```jsx
+fcl.config({
+ 'accessNode.api': 'https://rest-testnet.onflow.org',
+ 'discovery.wallet': 'https://fcl-discovery.onflow.org/testnet/authn',
+});
+```
+
+**One-Line Discovery UI Setup**:
+
+- By adding the `'discovery.wallet'` line to the FCL configuration, we enable the Discovery UI.
+- This provides an interface for users to select and authenticate with a wallet.
+- This is all it takes—just one line—to integrate wallet selection into your app.
+
+### Adding Authentication Buttons
+
+Let's add a simple authentication flow to our app. We'll allow users to log in and log out, and display their account address when they're logged in.
+
+First, add a new state variable to manage the user's authentication state:
+
+```jsx
+const [user, setUser] = useState({ loggedIn: false });
+```
+
+Then, use `useEffect` to subscribe to the current user's authentication state:
+
+```jsx
+useEffect(() => {
+ fcl.currentUser.subscribe(setUser);
+ queryGreeting();
}, []);
```
-At this point our entire `src/App.js` file should look like this:
+- **Explanation**:
+ - `fcl.currentUser.subscribe(setUser)` sets up a listener that updates the `user` state whenever the authentication state changes.
+ - We also call `queryGreeting()` to fetch the greeting when the component mounts.
+
+Next, define the `logIn` and `logOut` functions:
+
+```jsx
+const logIn = () => {
+ fcl.authenticate();
+};
+
+const logOut = () => {
+ fcl.unauthenticate();
+};
+```
+
+- **Explanation**:
+ - `fcl.authenticate()` triggers the authentication process using the Discovery UI.
+ - `fcl.unauthenticate()` logs the user out.
+
+Now, update the `return` statement to include authentication buttons and display the user's address when they're logged in:
+
+```jsx
+return (
+
+
FCL App Quickstart
+
Greeting: {greeting}
+ {user.loggedIn ? (
+
+
Address: {user.addr}
+
+ {/* We'll add the transaction form here later */}
+
+ ) : (
+
+ )}
+
+);
+```
+
+Now, when the user clicks the "Log In" button, they'll be presented with the Discovery UI to select a wallet for authentication.
+
+### Sending a Transaction to Change the Greeting
+
+Next, we'll add a form to allow the user to change the greeting by sending a transaction to the blockchain.
+
+First, add a state variable to hold the new greeting:
+
+```jsx
+const [newGreeting, setNewGreeting] = useState('');
+```
-```tsx
+Now, define the `sendTransaction` function:
+
+```jsx
+const sendTransaction = async () => {
+ try {
+ const transactionId = await fcl.mutate({
+ cadence: `
+ import HelloWorld from 0xa1296b1e2e90ca5b
+
+ transaction(newGreeting: String) {
+ prepare(acct: AuthAccount) {}
+ execute {
+ HelloWorld.changeGreeting(newGreeting: newGreeting)
+ }
+ }
+ `,
+ args: (arg, t) => [arg(newGreeting, t.String)],
+ proposer: fcl.currentUser,
+ payer: fcl.currentUser,
+ authorizations: [fcl.currentUser.authorization],
+ limit: 50,
+ });
+
+ console.log('Transaction Id', transactionId);
+
+ await fcl.tx(transactionId).onceSealed();
+ console.log('Transaction Sealed');
+
+ queryGreeting();
+ setNewGreeting('');
+ } catch (error) {
+ console.error('Transaction Failed', error);
+ }
+};
+```
+
+- **Explanation**:
+ - `fcl.mutate` is used to send a transaction to the Flow blockchain.
+ - The Cadence transaction imports the `HelloWorld` contract and calls `changeGreeting` with the new greeting.
+ - We pass the `newGreeting` as an argument to the transaction.
+ - `proposer`, `payer`, and `authorizations` are set to `fcl.currentUser`, meaning the authenticated user will sign and pay for the transaction.
+ - We wait for the transaction to be sealed (completed and finalized on the blockchain) using `fcl.tx(transactionId).onceSealed()`.
+ - After the transaction is sealed, we call `queryGreeting()` to fetch the updated greeting.
+
+Next, update the `return` statement to include the input field and button for changing the greeting:
+
+```jsx
+{user.loggedIn ? (
+
+
Address: {user.addr}
+
+
+ setNewGreeting(e.target.value)}
+ />
+
+
+
+) : (
+
+)}
+```
+
+- **Explanation**:
+ - When the user is logged in, we display an input field for the new greeting and a button to submit it.
+ - The input field is controlled by the `newGreeting` state.
+ - Clicking the "Change Greeting" button triggers the `sendTransaction` function.
+
+## Full Code
+
+Your `src/App.js` should now look like this:
+
+```jsx
import { useEffect, useState } from 'react';
import './App.css';
import * as fcl from '@onflow/fcl';
fcl.config({
- 'accessNode.api': 'https://rest-testnet.onflow.org'
+ 'accessNode.api': 'https://rest-testnet.onflow.org',
+ 'discovery.wallet': 'https://fcl-discovery.onflow.org/testnet/authn',
});
function App() {
- const [greeting, setGreeting] = useState("");
-
- useEffect(() => {
- const queryChain = async () => {
- const res = await fcl.query({
- cadence: `
- import HelloWorld from 0xa1296b1e2e90ca5b
-
- access(all) fun main(): String {
- return HelloWorld.greeting
- }
- `
- });
-
- console.log(res);
- setGreeting(res);
- };
-
- queryChain();
- }, []);
-
- return (
-
+ );
}
export default App;
```
-You just built an app on Flow!
+## Running the App
+
+Now, run your app with `npm start` and open it in your browser.
-Run `npm start` again. After a moment, the greeting from `HelloWorld` will appear!
+- **Log In**:
+ - Click the "Log In" button.
+ - The Discovery UI will appear, presenting you with a list of wallets to authenticate with (e.g., Flow Wallet).
+ - Select a wallet and follow the prompts to log in.
-## Mutating Chain State and More
+- **Change Greeting**:
+ - Once logged in, you'll see your account address displayed.
+ - Enter a new greeting in the input field.
+ - Click the "Change Greeting" button.
+ - Your wallet will prompt you to approve the transaction.
+ - After approving, the transaction will be sent to the Flow blockchain.
-For a deeper dive into writing an FCL app, such as how to change the chain state with FCL, check out [the app quickstart guide] or the [FCL documentation].
+- **View Updated Greeting**:
+ - After the transaction is sealed, the app will automatically fetch and display the updated greeting.
+ - You should see your new greeting displayed on the page.
From a67aaa35f02d9537f784d04ffb0515ecdc0ce462 Mon Sep 17 00:00:00 2001
From: Chase Fleming <1666730+chasefleming@users.noreply.github.com>
Date: Thu, 24 Oct 2024 09:53:39 -0700
Subject: [PATCH 02/18] Remove quickstart
---
docs/build/guides/flow-app-quickstart.md | 407 -----------------------
1 file changed, 407 deletions(-)
delete mode 100644 docs/build/guides/flow-app-quickstart.md
diff --git a/docs/build/guides/flow-app-quickstart.md b/docs/build/guides/flow-app-quickstart.md
deleted file mode 100644
index 80cb9fa5d5..0000000000
--- a/docs/build/guides/flow-app-quickstart.md
+++ /dev/null
@@ -1,407 +0,0 @@
----
-description: Building an application on Flow
-sidebar_position: 4
-sidebar_custom_props:
- icon: 🏗️
----
-
-# Create a Web App on Flow
-
----
-
-This guide is a simple walkthrough to get started building a web3 app using the Flow Client Library (FCL).
-
-:::info
-
-If you are looking for a scaffolds, check out [scaffolds available in the Flow CLI](../../tools/flow-cli/super-commands.md#using-scaffolds).
-
-:::
-
-This simple guide uses the "Hello World" scaffold, it is meant to provide all the code needed to get a web application up and running.
-
-## Introduction
-
-![Flow app anatomy](flow-dapp-anatomy.png)
-
-:::info
-
-FCL (aka Flow Client Library) wraps the logic needed to communicate with the Flow blockchain. It's a npm package, [More Information](../../tools/clients/fcl-js)
-
-:::
-
-This guide assumes a good understanding of React. The concepts are easy to understand and apply to other libraries and framework. A strong understanding of Cadence (Flow's smart contract language) is not required. More information on Cadence, [learning the Cadence language](https://cadence-lang.org/docs/language/).
-
-### FCL concepts covered:
-
-- [Installation](#installation)
-- [Configuration](#configuration)
-- [Authenticate a user](#authenticate-a-user)
-- [Deploy contracts](#deploy-contracts)
-- [Query the Blockchain](#query-the-blockchain)
-- [Mutate the Blockchain](#mutate-the-blockchain)
-
-For more help, [Discord](https://discord.com/invite/J6fFnh2xx6). See links at the end of this article for diving deeper into building on Flow.
-
-## Installation
-
-Make sure you have Flow CLI installed. [installation instructions](../../tools/flow-cli/install.md).
-
-## Configuration
-
-### Setting up Flow
-
-Using the Flow CLI scaffold, create a basic hello world web project with `Web Scaffolds` -> `[5] FCL Web Dapp`. This will create a new `flow.json` file in the `hello-world` folder. This file will contain the Flow configuration for your project.
-
-```sh
-flow init hello-world --scaffold
-# select scaffold 5
-cd hello-world
-npm install
-# run the app in a later step
-```
-
-We don't recommend keeping private keys in your `flow.json`, notice that Flow CLI already moved the emulator private key to a `emulator.key` file and point to it using the [key/location pattern](../../tools/flow-cli/flow.json/security.md#private-account-configuration-file). This file should be added to your `.gitignore` file, so it won't be committed to your repository.
-
-We won't be using emulator and running contracts locally in this quickstart, but FCL will complain if it finds private keys in your `flow.json` file.
-
-Your `flow.json` file should look like this:
-
-```
-{
- "networks": {
- "emulator": "127.0.0.1:3569",
- "mainnet": "access.mainnet.nodes.onflow.org:9000",
- "testnet": "access.devnet.nodes.onflow.org:9000"
- },
- "accounts": {
- "emulator-account": {
- "address": "f8d6e0586b0a20c7",
- "key": {
- "type": "file",
- "location": "./emulator.key"
- }
- }
- }
-}
-```
-
-:::info
-
-The `flow.json` file is used to keep track of deployed contracts and accounts. [More Information](../../tools/clients/fcl-js/api#using-flowjson)
-
-:::
-
-### Configuring FCL
-
-Next, notice `@onflow/fcl` has been added to the `package.json` and the web application is ready to be run.
-
-:::info
-
-There are a lot of benefits to getting familiar with existing Flow CLI scaffolds. For example the `hello-world` scaffold already has fcl configuration settings to run on local emulator.
-
-:::
-
-
-The `hello-world` web application comes with convenience npm commands to facilitate a quick start. The following command will preform:
- 1. Start emulator
- 2. Start dev wallet
- 3. Start web app
-
-:::info
-
-Emulator is a local blockchain [More Information](../../tools/emulator/index.md). Emulator has all the features as testnet and mainnet blockchains
-
-:::
-
-```sh
-npm run dev:local
-```
-
-Now that your app is running. FCL loads the configuration in `config/fcl.ts` This file contains configuration information for FCL, such as what Access Node and wallet discovery endpoint and which network to use (e.g. testnet or a local emulator).
-
-- `accessNode.api` key specifies the address of a Flow access node. There are publically available access nodes, but have to rate limit. Alternatively, applications might want to run an Observer node [Run a Node](../../networks/node-ops/access-onchain-data/light-nodes/observer-node.md).
-- `discovery.wallet` is an address that points to a service that lists FCL compatible wallets. Flow's FCL Discovery service is a service that FCL wallet providers can be added to, and be made 'discoverable' to any application that uses the `discovery.wallet` endpoint.
-
-Also, notice that `package.json` uses `NEXT_PUBLIC_FLOW_NETWORK=local` for `dev` command, this is used to set the network in `config/fcl.ts`.
-
-:::info
-
-Learn more about [configuring Discovery](../../tools/clients/fcl-js/discovery.md) or [setting configuration values](../../tools/clients/fcl-js/api.md#setting-configuration-values).
-
-:::
-
-The main Next.js app component is located in `pages/_app.tsx`. It should import the config file `config/fcl.ts` already and should look like this:
-
-```jsx
-import '../styles/globals.css'
-import DefaultLayout from '../layouts/DefaultLayout'
-
-// Import FCL config
-import '../config/fcl'
-
-function MyApp({ Component, pageProps }) {
- return (
-
-
-
- )
-}
-
-export default MyApp
-
-```
-
-The main page for the Next.js app is located in `pages/index.tsx`. It should contain some basic UI and should look like this:
-
-```jsx
-import Head from 'next/head'
-import styles from '../styles/Home.module.css'
-import Links from '../components/Links'
-import Container from '../components/Container'
-import useCurrentUser from '../hooks/useCurrentUser'
-
-export default function Home() {
- const { loggedIn } = useCurrentUser()
-
- return (
-
- )
-}
-
-```
-
-Now we're ready to start talking to Flow!
-
-:::warning
-
-The web app will run, but there are no contracts deployed to local emulator. This is a step in [Query the Blockchain](#query-the-blockchain) section.
-
-:::
-
-## Authenticate a User
-
-Navigate to [localhost:3000](http://localhost:3000) in your browser.
-
-![User Login](./user-login-hello-world.gif)
-
-Note: in the code above `useCurrentUser` is used to determine if there is a logged in user.
-
-There are two methods to allow the user to login. `fcl.logIn()` or `fcl.authenticate()` [More Information on, authenticate](../../tools/clients/fcl-js/api#authenticate)
-
-In `components/Navbar.tsx` a button wires up the authentication method `fcl.authenticate()`. It is used to bring up the list of supported wallets. See below
-
-Once authenticated, FCL uses a hook `const user = useCurrentUser()` to get the user data, when user is signed in `user.loggedIn` flag is `true`. For more information on the `currentUser`, read more [here](../../tools/clients/fcl-js/api.md#current-user).
-
-```jsx
-import Head from 'next/head'
-import * as fcl from '@onflow/fcl'
-import useCurrentUser from '../hooks/useCurrentUser'
-import navbarStyles from '../styles/Navbar.module.css'
-import elementStyles from '../styles/Elements.module.css'
-
-export default function Navbar() {
- const user = useCurrentUser()
-
- return (
-
- )
-}
-
-```
-
-You should now be able to log in or sign up users and unauthenticate them. Upon logging in or signing up your users will see a popup where they can choose between wallet providers. Choose the `dev wallet` to use the same account that deployed the `HelloWorld` contract, this is needed for mutation. Upon completing authentication, you'll see the component change and the user's wallet address appear on the screen if you've completed this properly.
-
-:::info
-
-More on wallets, [Flow Core wallet](https://core.flow.com/) is a Reference Flow wallet.
-
-:::
-
-## Deploy contracts
-
-Hello World scaffold does come with a Cadence contract. You will notice `HelloWorld.cdc` has been deployed when running `npm run dev:local`. Look at hello-world `package.json` to see the commands that get run, `flow dev` deploys contracts to the emulator.
-In the `flow.json` make sure the emulator endpoint is correct. Look at the terminal the emulator is running,
-
-![Emulator Output](./emulator-output.png)
-
-1. Make sure the emulator is using the same port as `gRPC` and
-2. The `deployment` section of `flow.json` should look something like this:
-```json
- ...
- "networks": {
- "emulator": "127.0.0.1:3569",
- ...
- },
- "deployments": {
- "emulator": {
- "default": [
- "HelloWorld"
- ]
- }
-}
-
-```
-
-Verify that `flow.json` updates with HelloWorld contract information, `contracts` has the `HelloWorld` contract and `deployments` shows that `HelloWorld` has been deployed.
-
-
-```json
-{
- "contracts": {
- "HelloWorld": "cadence/contracts/HelloWorld.cdc"
- },
- "networks": {
- "emulator": "127.0.0.1:3569",
- "mainnet": "access.mainnet.nodes.onflow.org:9000",
- "testnet": "access.devnet.nodes.onflow.org:9000"
- },
- "accounts": {
- "default": {
- "address": "01cf0e2f2f715450",
- "key": "..."
- },
- "emulator-account": {
- "address": "f8d6e0586b0a20c7",
- "key": {
- "type": "file",
- "location": "./emulator.key"
- }
- }
- },
- "deployments": {
- "emulator": {
- "default": [
- "HelloWorld"
- ]
- }
- }
-}
-```
-
-For more information on deployments check [Flow CLI](../../tools/flow-cli/flow.json/manage-configuration.md) documentation
-
-## Query the Blockchain
-
-Now that all the pieces are in place, you can query the `HelloWorld` contract.
-
-Navigate again to [localhost:3000](http://localhost:3000) in your browser.
-
-![Query HelloWorld Contract](./query-helloWorld-contract.gif)
-
-
-The script that queries the Hello World contract is located `hello-world/cadence/scripts/ReadHelloWorld.cdc`
-
-```cadence
-import "HelloWorld"
-
-access(all) fun main(): String {
- return HelloWorld.greeting
-}
-```
-
-In `components/Container.tsx` file, `fcl.query` is used to set the Cadence script and query the contract.
-
-```jsx
-
- const queryChain = async () => {
- const res = await fcl.query({
- cadence: ReadHelloWorld
- })
-
- setChainGreeting(res)
- }
-```
-
-It is that simple!
-
-## Mutate the Blockchain
-
-Update the `HelloWorld` contract greeting. Notice that Greeting gets changed when the transaction gets processed.
-
-![Update contract](./hello-world-update-contract.gif)
-
-
-In `components/Container.tsx` file, the `mutateGreeting` method `fcl.mutate` sends `UpdateHelloWorld` cadence which triggers a transaction that the user signs.
-
-```javascript
- const mutateGreeting = async (event) => {
- event.preventDefault()
-
- if (!userGreetingInput.length) {
- throw new Error('Please add a new greeting string.')
- }
-
- const transactionId = await fcl.mutate({
- cadence: UpdateHelloWorld,
- args: (arg, t) => [arg(userGreetingInput, t.String)],
- })
-
- setLastTransactionId(transactionId)
- }
-
-```
-
-## More information
-
-That's it! You now have Flow app that uses auth, query and mutate the chain. This is just the beginning. There is so much more to know. Next steps:
-
-**Cadence**
-- [Cadence Playground Tutorials](https://cadence-lang.org/docs/tutorial/first-steps)
-- [Cadence Hello World Video](https://www.youtube.com/watch?v=pRz7EzrWchs)
-- [Why Cadence?](https://www.onflow.org/post/flow-blockchain-cadence-programming-language-resources-assets)
-
-**FCL Scaffolds**
-- [FCL Next TypeScript Scaffold](https://github.com/chasefleming/fcl-next-scaffold)
-- [FCL React Native Scaffold](https://github.com/jribbink/fcl-react-native-scaffold)
-
-**Full Stack NFT Marketplace Example**
-- [Beginner Example: CryptoDappy](https://github.com/bebner/crypto-dappy)
-
-**More FCL**
-- [FCL API Quick Reference](../../tools/clients/fcl-js/api)
-- [More on Scripts](../../tools/clients/fcl-js/scripts.md)
-- [More on Transactions](../../tools/clients/fcl-js/transactions.md)
-- [User Signatures](../../tools/clients/fcl-js/user-signatures.md)
-- [Proving Account Ownership](../../tools/clients/fcl-js/proving-authentication.mdx)
From 0bae5676a781d6d4fa9cadb4859ae790395671a5 Mon Sep 17 00:00:00 2001
From: Chase Fleming <1666730+chasefleming@users.noreply.github.com>
Date: Thu, 24 Oct 2024 09:53:46 -0700
Subject: [PATCH 03/18] Change links
---
docs/build/basics/flow-token.md | 2 +-
docs/build/explore-more.md | 4 ++--
docs/build/flow.md | 2 +-
docs/build/getting-started/fcl-quickstart.md | 1 -
docs/tools/clients/fcl-js/api.md | 2 +-
docs/tools/clients/fcl-js/authentication.md | 2 +-
docs/tools/clients/fcl-js/index.md | 2 +-
docs/tools/clients/fcl-js/index.mdx.txt | 4 ++--
vercel.json | 5 +++++
9 files changed, 14 insertions(+), 10 deletions(-)
diff --git a/docs/build/basics/flow-token.md b/docs/build/basics/flow-token.md
index 38eb4755c5..efabb75de9 100644
--- a/docs/build/basics/flow-token.md
+++ b/docs/build/basics/flow-token.md
@@ -107,4 +107,4 @@ The Flow SDKs also allow polling for events using the Flow Access API,
## How to Build with FLOW
-To get started building on Flow, please see the [Flow App Quickstart](../guides/flow-app-quickstart.md)
+To get started building on Flow, please see the [Flow App Quickstart](../getting-started/fcl-quickstart.md)
diff --git a/docs/build/explore-more.md b/docs/build/explore-more.md
index 2b2a959d81..2beafbda87 100644
--- a/docs/build/explore-more.md
+++ b/docs/build/explore-more.md
@@ -16,7 +16,7 @@ Below are some additional tutorials to help you get started with Flow:
{
type: 'link',
label: 'Flow App Quickstart',
- href: '/build/guides/flow-app-quickstart',
+ href: '/build/getting-started/fcl-quickstart',
description: 'Simple walkthrough building a web3 app using the Flow Client Library (FCL)',
customProps: {
icon: ,
@@ -58,7 +58,7 @@ Below are some additional tutorials to help you get started with Flow:
{
type: 'link',
label: 'Walkthrough Guides',
- href: '/build/guides/flow-app-quickstart',
+ href: '/build/getting-started/fcl-quickstart',
description: 'Longer form guides to help you get started with Flow',
customProps: {
icon: ,
diff --git a/docs/build/flow.md b/docs/build/flow.md
index f8a5c12b8e..ea35f585cb 100644
--- a/docs/build/flow.md
+++ b/docs/build/flow.md
@@ -19,7 +19,7 @@ The following chapters summarize the content in this section. Read on more for d
## App Development
-The [Flow App Quickstart](./guides/flow-app-quickstart.md) covers the Flow core concepts, including:
+The [Flow App Quickstart](./getting-started/fcl-quickstart.md) covers the Flow core concepts, including:
- **App Client:** The app client is the interface through which users interact with your app. Web and mobile applications are typical examples of app clients.
- **Smart Contract:** A smart contract is a collection of code deployed to a permanent location on the blockchain that defines the core logic for a dApp.
diff --git a/docs/build/getting-started/fcl-quickstart.md b/docs/build/getting-started/fcl-quickstart.md
index 1a1457d5e9..47bf7024fa 100644
--- a/docs/build/getting-started/fcl-quickstart.md
+++ b/docs/build/getting-started/fcl-quickstart.md
@@ -509,5 +509,4 @@ Now, run your app with `npm start` and open it in your browser.
[React]: https://react.dev/learn
[Create React App]: https://create-react-app.dev
[view the contract here]: https://f.dnz.dev/0xa1296b1e2e90ca5b/HelloWorld
-[the app quickstart guide]: ../guides/flow-app-quickstart.md
[FCL documentation]: ../../tools/clients/fcl-js/index.md
\ No newline at end of file
diff --git a/docs/tools/clients/fcl-js/api.md b/docs/tools/clients/fcl-js/api.md
index f59ce9ae3f..c747df6885 100644
--- a/docs/tools/clients/fcl-js/api.md
+++ b/docs/tools/clients/fcl-js/api.md
@@ -434,7 +434,7 @@ export const signMessage = async () => {
Discovery abstracts away code so that developers don't have to deal with the discovery of Flow compatible wallets, integration, or authentication. Using `discovery` from FCL allows dapps to list and authenticate with wallets while having full control over the UI. Common use cases for this are login or registration pages.
-(Alternatively, if you don't need control over your UI you can continue to use the `discovery.wallet` config value documented in the [Quickstart](../../../build/guides/flow-app-quickstart.md) for the simplest configuration.)
+(Alternatively, if you don't need control over your UI you can continue to use the `discovery.wallet` config value documented in the [Quickstart](../../../build/getting-started/fcl-quickstart.md) for the simplest configuration.)
> ⚠️**The following methods can only be used in web browsers.**
diff --git a/docs/tools/clients/fcl-js/authentication.md b/docs/tools/clients/fcl-js/authentication.md
index 28cb268974..a1f029aa65 100644
--- a/docs/tools/clients/fcl-js/authentication.md
+++ b/docs/tools/clients/fcl-js/authentication.md
@@ -42,6 +42,6 @@ The TL;DR is to call `fcl.authenticate()` and `fcl.unauthenticate()` respectivel
On Flow mainnet, you wont even need to configure anything for this to work, the users of your dapp will go through the authentication process and be able to use any FCL compatible wallet providers.
During development you will probably want to configure your dapp to use [`@onflow/dev-wallet`](https://github.com/onflow/fcl-dev-wallet).
-The [Quick Start](../../../build/guides/flow-app-quickstart.md) guide will walk you through using it.
+The [Quick Start](../../../build/getting-started/fcl-quickstart.md) guide will walk you through using it.
We know this can all be fairly overwhelming, we are committed to help though. If you run into any problems, reach out to us on [Discord](https://discord.gg/flow), we are more than happy to help out.
diff --git a/docs/tools/clients/fcl-js/index.md b/docs/tools/clients/fcl-js/index.md
index 2864b53af2..8cad59b29b 100644
--- a/docs/tools/clients/fcl-js/index.md
+++ b/docs/tools/clients/fcl-js/index.md
@@ -114,7 +114,7 @@ const txId = await fcl.mutate({
## Next Steps
-See the [Flow App Quick Start](../../../build/guides/flow-app-quickstart.md).
+See the [Flow App Quick Start](../../../build/getting-started/fcl-quickstart.md).
See the full [API Reference](./api.md) for all FCL functionality.
diff --git a/docs/tools/clients/fcl-js/index.mdx.txt b/docs/tools/clients/fcl-js/index.mdx.txt
index eb37d216f0..2786f23daf 100644
--- a/docs/tools/clients/fcl-js/index.mdx.txt
+++ b/docs/tools/clients/fcl-js/index.mdx.txt
@@ -7,7 +7,7 @@
View on Github»
- Quickstart
+ Quickstart
·
Report Bug
·
@@ -128,7 +128,7 @@ const txId = await fcl.mutate({
## Next Steps
-See the [Flow App Quick Start](../../guides/flow-app-quickstart.mdx).
+See the [Flow App Quick Start](../../getting-started/fcl-quickstart.mdx).
See the full [API Reference](./api.md) for all FCL functionality.
diff --git a/vercel.json b/vercel.json
index 71067480bc..4807c07f0c 100644
--- a/vercel.json
+++ b/vercel.json
@@ -1252,6 +1252,11 @@
"source": "build/smart-contracts/cadence",
"destination": "https://cadence-lang.org/docs/",
"permanent": true
+ },
+ {
+ "source": "/build/guides/flow-app-quickstart",
+ "destination": "/build/getting-started/fcl-quickstart",
+ "permanent": true
}
]
}
\ No newline at end of file
From ca0ad26bb3888c53a395bbe943b25fa6e7194408 Mon Sep 17 00:00:00 2001
From: Chase Fleming <1666730+chasefleming@users.noreply.github.com>
Date: Thu, 24 Oct 2024 14:05:17 -0700
Subject: [PATCH 04/18] Address feedback
---
docs/build/getting-started/fcl-quickstart.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/docs/build/getting-started/fcl-quickstart.md b/docs/build/getting-started/fcl-quickstart.md
index 47bf7024fa..50ea496856 100644
--- a/docs/build/getting-started/fcl-quickstart.md
+++ b/docs/build/getting-started/fcl-quickstart.md
@@ -56,11 +56,11 @@ Now, let's run our app with the following `npm` command:
npm start
```
-This will start the development server and open your app in the browser. You should see a page displaying `FCL App Quickstart`.
+This will start the development server and open your app in the browser. You will see a page displaying `FCL App Quickstart`.
## Setting Up FCL
-To interact with the Flow blockchain, we need to install the Flow Client Library (FCL). Stop the development server by pressing `Ctrl+C` in the terminal, and then run the following command to install FCL:
+To interact with the Flow blockchain, we need to install the [Flow Client Library] (FCL). Stop the development server by pressing `Ctrl+C` in the terminal, and then run the following command to install FCL:
```bash
npm install @onflow/fcl --save
@@ -68,7 +68,7 @@ npm install @onflow/fcl --save
This command installs FCL and adds it to your project's dependencies.
-Next, we'll configure FCL to connect to the Flow Testnet. An Access Node serves as the primary point of interaction for clients to communicate with the Flow network. It provides a gateway for submitting transactions, querying data, and retrieving information.
+Next, we'll configure FCL to connect to the [Flow Testnet](../../networks/flow-networks/accessing-testnet.md). An [Access Node](../../networks/node-ops/access-onchain-data/access-nodes/accessing-data/access-api.md) serves as the primary point of interaction for clients to communicate with the Flow network. It provides a gateway for submitting transactions, querying data, and retrieving information.
In `src/App.js`, import FCL and add the configuration code:
From c1931605c0728d4439fd4e5920f7d4376199928f Mon Sep 17 00:00:00 2001
From: Chase Fleming <1666730+chasefleming@users.noreply.github.com>
Date: Fri, 25 Oct 2024 09:57:08 -0700
Subject: [PATCH 05/18] Fix script
---
docs/build/getting-started/fcl-quickstart.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/docs/build/getting-started/fcl-quickstart.md b/docs/build/getting-started/fcl-quickstart.md
index 50ea496856..d664759c09 100644
--- a/docs/build/getting-started/fcl-quickstart.md
+++ b/docs/build/getting-started/fcl-quickstart.md
@@ -133,7 +133,8 @@ const queryGreeting = async () => {
cadence: `
import HelloWorld from 0xa1296b1e2e90ca5b
- pub fun main(): String {
+ access(all)
+ fun main(): String {
return HelloWorld.greeting
}
`,
From a6c2cc6b813a55ce06e41a89958cf548cbf90d3c Mon Sep 17 00:00:00 2001
From: Chase Fleming <1666730+chasefleming@users.noreply.github.com>
Date: Fri, 25 Oct 2024 09:59:39 -0700
Subject: [PATCH 06/18] Fix
---
docs/build/getting-started/fcl-quickstart.md | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/docs/build/getting-started/fcl-quickstart.md b/docs/build/getting-started/fcl-quickstart.md
index d664759c09..9687c1b7da 100644
--- a/docs/build/getting-started/fcl-quickstart.md
+++ b/docs/build/getting-started/fcl-quickstart.md
@@ -188,7 +188,8 @@ function App() {
cadence: `
import HelloWorld from 0xa1296b1e2e90ca5b
- pub fun main(): String {
+ access(all)
+ fun main(): String {
return HelloWorld.greeting
}
`,
@@ -402,7 +403,8 @@ function App() {
cadence: `
import HelloWorld from 0xa1296b1e2e90ca5b
- pub fun main(): String {
+ access(all)
+ fun main(): String {
return HelloWorld.greeting
}
`,
From f867074cb8c7154cbef4ccb54d1490e090ea1f6a Mon Sep 17 00:00:00 2001
From: Chase Fleming <1666730+chasefleming@users.noreply.github.com>
Date: Fri, 25 Oct 2024 10:44:02 -0700
Subject: [PATCH 07/18] Update tx
---
docs/build/getting-started/fcl-quickstart.md | 22 +++++++++++++-------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/docs/build/getting-started/fcl-quickstart.md b/docs/build/getting-started/fcl-quickstart.md
index 9687c1b7da..0e464b6e49 100644
--- a/docs/build/getting-started/fcl-quickstart.md
+++ b/docs/build/getting-started/fcl-quickstart.md
@@ -317,12 +317,15 @@ const sendTransaction = async () => {
cadence: `
import HelloWorld from 0xa1296b1e2e90ca5b
- transaction(newGreeting: String) {
- prepare(acct: AuthAccount) {}
- execute {
- HelloWorld.changeGreeting(newGreeting: newGreeting)
+ transaction(greeting: String) {
+ prepare(acct: &Account) {
+ log(acct.address)
+ }
+
+ execute {
+ HelloWorld.changeGreeting(newGreeting: greeting)
+ }
}
- }
`,
args: (arg, t) => [arg(newGreeting, t.String)],
proposer: fcl.currentUser,
@@ -431,10 +434,13 @@ function App() {
cadence: `
import HelloWorld from 0xa1296b1e2e90ca5b
- transaction(newGreeting: String) {
- prepare(acct: AuthAccount) {}
+ transaction(greeting: String) {
+ prepare(acct: &Account) {
+ log(acct.address)
+ }
+
execute {
- HelloWorld.changeGreeting(newGreeting: newGreeting)
+ HelloWorld.changeGreeting(newGreeting: greeting)
}
}
`,
From d0211af13e094acf9c72ba1d8dfccb9caeeac970 Mon Sep 17 00:00:00 2001
From: Chase Fleming <1666730+chasefleming@users.noreply.github.com>
Date: Fri, 25 Oct 2024 10:50:15 -0700
Subject: [PATCH 08/18] Add section about faucet
---
docs/build/getting-started/fcl-quickstart.md | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/docs/build/getting-started/fcl-quickstart.md b/docs/build/getting-started/fcl-quickstart.md
index 0e464b6e49..9af87e86f0 100644
--- a/docs/build/getting-started/fcl-quickstart.md
+++ b/docs/build/getting-started/fcl-quickstart.md
@@ -218,6 +218,12 @@ Now, run `npm start` again. After a moment, the greeting from the `HelloWorld` c
Now that we've successfully read data from the Flow blockchain, let's modify the state by changing the `greeting` in the `HelloWorld` contract. To do this, we'll need to send a transaction to the blockchain, which requires user authentication through a wallet.
+### Creating a Flow Wallet and Funding Your Testnet Account
+
+Before sending transactions, you need a Flow wallet to authenticate and interact with the blockchain. You can create a wallet by visiting the [Flow Wallet](https://wallet.flow.com/) website. Follow the on-screen instructions to set up your wallet.
+
+Once you have a wallet, make sure that your account has enough FLOW tokens to cover transaction fees on the Flow Testnet. You can fund your testnet account using the [Flow Testnet Faucet](https://faucet.flow.com/fund-account). Simply enter your account address and submit to receive testnet FLOW tokens.
+
### Setting Up Wallet Authentication with Discovery
Before we can send a transaction, we need to set up wallet authentication. We'll use FCL's Discovery UI to allow users to connect their wallet with minimal setup.
From 566174e1f877d5d8f7ac97af18004a7ce71d4ecd Mon Sep 17 00:00:00 2001
From: Chase Fleming <1666730+chasefleming@users.noreply.github.com>
Date: Mon, 4 Nov 2024 10:50:49 -0800
Subject: [PATCH 09/18] Update to counter contract
---
docs/build/getting-started/hello-world.md | 94 +++++++++++++++--------
1 file changed, 60 insertions(+), 34 deletions(-)
diff --git a/docs/build/getting-started/hello-world.md b/docs/build/getting-started/hello-world.md
index 0bbb9c62b3..883c10c2b2 100644
--- a/docs/build/getting-started/hello-world.md
+++ b/docs/build/getting-started/hello-world.md
@@ -1,10 +1,11 @@
---
sidebar_position: 1
-sidebar_label: Hello World
+sidebar_label: Contract Interaction
---
+
import VerticalSplit from "./vertical-split.svg"
-# Hello World
+# Contract Interaction
In this quickstart guide, you'll interact with your first smart contract on the Flow Testnet. `Testnet` is a public instance of the Flow blockchain designed for experimentation, where you can deploy and invoke smart contracts without incurring any real-world costs.
@@ -16,8 +17,8 @@ Flow supports modern smart contracts written in [Cadence], a resource-oriented p
After completing this guide, you'll be able to:
-* Read a public variable on a [Cadence] smart contract deployed on Flow.
-* Understand how to interact with contracts on Flow's `testnet`.
+* Read data from a [Cadence] smart contract deployed on Flow.
+* Understand how to interact with contracts on Flow's `testnet`.
* Retrieve and display data from a deployed smart contract via scripts.
In later steps, you'll learn how to:
@@ -28,80 +29,105 @@ In later steps, you'll learn how to:
* Write and execute transactions to interact with a deployed smart contract.
* Display data from a Cadence smart contract on a React frontend using the [Flow Client Library](../../tools/clients/fcl-js/index.md).
-
## Calling a Contract With a Script
-The `HelloWorld` contract exposes a public variable named `greeting` that is accessible to everything outside the contract. We can retrieve its value using a simple script written in the [Cadence] programming language. Scripts in Cadence are read-only operations that allow you to query data from the blockchain without changing any state.
+The `Counter` contract exposes a public function named `getCount()` that returns the current value of the counter. We can retrieve its value using a simple script written in the [Cadence] programming language. Scripts in Cadence are read-only operations that allow you to query data from the blockchain without changing any state.
Here's the script:
```cadence
-import HelloWorld from 0xa1296b1e2e90ca5b
+import Counter from 0x8a4dce54554b225d
-access(all) fun main(): String {
- return HelloWorld.greeting
+access(all)
+fun main(): Int {
+ return Counter.getCount()
}
```
Let's break down what this script does:
-- **Import Statement**: `import HelloWorld from 0xa1296b1e2e90ca5b` tells the script to use the `HelloWorld` contract deployed at the address `0xa1296b1e2e90ca5b` on the `testnet`.
-- **Main Function**: `access(all) fun main(): String` defines the entry point of the script, which returns a `String`.
-- **Return Statement**: `return HelloWorld.greeting` accesses the greeting variable from the `HelloWorld` contract and returns its value.
+- **Import Statement**: `import Counter from 0x8a4dce54554b225d` tells the script to use the `Counter` contract deployed at the address `0x8a4dce54554b225d` on the `testnet`.
+- **Main Function**: `access(all) fun main(): Int` defines the entry point of the script, which returns an `Int`.
+- **Return Statement**: `return Counter.getCount()` calls the `getCount()` function from the `Counter` contract and returns its value.
### Steps to Execute the Script
- **Run the Script**: Click the Run button to execute the script.
-- **View the Output**: Observe the output returned by the script. You should see the current value of the `greeting` variable, which is `"Hello, World!"`.
+- **View the Output**: Observe the output returned by the script. You should see the current value of the `count` variable, which is `0` unless it has been modified.
-
+
-## Understanding the `HelloWorld` Contract
+## Understanding the `Counter` Contract
-To fully grasp how the script works, it's important to understand the structure of the `HelloWorld` contract. Below is the source code for the contract:
+To fully grasp how the script works, it's important to understand the structure of the `Counter` contract. Below is the source code for the contract:
```cadence
-access(all) contract HelloWorld {
+access(all) contract Counter {
+
+ access(all) var count: Int
+
+ // Event to be emitted when the counter is incremented
+ access(all) event CounterIncremented(newCount: Int)
+
+ // Event to be emitted when the counter is decremented
+ access(all) event CounterDecremented(newCount: Int)
+
+ init() {
+ self.count = 0
+ }
- access(all) var greeting: String
+ // Public function to increment the counter
+ access(all) fun increment() {
+ self.count = self.count + 1
+ emit CounterIncremented(newCount: self.count)
+ }
- access(account) fun changeGreeting(newGreeting: String) {
- self.greeting = newGreeting
- }
+ // Public function to decrement the counter
+ access(all) fun decrement() {
+ self.count = self.count - 1
+ emit CounterDecremented(newCount: self.count)
+ }
- init() {
- self.greeting = "Hello, World!"
- }
+ // Public function to get the current count
+ view access(all) fun getCount(): Int {
+ return self.count
+ }
}
```
### Breakdown of the Contract
-- **Contract Declaration**: `access(all) contract HelloWorld` declares a new contract named `HelloWorld` that is accessible to everyone.
-- **State Variable**: `access(all) var greeting: String` declares a public variable `greeting` of type `String`. The `access(all)` modifier means that this variable can be read by anyone.
-- **Function to Change Greeting**: `access(account) fun changeGreeting(newGreeting: String)` defines a function that allows changing the value of `greeting`. The `access(account)` modifier restricts this function so that only the account that deployed the contract (the owner) can call it.
-- **Initializer**: The `init()` function is called when the contract is deployed. It sets the initial value of `greeting` to `"Hello, World!"`.
+- **Contract Declaration**: `access(all) contract Counter` declares a new contract named `Counter` that is accessible to everyone.
+- **State Variable**: `access(all) var count: Int` declares a public variable `count` of type `Int`. The `access(all)` modifier means that this variable can be read by anyone.
+- **Events**: Two events are declared:
+ - `CounterIncremented(newCount: Int)`: Emitted when the counter is incremented.
+ - `CounterDecremented(newCount: Int)`: Emitted when the counter is decremented.
+- **Initializer**: The `init()` function initializes the `count` variable to `0` when the contract is deployed.
+- **Public Functions**:
+ - `increment()`: Increases the `count` by `1` and emits the `CounterIncremented` event.
+ - `decrement()`: Decreases the `count` by `1` and emits the `CounterDecremented` event.
+ - `getCount()`: Returns the current value of `count`. The `view` modifier indicates that this function does not modify the contract's state.
### Key Points
-- **Public Access**: The `greeting` variable is public, allowing anyone to read its value without any restrictions.
-- **Restricted Modification**: Only the contract owner can modify the `greeting` variable using the `changeGreeting` function. This ensures that unauthorized accounts cannot change the contract's state.
-- **No Read Costs**: Reading data from the blockchain is free on Flow. Executing scripts like the one you ran does not incur any costs.
+- **Public Access**: The `count` variable and the functions `increment()`, `decrement()`, and `getCount()` are all public, allowing anyone to interact with them.
+- **State Modification**: The `increment()` and `decrement()` functions modify the state of the contract by changing the value of `count` and emitting events.
+- **Read Costs**: Reading data from the blockchain is free on Flow. Executing scripts like the one you ran does not incur any costs. However, transactions that modify state, such as calling `increment()` or `decrement()`, will incur costs and require proper authorization.
### What's Next?
In the upcoming tutorials, you'll learn how to:
-- **Modify the Greeting**: Invoke the `changeGreeting` function to update the `greeting` value.
+- **Modify the Counter**: Invoke the `increment()` and `decrement()` functions to update the `count` value.
- **Deploy Contracts**: Use the Flow CLI to deploy your own smart contracts.
- **Interact with Contracts Locally**: Use the Flow Emulator to test contracts in a local development environment.
- **Build Frontend Applications**: Display data from smart contracts in a React application using the Flow Client Library.
-By understanding the `HelloWorld` contract and how to interact with it, you're building a solid foundation for developing more complex applications on the Flow blockchain.
+By understanding the `Counter` contract and how to interact with it, you're building a solid foundation for developing more complex applications on the Flow blockchain.
Proceed to the next tutorial to learn how to create your own contracts and deploy them live using the Flow CLI.
-
+
[Cadence]: https://cadence-lang.org/
[EVM]: https://flow.com/upgrade/crescendo/evm
\ No newline at end of file
From 6801af84d80e26ef9a08e5369560cace0df5ab47 Mon Sep 17 00:00:00 2001
From: Chase Fleming <1666730+chasefleming@users.noreply.github.com>
Date: Fri, 8 Nov 2024 12:28:43 -0800
Subject: [PATCH 10/18] First draft rewrite
---
docs/build/getting-started/flow-cli.md | 200 +++++++++++--------------
1 file changed, 87 insertions(+), 113 deletions(-)
diff --git a/docs/build/getting-started/flow-cli.md b/docs/build/getting-started/flow-cli.md
index 7b667444fa..7ce38e6a2f 100644
--- a/docs/build/getting-started/flow-cli.md
+++ b/docs/build/getting-started/flow-cli.md
@@ -12,6 +12,7 @@ The [Flow Command Line Interface] (CLI) is a set of tools that developers can us
After completing this guide, you'll be able to:
* Create a Flow project using the [Flow Command Line Interface]
+* Run tests for a smart contract
* Add an already-deployed contract to your project with the [Dependency Manager]
* Deploy a smart contract locally to the Flow Emulator
* Write and execute scripts to interact with a deployed smart contract
@@ -26,65 +27,42 @@ brew install flow-cli
For other ways of installing, please refer to the [installation guide].
-## Configuration
+## Creating a New Project
-Lets first create a project directory and navigate to it:
+To create a new project, navigate to the directory where you want to create your project and run:
```zsh
-mkdir cli-quickstart
-cd cli-quickstart
+flow init
```
-Next, we'll initialize a new Flow project with the CLI:
+Upon running this command, you'll be prompted to enter a project name. Enter a name and press `Enter`.
-```zsh
-flow init --config-only
-```
+You'll also be asked if you'd like to install any core contracts (such as `FungibleToken`, `NonFungibleToken`, etc.) using the [Dependency Manager](../../tools/flow-cli/dependency-manager.md). For this tutorial, you can select `No`.
-This will create a `flow.json` file in your project directory. This file is used to configure your project and describe the setup of your contracts, networks, and accounts.
+The `init` command will create a new directory with the project name and the following files:
-It will also have a default `emulator-account` created for you. We'll use this account to interact with the emulator later on.
-
-:::info
+- `flow.json`: This file contains the configuration for your project.
+- `emulator-account.pkey`: This file contains the private key for the default emulator account.
+- `flow.json`: This file contains the configuration for your project.
+- `cadence/`: This directory contains your Cadence code. Inside there are subdirectories for contracts, scripts, transactions, and tests.
-For additional details on how `flow.json` is configured, review the [configuration docs].
+Inside the `cadence/contracts` directory, you'll find a `Counter.cdc` file. This is the same as the `Counter` contract in the previous step.
-:::
+Next, `cd` into your new project directory.
-## Grabbing the `HelloWorld` Contract
+### Running the Tests
-For this demo, we are going to be interacting with a simple `HelloWorld` contract, written in [Cadence], that is already deployed on Flow's `testnet` network on account [0xa1296b1e2e90ca5b]. In order to grab this project dependency, we'll use Flow's [Dependency Manager] to install it into our project using a source string that defines the network, address, and contract name of the contract we want to import.
+To run the example test for the `Counter` contract located in `cadence/tests`, you can run:
```zsh
-flow dependencies add testnet://0xa1296b1e2e90ca5b.HelloWorld
+flow test
```
-This will add the `HelloWorld` contract and any of its dependencies to an `imports` directory in your project. We recommend adding this directory to your `.gitignore` file, which is done by the script by default. It will also add any dependencies to your `flow.json` file.
-
-During the install you'll be prompted to specify which account to deploy the contracts to. For this tutorial, you can select the default `emulator-account`. Leave the alias address for HelloWorld on mainnet blank.
-
-Review the `📝 Dependency Manager Actions Summary` for a list of actions completed by the script.
-
-Open `imports/a1296b1e2e90ca5b/HelloWorld.cdc` in your editor. You will see the following:
-
-```cadence
-access(all) contract HelloWorld {
-
- access(all)
- var greeting: String
-
- access(all)
- fun changeGreeting(newGreeting: String) {
- self.greeting = newGreeting
- }
+:::info
- init() {
- self.greeting = "Hello, World!"
- }
-}
-```
+For additional details on how `flow.json` is configured, review the [configuration docs].
-This contract has a `greeting` variable that can be read and changed. It also has a `changeGreeting` function that allows you to change the greeting.
+:::
## Deploying the Contract to Emulator
@@ -96,50 +74,61 @@ Before we deploy, let's open a new terminal window and run the emulator. From t
flow emulator start
```
-:::warning
+Your emulator should now be running.
-If you see a message that configuration is missing, you are in the wrong directory. Do **not** run `flow init`!.
+### Deploying a Contract
+#### Creating an Account
-> 🙏 Configuration is missing, initialize it with: 'flow init' and then rerun this command.
+When you created a project you'll see that a `Counter` contract was added to your `flow.json` configuration file, but it's not set up for deployment yet. We could deploy it to the `emulator-account`, but for this example lets also create a new account on the emulator to deploy it to.
-:::
+With your emulator running, run the following command:
+
+```zsh
+flow accounts create
+```
+
+When prompted, give your account the name `test-account` and select `Emulator` as the network. You'll now see this account in your `flow.json`.
-To deploy the `HelloWorld` contract to the emulator, return to your first terminal and run the following command:
+#### Configuring the Deployment
+
+To deploy the `Counter` contract to the emulator, you'll need to add it to your project configuration. You can do this by running:
```zsh
-flow project deploy
+flow config add deployment
```
-You should see:
+You'll be prompted to select the contract you want to deploy. Select `Counter` and then select the account you want to deploy it to. For this example, select `test-account`.
+
+#### Deploying the Contract
+
+To deploy the `Counter` contract to the emulator, run:
```zsh
-🎉 All contracts deployed successfully
+flow project deploy
```
-The contract will now have been deployed to the default `emulator-account`. You can now interact with it using a script.
+That's it! You've just deployed your first contract to the Flow Emulator.
## Running Scripts
Scripts are used to read data from the Flow blockchain. There is no state modification. In our case, we are going to read a greeting from the `HelloWorld` contract.
-Let's create a script file. We can generate a boilerplate script file with the following command:
+If we wanted to generate a new script, we could run:
```zsh
-flow generate script ReadGreeting
+flow generate script ScriptName
```
-This will create a file called `ReadGreeting.cdc` in the `cadence/scripts` directory. Let's update the script to read the greeting from the `HelloWorld` contract. Replace the existing coded with:
+But the default project already has a `GetCounter` script for reading the count of the `Counter` contract. Open `cadence/scripts/GetCounter.cdc` in your editor to see the script.
-```cadence
-import "HelloWorld"
+To run the script, you can run:
-access(all) fun main(): String {
- return HelloWorld.greeting
-}
+```zsh
+flow scripts execute cadence/scripts/GetCounter.cdc
```
-The import syntax will automatically resolve the address of the contract on the network you are running the script on. This is determined by your `flow.json` configuration.
+You should see zero as the result since the `Counter` contract initializes the count to zero and we haven't run any transactions to increment it.
:::tip
@@ -147,42 +136,17 @@ If you'll like to learn more about writing scripts, please check out the docs fo
:::
-To run the script, we'll run this from the CLI:
-
-```zsh
-flow scripts execute cadence/scripts/ReadGreeting.cdc
-```
-
-You should see the result of the greeting. `Result: "Hello, world!"`
+## Executing Transactions
-## Creating an Account and Running a Transaction
+Transactions are used to modify the state of the blockchain. In our case, we want to increment the count of the `Counter` contract. Luckily, we already have a transaction for that in the project that was generated for us. Open `cadence/transactions/IncrementCounter.cdc` in your editor to see the transaction.
-To change state on the Flow Blockchain, you need to run a transaction. Let's create a simple transaction file. We can use to modify the `greeting` on the `HelloWorld` contract.
-
-First, create a file called `cadence/transactions/ChangeGreeting.cdc` with the following command:
+To run the transaction, you can run:
```zsh
-flow generate transaction ChangeGreeting
-```
-
-Open the new file - `cadence/transactions/ChangeGreeting.cdc`. Update the boilerplate transaction to look like this:
-
-```cadence
-import "HelloWorld"
-
-transaction(greeting: String) {
-
- prepare(acct: &Account) {
- log(acct.address)
- }
-
- execute {
- HelloWorld.changeGreeting(newGreeting: greeting)
- }
-}
+flow transactions send cadence/transactions/IncrementCounter.cdc
```
-This will log the account signing the transaction, call the `changeGreeting` method of the `HelloWorld` contract, and pass in the new greeting.
+By default, this uses the `emulator-account` to sign the transaction and the emulator network. If you want to use your `test-account` account, you can specify the `--signer` flag with the account name.
:::tip
@@ -190,51 +154,61 @@ If you want to learn more about writing transactions, please read the docs for [
:::
-In order to run a transaction, the signing account needs to pay for it. You could run the transaction on emulator using the default `emulator-account` account, but a better test is to run it with a new test account.
+## Installing & Interacting With External Dependencies
-Let's learn the command for creating accounts.
+In addition to creating your own contracts, you can also install contracts that have already been deployed to the network by using the [Dependency Manager]. This is useful for interacting with contracts that are part of the Flow ecosystem or that have been deployed by other developers.
-The easiest way to create an account using CLI is with:
+For example, let's say we want to format the result of our `GetCounter` script so that we display the number with commas if it's greater than 999. To do that we can install a contract called [`NumberFormatter`](https://contractbrowser.com/A.8a4dce54554b225d.NumberFormatter) from `testnet` that has a function to format numbers.
+
+To grab it, run:
```zsh
-flow accounts create
+flow dependencies add testnet://8a4dce54554b225d.NumberFormatter
```
-Remember, your emulator should still be running at this point in another terminal.
+When prompted for the account to deploy the contract to, select any account and ignore the prompt for an alias. This is if you wanted to configure a `mainnet` address for the contract.
-Give your account the name `emulator-tester`, then select `Emulator` as the network. You'll now see this account in your `flow.json`.
+This will add the `NumberFormatter` contract and any of its dependencies to an `imports` directory in your project. It will also add any dependencies to your `flow.json` file. In addition, the prompt will configure the deployment of the contract to the account you selected.
-To run a transaction with this new account, you can run the following:
+Now we can deploy the `NumberFormatter` contract to the emulator by running:
```zsh
-flow transactions send cadence/transactions/ChangeGreeting.cdc "Hello, me" --signer emulator-tester --network emulator
+flow project deploy
```
-You've just modified the state of the Flow Blockchain! At least on the emulator. You'll know it worked if you see the receipt. Yours will be similar to:
+Now that we have the `NumberFormatter` contract deployed, we can update our `GetCounter` script to format the result. Open `cadence/scripts/GetCounter.cdc` and update it to use the following code:
-```zsh
-Transaction ID: 2ff6cbb8125103595fca0abaead94cd00510d29902ceae9f5dc480e927ab7334
-
-Block ID 36bbf6fc573129fa9a3c78a43e257d3b627a3af78fd9e64eeb133d981819cc69
-Block Height 3
-Status ✅ SEALED
-ID 2ff6cbb8125103595fca0abaead94cd00510d29902ceae9f5dc480e927ab7334
-Payer 179b6b1cb6755e31
-Authorizers [179b6b1cb6755e31]
-```
+```cadence
+import "Counter"
+import "NumberFormatter"
-You can also re-run the `ReadGreeting` script with:
+access(all)
+fun main(): String {
+ // Retrieve the count from the Counter contract
+ let count: Int = Counter.getCount()
-```zsh
-flow scripts execute cadence/scripts/ReadGreeting.cdc
+ // Format the count using NumberFormatter
+ let formattedCount = NumberFormatter.formatWithCommas(number: count)
+
+ // Return the formatted count
+ return formattedCount
+}
```
-You'll now see:
+The things to note here are:
+
+- We import the `NumberFormatter` contract.
+- We call the `formatWithCommas` function from the `NumberFormatter` contract to format the count.
+- We return the formatted count as a `String`.
+
+Now, to run the updated script, you can run:
```zsh
-Result: "Hello, me"
+flow scripts execute cadence/scripts/GetCounter.cdc
```
+You should now see the result. You won't see the commas unless the number is greater than 999.
+
## More
If you want to continue on generating your own contracts, you can also use the the `generate` subcommand to create a new contract file. See more in the [`generate` documentation].
From b67585fcf535c4567a21fc07af44c95767e1226a Mon Sep 17 00:00:00 2001
From: Chase Fleming <1666730+chasefleming@users.noreply.github.com>
Date: Tue, 12 Nov 2024 15:06:41 -0800
Subject: [PATCH 11/18] Change to counter code
---
docs/build/getting-started/fcl-quickstart.md | 329 +++++++++++--------
1 file changed, 190 insertions(+), 139 deletions(-)
diff --git a/docs/build/getting-started/fcl-quickstart.md b/docs/build/getting-started/fcl-quickstart.md
index 9af87e86f0..5c9726bdd4 100644
--- a/docs/build/getting-started/fcl-quickstart.md
+++ b/docs/build/getting-started/fcl-quickstart.md
@@ -5,7 +5,7 @@ sidebar_label: Simple Frontend
# Simple Frontend
-[Flow Client Library] (FCL) is a JavaScript library developed to facilitate interactions with the Flow blockchain. It provides developers with tools to build, integrate, and interact with Flow directly from web applications. This quickstart will guide you through interacting with a contract already deployed on Flow, reading and mutating its state, and setting up wallet authentication using FCL's Discovery UI.
+[Flow Client Library] (FCL) is a JavaScript library developed to facilitate interactions with the Flow blockchain. It provides developers with tools to build, integrate, and interact with Flow directly from web applications. This quickstart will guide you through interacting with the `Counter` contract already deployed on Flow, reading and mutating its state, and setting up wallet authentication using FCL's Discovery UI.
For this tutorial, we're going to create a [React] app using [Create React App]. We'll keep the code as simple as possible, so even if you're coming from another framework, you can follow along.
@@ -13,7 +13,7 @@ For this tutorial, we're going to create a [React] app using [Create React App].
After completing this guide, you'll be able to:
-- Display data from a [Cadence] smart contract on a React frontend using the [Flow Client Library].
+- Display data from a [Cadence] smart contract (`Counter`) on a React frontend using the [Flow Client Library].
- Mutate the state of a smart contract by sending transactions using FCL and a wallet.
- Set up the Discovery UI to use a wallet for authentication.
@@ -26,7 +26,7 @@ npx create-react-app fcl-app-quickstart
cd fcl-app-quickstart
```
-This command uses sets up a new React project named `fcl-app-quickstart`. Then, we navigate into the project directory.
+This command sets up a new React project named `fcl-app-quickstart`. Then, we navigate into the project directory.
Open the new project in your editor.
@@ -68,7 +68,7 @@ npm install @onflow/fcl --save
This command installs FCL and adds it to your project's dependencies.
-Next, we'll configure FCL to connect to the [Flow Testnet](../../networks/flow-networks/accessing-testnet.md). An [Access Node](../../networks/node-ops/access-onchain-data/access-nodes/accessing-data/access-api.md) serves as the primary point of interaction for clients to communicate with the Flow network. It provides a gateway for submitting transactions, querying data, and retrieving information.
+Next, we'll configure FCL to connect to the [Flow Testnet](https://developers.flow.com/tools/access-api#testnet-access-node). An [Access Node](https://developers.flow.com/tools/access-api) serves as the primary point of interaction for clients to communicate with the Flow network. It provides a gateway for submitting transactions, querying data, and retrieving information.
In `src/App.js`, import FCL and add the configuration code:
@@ -107,11 +107,11 @@ export default App;
## Querying the Chain
-Now, let's read data from a smart contract deployed on the Flow Testnet. We'll use a `HelloWorld` contract deployed to the account `0xa1296b1e2e90ca5b` (you can [view the contract here] to see what it looks like).
+Now, let's read data from the `Counter` smart contract deployed on the Flow Testnet. We'll use the `Counter` contract deployed to the account `0x8a4dce54554b225d` (the same contract we used in previous steps).
-This contract has a public variable `greeting` that we can read.
+This contract has a public function `getCount()` that we can call to retrieve the current count.
-First, we'll set up state in our app to store the greeting and manage component updates. We'll use React's `useState` and `useEffect` hooks.
+First, we'll set up state in our app to store the count and manage component updates. We'll use React's `useState` and `useEffect` hooks.
Update your imports in `src/App.js` to include `useState` and `useEffect`:
@@ -119,52 +119,56 @@ Update your imports in `src/App.js` to include `useState` and `useEffect`:
import { useEffect, useState } from 'react';
```
-Next, initialize the `greeting` state variable inside your `App` component:
+Next, initialize the `count` state variable inside your `App` component:
```jsx
-const [greeting, setGreeting] = useState('');
+const [count, setCount] = useState(0);
```
-Now, let's create a function to query the greeting from the blockchain:
+Now, let's create a function to query the count from the blockchain:
```jsx
-const queryGreeting = async () => {
- const res = await fcl.query({
- cadence: `
- import HelloWorld from 0xa1296b1e2e90ca5b
-
- access(all)
- fun main(): String {
- return HelloWorld.greeting
- }
- `,
- });
- setGreeting(res);
+const queryCount = async () => {
+ try {
+ const res = await fcl.query({
+ cadence: `
+ import Counter from 0x8a4dce54554b225d
+
+ access(all)
+ fun main(): Int {
+ return Counter.getCount()
+ }
+ `,
+ });
+ setCount(res);
+ } catch (error) {
+ console.error('Error querying count:', error);
+ }
};
```
- **Explanation**:
- - We use `fcl.query` to send a script to the Flow blockchain.
- - The Cadence script imports the `HelloWorld` contract and defines a `main` function that returns the `greeting` variable.
- - The result of the query is stored in `res`, and we update the `greeting` state with `setGreeting(res)`.
+ - We use `fcl.query` to send a script to the Flow blockchain.
+ - The Cadence script imports the `Counter` contract and defines a `main` function that returns the `count` variable via the `getCount()` function.
+ - The result of the query is stored in `res`, and we update the `count` state with `setCount(res)`.
-Next, use the `useEffect` hook to call `queryGreeting` when the component mounts:
+Next, use the `useEffect` hook to call `queryCount` when the component mounts:
```jsx
useEffect(() => {
- queryGreeting();
+ queryCount();
}, []);
```
-The empty array `[]` ensures that `queryGreeting` is called only once when the component first renders.
+The empty array `[]` ensures that `queryCount` is called only once when the component first renders.
-Finally, update the `return` statement to display the greeting:
+Finally, update the `return` statement to display the count:
```jsx
return (
);
}
@@ -212,17 +220,17 @@ function App() {
export default App;
```
-Now, run `npm start` again. After a moment, the greeting from the `HelloWorld` contract should appear on your page!
+Now, run `npm start` again. After a moment, the count from the `Counter` contract should appear on your page!
## Mutating the Chain State
-Now that we've successfully read data from the Flow blockchain, let's modify the state by changing the `greeting` in the `HelloWorld` contract. To do this, we'll need to send a transaction to the blockchain, which requires user authentication through a wallet.
+Now that we've successfully read data from the Flow blockchain, let's modify the state by incrementing or decrementing the `count` in the `Counter` contract. To do this, we'll need to send a transaction to the blockchain, which requires user authentication through a wallet.
### Creating a Flow Wallet and Funding Your Testnet Account
-Before sending transactions, you need a Flow wallet to authenticate and interact with the blockchain. You can create a wallet by visiting the [Flow Wallet](https://wallet.flow.com/) website. Follow the on-screen instructions to set up your wallet.
+Before sending transactions, you need a Flow wallet to authenticate and interact with the blockchain. You can create a wallet by visiting the [Flow Testnet Wallet](https://testnet-faucet.onflow.org/authn) website. Follow the on-screen instructions to set up your wallet.
-Once you have a wallet, make sure that your account has enough FLOW tokens to cover transaction fees on the Flow Testnet. You can fund your testnet account using the [Flow Testnet Faucet](https://faucet.flow.com/fund-account). Simply enter your account address and submit to receive testnet FLOW tokens.
+Once you have a wallet, make sure that your account has enough FLOW tokens to cover transaction fees on the Flow Testnet. You can fund your testnet account using the [Flow Testnet Faucet](https://testnet-faucet.onflow.org/fund-account). Simply enter your account address and submit to receive testnet FLOW tokens.
### Setting Up Wallet Authentication with Discovery
@@ -258,13 +266,13 @@ Then, use `useEffect` to subscribe to the current user's authentication state:
```jsx
useEffect(() => {
fcl.currentUser.subscribe(setUser);
- queryGreeting();
+ queryCount();
}, []);
```
- **Explanation**:
- - `fcl.currentUser.subscribe(setUser)` sets up a listener that updates the `user` state whenever the authentication state changes.
- - We also call `queryGreeting()` to fetch the greeting when the component mounts.
+ - `fcl.currentUser.subscribe(setUser)` sets up a listener that updates the `user` state whenever the authentication state changes.
+ - We also call `queryCount()` to fetch the count when the component mounts.
Next, define the `logIn` and `logOut` functions:
@@ -279,8 +287,8 @@ const logOut = () => {
```
- **Explanation**:
- - `fcl.authenticate()` triggers the authentication process using the Discovery UI.
- - `fcl.unauthenticate()` logs the user out.
+ - `fcl.authenticate()` triggers the authentication process using the Discovery UI.
+ - `fcl.unauthenticate()` logs the user out.
Now, update the `return` statement to include authentication buttons and display the user's address when they're logged in:
@@ -288,12 +296,12 @@ Now, update the `return` statement to include authentication buttons and display
return (
FCL App Quickstart
-
Greeting: {greeting}
+
Count: {count}
{user.loggedIn ? (
Address: {user.addr}
- {/* We'll add the transaction form here later */}
+ {/* We'll add the transaction buttons here later */}
) : (
@@ -304,36 +312,56 @@ return (
Now, when the user clicks the "Log In" button, they'll be presented with the Discovery UI to select a wallet for authentication.
-### Sending a Transaction to Change the Greeting
+### Sending Transactions to Increment and Decrement the Counter
-Next, we'll add a form to allow the user to change the greeting by sending a transaction to the blockchain.
+Next, we'll add buttons to allow the user to increment or decrement the count by sending transactions to the blockchain.
-First, add a state variable to hold the new greeting:
+First, define the `incrementCount` and `decrementCount` functions:
```jsx
-const [newGreeting, setNewGreeting] = useState('');
-```
+const incrementCount = async () => {
+ try {
+ const transactionId = await fcl.mutate({
+ cadence: `
+ import Counter from 0x8a4dce54554b225d
-Now, define the `sendTransaction` function:
+ transaction {
+ prepare(acct: AuthAccount) {}
+ execute {
+ Counter.increment()
+ }
+ }
+ `,
+ proposer: fcl.currentUser,
+ payer: fcl.currentUser,
+ authorizations: [fcl.currentUser.authorization],
+ limit: 50,
+ });
-```jsx
-const sendTransaction = async () => {
+ console.log('Transaction Id', transactionId);
+
+ await fcl.tx(transactionId).onceSealed();
+ console.log('Transaction Sealed');
+
+ queryCount();
+ } catch (error) {
+ console.error('Transaction Failed', error);
+ }
+};
+
+const decrementCount = async () => {
try {
const transactionId = await fcl.mutate({
cadence: `
- import HelloWorld from 0xa1296b1e2e90ca5b
+ import Counter from 0x8a4dce54554b225d
- transaction(greeting: String) {
- prepare(acct: &Account) {
- log(acct.address)
- }
-
- execute {
- HelloWorld.changeGreeting(newGreeting: greeting)
- }
+ transaction {
+ prepare(acct: AuthAccount) {}
+ execute {
+ Counter.decrement()
}
+ }
`,
- args: (arg, t) => [arg(newGreeting, t.String)],
proposer: fcl.currentUser,
payer: fcl.currentUser,
authorizations: [fcl.currentUser.authorization],
@@ -345,8 +373,7 @@ const sendTransaction = async () => {
await fcl.tx(transactionId).onceSealed();
console.log('Transaction Sealed');
- queryGreeting();
- setNewGreeting('');
+ queryCount();
} catch (error) {
console.error('Transaction Failed', error);
}
@@ -354,14 +381,13 @@ const sendTransaction = async () => {
```
- **Explanation**:
- - `fcl.mutate` is used to send a transaction to the Flow blockchain.
- - The Cadence transaction imports the `HelloWorld` contract and calls `changeGreeting` with the new greeting.
- - We pass the `newGreeting` as an argument to the transaction.
- - `proposer`, `payer`, and `authorizations` are set to `fcl.currentUser`, meaning the authenticated user will sign and pay for the transaction.
- - We wait for the transaction to be sealed (completed and finalized on the blockchain) using `fcl.tx(transactionId).onceSealed()`.
- - After the transaction is sealed, we call `queryGreeting()` to fetch the updated greeting.
+ - `fcl.mutate` is used to send a transaction to the Flow blockchain.
+ - The Cadence transaction imports the `Counter` contract and calls either `increment()` or `decrement()`.
+ - `proposer`, `payer`, and `authorizations` are set to `fcl.currentUser`, meaning the authenticated user will sign and pay for the transaction.
+ - We wait for the transaction to be sealed (completed and finalized on the blockchain) using `fcl.tx(transactionId).onceSealed()`.
+ - After the transaction is sealed, we call `queryCount()` to fetch the updated count.
-Next, update the `return` statement to include the input field and button for changing the greeting:
+Next, update the `return` statement to include the buttons for incrementing and decrementing the count:
```jsx
{user.loggedIn ? (
@@ -369,13 +395,8 @@ Next, update the `return` statement to include the input field and button for ch
Address: {user.addr}
- setNewGreeting(e.target.value)}
- />
-
+
+
) : (
@@ -384,9 +405,8 @@ Next, update the `return` statement to include the input field and button for ch
```
- **Explanation**:
- - When the user is logged in, we display an input field for the new greeting and a button to submit it.
- - The input field is controlled by the `newGreeting` state.
- - Clicking the "Change Greeting" button triggers the `sendTransaction` function.
+ - When the user is logged in, we display two buttons: "Increment Count" and "Decrement Count".
+ - Clicking these buttons triggers the corresponding functions to send a transaction to increment or decrement the count.
## Full Code
@@ -403,27 +423,30 @@ fcl.config({
});
function App() {
- const [greeting, setGreeting] = useState('');
+ const [count, setCount] = useState(0);
const [user, setUser] = useState({ loggedIn: false });
- const [newGreeting, setNewGreeting] = useState('');
- const queryGreeting = async () => {
- const res = await fcl.query({
- cadence: `
- import HelloWorld from 0xa1296b1e2e90ca5b
+ const queryCount = async () => {
+ try {
+ const res = await fcl.query({
+ cadence: `
+ import Counter from 0x8a4dce54554b225d
- access(all)
- fun main(): String {
- return HelloWorld.greeting
- }
- `,
- });
- setGreeting(res);
+ access(all)
+ fun main(): Int {
+ return Counter.getCount()
+ }
+ `,
+ });
+ setCount(res);
+ } catch (error) {
+ console.error('Error querying count:', error);
+ }
};
useEffect(() => {
fcl.currentUser.subscribe(setUser);
- queryGreeting();
+ queryCount();
}, []);
const logIn = () => {
@@ -434,23 +457,49 @@ function App() {
fcl.unauthenticate();
};
- const sendTransaction = async () => {
+ const incrementCount = async () => {
try {
const transactionId = await fcl.mutate({
cadence: `
- import HelloWorld from 0xa1296b1e2e90ca5b
+ import Counter from 0x8a4dce54554b225d
- transaction(greeting: String) {
- prepare(acct: &Account) {
- log(acct.address)
+ transaction {
+ prepare(acct: AuthAccount) {}
+ execute {
+ Counter.increment()
}
-
+ }
+ `,
+ proposer: fcl.currentUser,
+ payer: fcl.currentUser,
+ authorizations: [fcl.currentUser.authorization],
+ limit: 50,
+ });
+
+ console.log('Transaction Id', transactionId);
+
+ await fcl.tx(transactionId).onceSealed();
+ console.log('Transaction Sealed');
+
+ queryCount();
+ } catch (error) {
+ console.error('Transaction Failed', error);
+ }
+ };
+
+ const decrementCount = async () => {
+ try {
+ const transactionId = await fcl.mutate({
+ cadence: `
+ import Counter from 0x8a4dce54554b225d
+
+ transaction {
+ prepare(acct: AuthAccount) {}
execute {
- HelloWorld.changeGreeting(newGreeting: greeting)
+ Counter.decrement()
}
}
`,
- args: (arg, t) => [arg(newGreeting, t.String)],
proposer: fcl.currentUser,
payer: fcl.currentUser,
authorizations: [fcl.currentUser.authorization],
@@ -462,8 +511,7 @@ function App() {
await fcl.tx(transactionId).onceSealed();
console.log('Transaction Sealed');
- queryGreeting();
- setNewGreeting('');
+ queryCount();
} catch (error) {
console.error('Transaction Failed', error);
}
@@ -472,19 +520,14 @@ function App() {
return (
FCL App Quickstart
-
Greeting: {greeting}
+
Count: {count}
{user.loggedIn ? (
Address: {user.addr}
- setNewGreeting(e.target.value)}
- />
-
+
+
) : (
@@ -502,22 +545,30 @@ export default App;
Now, run your app with `npm start` and open it in your browser.
- **Log In**:
- - Click the "Log In" button.
- - The Discovery UI will appear, presenting you with a list of wallets to authenticate with (e.g., Flow Wallet).
- - Select a wallet and follow the prompts to log in.
-
-- **Change Greeting**:
- - Once logged in, you'll see your account address displayed.
- - Enter a new greeting in the input field.
- - Click the "Change Greeting" button.
- - Your wallet will prompt you to approve the transaction.
- - After approving, the transaction will be sent to the Flow blockchain.
-
-- **View Updated Greeting**:
- - After the transaction is sealed, the app will automatically fetch and display the updated greeting.
- - You should see your new greeting displayed on the page.
-
-
+ - Click the "Log In" button.
+ - The Discovery UI will appear, presenting you with a list of wallets to authenticate with (e.g., Flow Testnet Wallet).
+ - Select a wallet and follow the prompts to log in.
+
+- **Increment or Decrement Count**:
+ - Once logged in, you'll see your account address displayed.
+ - Click the "Increment Count" or "Decrement Count" buttons.
+ - Your wallet will prompt you to approve the transaction.
+ - After approving, the transaction will be sent to the Flow blockchain.
+
+- **View Updated Count**:
+ - After the transaction is sealed, the app will automatically fetch and display the updated count.
+ - You should see the count updated on the page.
+
+---
+
+By following these steps, you've successfully created a simple frontend application that interacts with the `Counter` smart contract on the Flow blockchain. You've learned how to read data from the blockchain, authenticate users, and send transactions to mutate the state of a smart contract.
+
+
+
+[Flow Client Library]: https://github.com/onflow/fcl-js
+[Cadence]: https://developers.flow.com/cadence
+[React]: https://reactjs.org/docs/getting-started.html
+[Create React App]: https://create-react-app.dev
[Flow Client Library]: ../../tools/clients/fcl-js/index.md
[Cadence]: https://cadence-lang.org
From 2cda34865ef7379c7ea59bb271601f19a001aff7 Mon Sep 17 00:00:00 2001
From: Chase Fleming <1666730+chasefleming@users.noreply.github.com>
Date: Tue, 12 Nov 2024 15:08:04 -0800
Subject: [PATCH 12/18] Reference step one and two
---
docs/build/getting-started/fcl-quickstart.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/build/getting-started/fcl-quickstart.md b/docs/build/getting-started/fcl-quickstart.md
index 5c9726bdd4..55ba188bf4 100644
--- a/docs/build/getting-started/fcl-quickstart.md
+++ b/docs/build/getting-started/fcl-quickstart.md
@@ -5,7 +5,7 @@ sidebar_label: Simple Frontend
# Simple Frontend
-[Flow Client Library] (FCL) is a JavaScript library developed to facilitate interactions with the Flow blockchain. It provides developers with tools to build, integrate, and interact with Flow directly from web applications. This quickstart will guide you through interacting with the `Counter` contract already deployed on Flow, reading and mutating its state, and setting up wallet authentication using FCL's Discovery UI.
+Building upon the `Counter` contract you interacted with in [Step 1: Contract Interaction](hello-world.md) and deployed locally in [Step 2: Local Development](./flow-cli.md), this tutorial will guide you through creating a simple frontend application to interact with the `Counter` smart contract on the Flow blockchain. Using the [Flow Client Library] (FCL), you'll learn how to read and modify the contract's state from a React web application, and set up wallet authentication using FCL's Discovery UI.
For this tutorial, we're going to create a [React] app using [Create React App]. We'll keep the code as simple as possible, so even if you're coming from another framework, you can follow along.
From dbc542d0a89d16f3918737b88960971b3f00a40a Mon Sep 17 00:00:00 2001
From: Chase Fleming <1666730+chasefleming@users.noreply.github.com>
Date: Tue, 12 Nov 2024 15:11:57 -0800
Subject: [PATCH 13/18] Remove decrement
---
docs/build/getting-started/fcl-quickstart.md | 99 ++++----------------
1 file changed, 16 insertions(+), 83 deletions(-)
diff --git a/docs/build/getting-started/fcl-quickstart.md b/docs/build/getting-started/fcl-quickstart.md
index 55ba188bf4..09355e6f5b 100644
--- a/docs/build/getting-started/fcl-quickstart.md
+++ b/docs/build/getting-started/fcl-quickstart.md
@@ -198,11 +198,11 @@ function App() {
return Counter.getCount()
}
`,
- });
- setCount(res);
- } catch (error) {
- console.error('Error querying count:', error);
- }
+ });
+ setCount(res);
+ } catch (error) {
+ console.error('Error querying count:', error);
+ }
};
useEffect(() => {
@@ -224,7 +224,7 @@ Now, run `npm start` again. After a moment, the count from the `Counter` contrac
## Mutating the Chain State
-Now that we've successfully read data from the Flow blockchain, let's modify the state by incrementing or decrementing the `count` in the `Counter` contract. To do this, we'll need to send a transaction to the blockchain, which requires user authentication through a wallet.
+Now that we've successfully read data from the Flow blockchain, let's modify the state by incrementing the `count` in the `Counter` contract. To do this, we'll need to send a transaction to the blockchain, which requires user authentication through a wallet.
### Creating a Flow Wallet and Funding Your Testnet Account
@@ -301,7 +301,7 @@ return (
Address: {user.addr}
- {/* We'll add the transaction buttons here later */}
+ {/* We'll add the transaction button here later */}
) : (
@@ -312,11 +312,11 @@ return (
Now, when the user clicks the "Log In" button, they'll be presented with the Discovery UI to select a wallet for authentication.
-### Sending Transactions to Increment and Decrement the Counter
+### Sending a Transaction to Increment the Counter
-Next, we'll add buttons to allow the user to increment or decrement the count by sending transactions to the blockchain.
+Next, we'll add a button to allow the user to increment the count by sending a transaction to the blockchain.
-First, define the `incrementCount` and `decrementCount` functions:
+First, define the `incrementCount` function:
```jsx
const incrementCount = async () => {
@@ -348,46 +348,16 @@ const incrementCount = async () => {
console.error('Transaction Failed', error);
}
};
-
-const decrementCount = async () => {
- try {
- const transactionId = await fcl.mutate({
- cadence: `
- import Counter from 0x8a4dce54554b225d
-
- transaction {
- prepare(acct: AuthAccount) {}
- execute {
- Counter.decrement()
- }
- }
- `,
- proposer: fcl.currentUser,
- payer: fcl.currentUser,
- authorizations: [fcl.currentUser.authorization],
- limit: 50,
- });
-
- console.log('Transaction Id', transactionId);
-
- await fcl.tx(transactionId).onceSealed();
- console.log('Transaction Sealed');
-
- queryCount();
- } catch (error) {
- console.error('Transaction Failed', error);
- }
-};
```
- **Explanation**:
- `fcl.mutate` is used to send a transaction to the Flow blockchain.
- - The Cadence transaction imports the `Counter` contract and calls either `increment()` or `decrement()`.
+ - The Cadence transaction imports the `Counter` contract and calls `increment()`.
- `proposer`, `payer`, and `authorizations` are set to `fcl.currentUser`, meaning the authenticated user will sign and pay for the transaction.
- We wait for the transaction to be sealed (completed and finalized on the blockchain) using `fcl.tx(transactionId).onceSealed()`.
- After the transaction is sealed, we call `queryCount()` to fetch the updated count.
-Next, update the `return` statement to include the buttons for incrementing and decrementing the count:
+Next, update the `return` statement to include the button for incrementing the count:
```jsx
{user.loggedIn ? (
@@ -396,7 +366,6 @@ Next, update the `return` statement to include the buttons for incrementing and
-
) : (
@@ -405,8 +374,8 @@ Next, update the `return` statement to include the buttons for incrementing and
```
- **Explanation**:
- - When the user is logged in, we display two buttons: "Increment Count" and "Decrement Count".
- - Clicking these buttons triggers the corresponding functions to send a transaction to increment or decrement the count.
+ - When the user is logged in, we display a button: "Increment Count".
+ - Clicking this button triggers the `incrementCount` function to send a transaction to increment the count.
## Full Code
@@ -487,36 +456,6 @@ function App() {
}
};
- const decrementCount = async () => {
- try {
- const transactionId = await fcl.mutate({
- cadence: `
- import Counter from 0x8a4dce54554b225d
-
- transaction {
- prepare(acct: AuthAccount) {}
- execute {
- Counter.decrement()
- }
- }
- `,
- proposer: fcl.currentUser,
- payer: fcl.currentUser,
- authorizations: [fcl.currentUser.authorization],
- limit: 50,
- });
-
- console.log('Transaction Id', transactionId);
-
- await fcl.tx(transactionId).onceSealed();
- console.log('Transaction Sealed');
-
- queryCount();
- } catch (error) {
- console.error('Transaction Failed', error);
- }
- };
-
return (
FCL App Quickstart
@@ -527,7 +466,6 @@ function App() {
-
) : (
@@ -549,9 +487,9 @@ Now, run your app with `npm start` and open it in your browser.
- The Discovery UI will appear, presenting you with a list of wallets to authenticate with (e.g., Flow Testnet Wallet).
- Select a wallet and follow the prompts to log in.
-- **Increment or Decrement Count**:
+- **Increment Count**:
- Once logged in, you'll see your account address displayed.
- - Click the "Increment Count" or "Decrement Count" buttons.
+ - Click the "Increment Count" button.
- Your wallet will prompt you to approve the transaction.
- After approving, the transaction will be sent to the Flow blockchain.
@@ -565,11 +503,6 @@ By following these steps, you've successfully created a simple frontend applicat
-[Flow Client Library]: https://github.com/onflow/fcl-js
-[Cadence]: https://developers.flow.com/cadence
-[React]: https://reactjs.org/docs/getting-started.html
-[Create React App]: https://create-react-app.dev
-
[Flow Client Library]: ../../tools/clients/fcl-js/index.md
[Cadence]: https://cadence-lang.org
[React]: https://react.dev/learn
From 56d34d758bf3b1dc34859f27477c60e19945acdb Mon Sep 17 00:00:00 2001
From: Chase Fleming <1666730+chasefleming@users.noreply.github.com>
Date: Wed, 13 Nov 2024 13:06:25 -0800
Subject: [PATCH 14/18] Switch to next js
---
docs/build/getting-started/fcl-quickstart.md | 164 ++++++++-----------
1 file changed, 71 insertions(+), 93 deletions(-)
diff --git a/docs/build/getting-started/fcl-quickstart.md b/docs/build/getting-started/fcl-quickstart.md
index 09355e6f5b..cbca7f6e4f 100644
--- a/docs/build/getting-started/fcl-quickstart.md
+++ b/docs/build/getting-started/fcl-quickstart.md
@@ -5,104 +5,91 @@ sidebar_label: Simple Frontend
# Simple Frontend
-Building upon the `Counter` contract you interacted with in [Step 1: Contract Interaction](hello-world.md) and deployed locally in [Step 2: Local Development](./flow-cli.md), this tutorial will guide you through creating a simple frontend application to interact with the `Counter` smart contract on the Flow blockchain. Using the [Flow Client Library] (FCL), you'll learn how to read and modify the contract's state from a React web application, and set up wallet authentication using FCL's Discovery UI.
-
-For this tutorial, we're going to create a [React] app using [Create React App]. We'll keep the code as simple as possible, so even if you're coming from another framework, you can follow along.
+Building upon the `Counter` contract you interacted with in [Step 1: Contract Interaction](hello-world.md) and deployed locally in [Step 2: Local Development](./flow-cli.md), this tutorial will guide you through creating a simple frontend application using [Next.js] to interact with the `Counter` smart contract on the Flow blockchain. Using the [Flow Client Library] (FCL), you'll learn how to read and modify the contract's state from a React web application and set up wallet authentication using FCL's Discovery UI.
## Objectives
After completing this guide, you'll be able to:
-- Display data from a [Cadence] smart contract (`Counter`) on a React frontend using the [Flow Client Library].
+- Display data from a [Cadence] smart contract (`Counter`) on a Next.js frontend using the [Flow Client Library].
- Mutate the state of a smart contract by sending transactions using FCL and a wallet.
- Set up the Discovery UI to use a wallet for authentication.
## Creating the App
-First, let's create our app and navigate to it with the following terminal commands. From the root of where you keep your source code:
+First, let's create our Next.js app and navigate to it with the following terminal commands. From the root of where you keep your source code:
```bash
-npx create-react-app fcl-app-quickstart
+npx create-next-app@latest fcl-app-quickstart
cd fcl-app-quickstart
```
-This command sets up a new React project named `fcl-app-quickstart`. Then, we navigate into the project directory.
+This command sets up a new Next.js project named `fcl-app-quickstart`. Then, we navigate into the project directory.
Open the new project in your editor.
-The default layout includes some boilerplate code that we don't need. Let's simplify `src/App.js` to start with a clean slate. Replace the contents of `src/App.js` with:
+The default layout includes some boilerplate code that we don't need. Let's simplify `pages/index.js` to start with a clean slate. Replace the contents of `pages/index.js` with:
```jsx
-// src/App.js
-
-import './App.css';
+// pages/index.js
-function App() {
+export default function Home() {
return (
-
-
FCL App Quickstart
+
+
FCL App Quickstart
);
}
-
-export default App;
```
-This code defines a simple `App` component that displays the text "FCL App Quickstart".
+This code defines a simple `Home` component that displays the text "FCL App Quickstart".
Now, let's run our app with the following `npm` command:
```bash
-npm start
+npm run dev
```
-This will start the development server and open your app in the browser. You will see a page displaying `FCL App Quickstart`.
+This will start the development server and open your app in the browser at `http://localhost:3000`. You will see a page displaying `FCL App Quickstart`.
## Setting Up FCL
-To interact with the Flow blockchain, we need to install the [Flow Client Library] (FCL). Stop the development server by pressing `Ctrl+C` in the terminal, and then run the following command to install FCL:
+To interact with the Flow blockchain, we need to install the [Flow Client Library] (FCL). In your terminal, run the following command to install FCL:
```bash
-npm install @onflow/fcl --save
+npm install @onflow/fcl
```
This command installs FCL and adds it to your project's dependencies.
-Next, we'll configure FCL to connect to the [Flow Testnet](https://developers.flow.com/tools/access-api#testnet-access-node). An [Access Node](https://developers.flow.com/tools/access-api) serves as the primary point of interaction for clients to communicate with the Flow network. It provides a gateway for submitting transactions, querying data, and retrieving information.
+Next, we'll configure FCL to connect to the [Flow Testnet]. An [Access Node] serves as the primary point of interaction for clients to communicate with the Flow network. It provides a gateway for submitting transactions, querying data, and retrieving information.
-In `src/App.js`, import FCL and add the configuration code:
+Create a new file `flow/config.js` (you may need to create the `flow` directory inside your project root) and add the following configuration code:
```jsx
-// src/App.js
+// flow/config.js
-import * as fcl from '@onflow/fcl';
+import * as fcl from "@onflow/fcl";
fcl.config({
- 'accessNode.api': 'https://rest-testnet.onflow.org',
+ "accessNode.api": "https://rest-testnet.onflow.org",
+ "discovery.wallet": "https://fcl-discovery.onflow.org/testnet/authn",
});
```
-This configuration sets the access node endpoint to the Flow Testnet.
-
-Your `src/App.js` should now look like this:
+Then, in your `pages/_app.js` file, import the configuration:
```jsx
-import './App.css';
-import * as fcl from '@onflow/fcl';
+// pages/_app.js
-fcl.config({
- 'accessNode.api': 'https://rest-testnet.onflow.org',
-});
+import "../styles/globals.css";
+import "../flow/config"; // Import the FCL configuration
-function App() {
- return (
-
-
FCL App Quickstart
-
- );
+function MyApp({ Component, pageProps }) {
+ return ;
}
-export default App;
+export default MyApp;
```
## Querying the Chain
@@ -113,13 +100,16 @@ This contract has a public function `getCount()` that we can call to retrieve th
First, we'll set up state in our app to store the count and manage component updates. We'll use React's `useState` and `useEffect` hooks.
-Update your imports in `src/App.js` to include `useState` and `useEffect`:
+Update your imports in `pages/index.js` to include `useState`, `useEffect`, and `fcl`:
```jsx
-import { useEffect, useState } from 'react';
+// pages/index.js
+
+import { useState, useEffect } from "react";
+import * as fcl from "@onflow/fcl";
```
-Next, initialize the `count` state variable inside your `App` component:
+Next, initialize the `count` state variable inside your `Home` component:
```jsx
const [count, setCount] = useState(0);
@@ -142,7 +132,7 @@ const queryCount = async () => {
});
setCount(res);
} catch (error) {
- console.error('Error querying count:', error);
+ console.error("Error querying count:", error);
}
};
```
@@ -166,25 +156,22 @@ Finally, update the `return` statement to display the count:
```jsx
return (
-
-
FCL App Quickstart
+
+
FCL App Quickstart
Count: {count}
);
```
-At this point, your `src/App.js` file should look like this:
+At this point, your `pages/index.js` file should look like this:
```jsx
-import { useEffect, useState } from 'react';
-import './App.css';
-import * as fcl from '@onflow/fcl';
+// pages/index.js
-fcl.config({
- 'accessNode.api': 'https://rest-testnet.onflow.org',
-});
+import { useState, useEffect } from "react";
+import * as fcl from "@onflow/fcl";
-function App() {
+export default function Home() {
const [count, setCount] = useState(0);
const queryCount = async () => {
@@ -201,7 +188,7 @@ function App() {
});
setCount(res);
} catch (error) {
- console.error('Error querying count:', error);
+ console.error("Error querying count:", error);
}
};
@@ -210,17 +197,15 @@ function App() {
}, []);
return (
-
-
FCL App Quickstart
+
+
FCL App Quickstart
Count: {count}
);
}
-
-export default App;
```
-Now, run `npm start` again. After a moment, the count from the `Counter` contract should appear on your page!
+Now, run `npm run dev` again. After a moment, the count from the `Counter` contract should appear on your page!
## Mutating the Chain State
@@ -255,7 +240,7 @@ fcl.config({
Let's add a simple authentication flow to our app. We'll allow users to log in and log out, and display their account address when they're logged in.
-First, add a new state variable to manage the user's authentication state:
+First, add new state variables to manage the user's authentication state:
```jsx
const [user, setUser] = useState({ loggedIn: false });
@@ -294,8 +279,8 @@ Now, update the `return` statement to include authentication buttons and display
```jsx
return (
-
-
FCL App Quickstart
+
+
FCL App Quickstart
Count: {count}
{user.loggedIn ? (
@@ -310,8 +295,6 @@ return (
);
```
-Now, when the user clicks the "Log In" button, they'll be presented with the Discovery UI to select a wallet for authentication.
-
### Sending a Transaction to Increment the Counter
Next, we'll add a button to allow the user to increment the count by sending a transaction to the blockchain.
@@ -338,14 +321,14 @@ const incrementCount = async () => {
limit: 50,
});
- console.log('Transaction Id', transactionId);
+ console.log("Transaction Id", transactionId);
await fcl.tx(transactionId).onceSealed();
- console.log('Transaction Sealed');
+ console.log("Transaction Sealed");
queryCount();
} catch (error) {
- console.error('Transaction Failed', error);
+ console.error("Transaction Failed", error);
}
};
```
@@ -379,19 +362,15 @@ Next, update the `return` statement to include the button for incrementing the c
## Full Code
-Your `src/App.js` should now look like this:
+Your `pages/index.js` should now look like this:
```jsx
-import { useEffect, useState } from 'react';
-import './App.css';
-import * as fcl from '@onflow/fcl';
+// pages/index.js
-fcl.config({
- 'accessNode.api': 'https://rest-testnet.onflow.org',
- 'discovery.wallet': 'https://fcl-discovery.onflow.org/testnet/authn',
-});
+import { useState, useEffect } from "react";
+import * as fcl from "@onflow/fcl";
-function App() {
+export default function Home() {
const [count, setCount] = useState(0);
const [user, setUser] = useState({ loggedIn: false });
@@ -409,7 +388,7 @@ function App() {
});
setCount(res);
} catch (error) {
- console.error('Error querying count:', error);
+ console.error("Error querying count:", error);
}
};
@@ -445,20 +424,20 @@ function App() {
limit: 50,
});
- console.log('Transaction Id', transactionId);
+ console.log("Transaction Id", transactionId);
await fcl.tx(transactionId).onceSealed();
- console.log('Transaction Sealed');
+ console.log("Transaction Sealed");
queryCount();
} catch (error) {
- console.error('Transaction Failed', error);
+ console.error("Transaction Failed", error);
}
};
return (
-
-
FCL App Quickstart
+
+
FCL App Quickstart
Count: {count}
{user.loggedIn ? (
@@ -474,13 +453,11 @@ function App() {
);
}
-
-export default App;
```
## Running the App
-Now, run your app with `npm start` and open it in your browser.
+Now, run your app with `npm run dev` and open it in your browser at `http://localhost:3000`.
- **Log In**:
- Click the "Log In" button.
@@ -499,13 +476,14 @@ Now, run your app with `npm start` and open it in your browser.
---
-By following these steps, you've successfully created a simple frontend application that interacts with the `Counter` smart contract on the Flow blockchain. You've learned how to read data from the blockchain, authenticate users, and send transactions to mutate the state of a smart contract.
+By following these steps, you've successfully created a simple frontend application using Next.js that interacts with the `Counter` smart contract on the Flow blockchain. You've learned how to read data from the blockchain, authenticate users, and send transactions to mutate the state of a smart contract.
-[Flow Client Library]: ../../tools/clients/fcl-js/index.md
-[Cadence]: https://cadence-lang.org
-[React]: https://react.dev/learn
-[Create React App]: https://create-react-app.dev
-[view the contract here]: https://f.dnz.dev/0xa1296b1e2e90ca5b/HelloWorld
+[Flow Client Library]: https://github.com/onflow/fcl-js
+[Cadence]: https://developers.flow.com/cadence
+[React]: https://reactjs.org/docs/getting-started.html
+[Next.js]: https://nextjs.org/docs/getting-started
+[Flow Testnet]: https://developers.flow.com/tools/access-api#testnet-access-node
+[Access Node]: https://developers.flow.com/tools/access-api
[FCL documentation]: ../../tools/clients/fcl-js/index.md
\ No newline at end of file
From 99e50e9722e49769c4eb603f0f2d8cca0ab2cebd Mon Sep 17 00:00:00 2001
From: Chase Fleming <1666730+chasefleming@users.noreply.github.com>
Date: Wed, 13 Nov 2024 17:13:50 -0800
Subject: [PATCH 15/18] Update with next
---
docs/build/getting-started/fcl-quickstart.md | 454 ++++++++++---------
1 file changed, 242 insertions(+), 212 deletions(-)
diff --git a/docs/build/getting-started/fcl-quickstart.md b/docs/build/getting-started/fcl-quickstart.md
index cbca7f6e4f..25fe3ee946 100644
--- a/docs/build/getting-started/fcl-quickstart.md
+++ b/docs/build/getting-started/fcl-quickstart.md
@@ -5,172 +5,174 @@ sidebar_label: Simple Frontend
# Simple Frontend
-Building upon the `Counter` contract you interacted with in [Step 1: Contract Interaction](hello-world.md) and deployed locally in [Step 2: Local Development](./flow-cli.md), this tutorial will guide you through creating a simple frontend application using [Next.js] to interact with the `Counter` smart contract on the Flow blockchain. Using the [Flow Client Library] (FCL), you'll learn how to read and modify the contract's state from a React web application and set up wallet authentication using FCL's Discovery UI.
+Building upon the `Counter` contract you interacted with in [Step 1: Contract Interaction](hello-world.md) and deployed locally in [Step 2: Local Development](./flow-cli.md), this tutorial will guide you through creating a simple frontend application using [Next.js] to interact with the `Counter` smart contract on the local Flow emulator. Using the [Flow Client Library] (FCL), you'll learn how to read and modify the contract's state from a React web application, set up wallet authentication using FCL's Discovery UI connected to the local emulator, and query the chain to read data from smart contracts.
## Objectives
After completing this guide, you'll be able to:
- Display data from a [Cadence] smart contract (`Counter`) on a Next.js frontend using the [Flow Client Library].
-- Mutate the state of a smart contract by sending transactions using FCL and a wallet.
-- Set up the Discovery UI to use a wallet for authentication.
+- Query the chain to read data from smart contracts on the local emulator.
+- Mutate the state of a smart contract by sending transactions using FCL and a wallet connected to the local emulator.
+- Set up the Discovery UI to use a wallet for authentication with the local emulator.
-## Creating the App
+## Prerequisites
-First, let's create our Next.js app and navigate to it with the following terminal commands. From the root of where you keep your source code:
+- Completion of [Step 1: Contract Interaction](hello-world.md) and [Step 2: Local Development](./flow-cli.md).
+- Flow CLI installed.
+- Node.js and npm installed.
+
+## Setting Up the Next.js App
+
+Assuming you're in your project directory from Steps 1 and 2, we'll create a Next.js frontend application to interact with your smart contract deployed on the local Flow emulator.
+
+### Step 1: Create a New Next.js App
+
+First, we'll create a new Next.js application using `npx create-next-app`. We'll create it inside your existing project directory and then move it up to the root directory.
+
+**Assumption**: You are already in your project directory.
+
+Run the following command:
```bash
npx create-next-app@latest fcl-app-quickstart
-cd fcl-app-quickstart
```
-This command sets up a new Next.js project named `fcl-app-quickstart`. Then, we navigate into the project directory.
+During the setup process, you'll be prompted with several options. Choose the following:
-Open the new project in your editor.
+- **TypeScript**: **No**
+- **Use src directory**: **Yes**
+- **Use App Router**: **Yes**
-The default layout includes some boilerplate code that we don't need. Let's simplify `pages/index.js` to start with a clean slate. Replace the contents of `pages/index.js` with:
+This command will create a new Next.js project named `fcl-app-quickstart` inside your current directory.
-```jsx
-// pages/index.js
+### Step 2: Move the Next.js App Up a Directory
-export default function Home() {
- return (
-
-
FCL App Quickstart
-
- );
-}
-```
+Now, we'll move the contents of the `fcl-app-quickstart` directory up to your project root directory.
+
+**Note**: Moving the Next.js app into your existing project may overwrite existing files such as `package.json`, `package-lock.json`, `.gitignore`, etc. **Make sure to back up any important files before proceeding.** You may need to merge configurations manually.
-This code defines a simple `Home` component that displays the text "FCL App Quickstart".
+#### Remove the README File
-Now, let's run our app with the following `npm` command:
+Before moving the files, let's remove the `README.md` file from the `fcl-app-quickstart` directory to avoid conflicts:
```bash
-npm run dev
+rm fcl-app-quickstart/README.md
```
-This will start the development server and open your app in the browser at `http://localhost:3000`. You will see a page displaying `FCL App Quickstart`.
+#### Merge `.gitignore` Files and Move Contents
+
+To merge the `.gitignore` files, you can use the `cat` command to concatenate them and then remove duplicates:
-## Setting Up FCL
+```bash
+cat .gitignore fcl-app-quickstart/.gitignore | sort | uniq > temp_gitignore
+mv temp_gitignore .gitignore
+```
+
+Now, move the contents of the `fcl-app-quickstart` directory to your project root:
-To interact with the Flow blockchain, we need to install the [Flow Client Library] (FCL). In your terminal, run the following command to install FCL:
+On macOS/Linux:
```bash
-npm install @onflow/fcl
+mv fcl-app-quickstart/* .
+mv fcl-app-quickstart/.* . # This moves hidden files like .env.local if any
+rm -r fcl-app-quickstart
```
-This command installs FCL and adds it to your project's dependencies.
+On Windows (PowerShell):
-Next, we'll configure FCL to connect to the [Flow Testnet]. An [Access Node] serves as the primary point of interaction for clients to communicate with the Flow network. It provides a gateway for submitting transactions, querying data, and retrieving information.
+```powershell
+Move-Item -Path .\fcl-app-quickstart\* -Destination . -Force
+Move-Item -Path .\fcl-app-quickstart\.* -Destination . -Force
+Remove-Item -Recurse -Force .\fcl-app-quickstart
+```
-Create a new file `flow/config.js` (you may need to create the `flow` directory inside your project root) and add the following configuration code:
+**Note**: When moving hidden files (those starting with a dot, like `.gitignore`), ensure you don't overwrite important files in your root directory.
-```jsx
-// flow/config.js
+### Step 3: Install FCL
-import * as fcl from "@onflow/fcl";
+Now, install the Flow Client Library (FCL) in your project. FCL is a JavaScript library that simplifies interaction with the Flow blockchain:
-fcl.config({
- "accessNode.api": "https://rest-testnet.onflow.org",
- "discovery.wallet": "https://fcl-discovery.onflow.org/testnet/authn",
-});
+```bash
+npm install @onflow/fcl
```
-Then, in your `pages/_app.js` file, import the configuration:
+## Setting Up the Local Flow Emulator and Dev Wallet
-```jsx
-// pages/_app.js
+Before proceeding, ensure that both the Flow emulator and the Dev Wallet are running.
-import "../styles/globals.css";
-import "../flow/config"; // Import the FCL configuration
+### Step 1: Start the Flow Emulator
-function MyApp({ Component, pageProps }) {
- return ;
-}
+In a new terminal window, navigate to your project directory and run:
-export default MyApp;
+```bash
+flow emulator start
```
-## Querying the Chain
-
-Now, let's read data from the `Counter` smart contract deployed on the Flow Testnet. We'll use the `Counter` contract deployed to the account `0x8a4dce54554b225d` (the same contract we used in previous steps).
+This starts the Flow emulator on `http://localhost:8888`.
-This contract has a public function `getCount()` that we can call to retrieve the current count.
+### Step 2: Start the FCL Dev Wallet
-First, we'll set up state in our app to store the count and manage component updates. We'll use React's `useState` and `useEffect` hooks.
+In another terminal window, run:
-Update your imports in `pages/index.js` to include `useState`, `useEffect`, and `fcl`:
+```bash
+flow dev-wallet
+```
-```jsx
-// pages/index.js
+This starts the Dev Wallet, which listens on `http://localhost:8701`. The Dev Wallet is a local wallet that allows you to authenticate with the Flow blockchain and sign transactions on the local emulator. This is the wallet we'll select in Discovery UI when authenticating.
-import { useState, useEffect } from "react";
-import * as fcl from "@onflow/fcl";
-```
+## Querying the Chain
-Next, initialize the `count` state variable inside your `Home` component:
+Now, let's read data from the `Counter` smart contract deployed on the local Flow emulator.
-```jsx
-const [count, setCount] = useState(0);
-```
+Since you've already deployed the `Counter` contract in [Step 2: Local Development](./flow-cli.md), we can proceed to query it.
-Now, let's create a function to query the count from the blockchain:
+### Step 1: Update the Home Page
-```jsx
-const queryCount = async () => {
- try {
- const res = await fcl.query({
- cadence: `
- import Counter from 0x8a4dce54554b225d
+Open `src/app/page.js` in your editor.
- access(all)
- fun main(): Int {
- return Counter.getCount()
- }
- `,
- });
- setCount(res);
- } catch (error) {
- console.error("Error querying count:", error);
- }
-};
-```
+#### Adding the FCL Configuration Before the Rest
-- **Explanation**:
- - We use `fcl.query` to send a script to the Flow blockchain.
- - The Cadence script imports the `Counter` contract and defines a `main` function that returns the `count` variable via the `getCount()` function.
- - The result of the query is stored in `res`, and we update the `count` state with `setCount(res)`.
+At the top of your `page.js` file, before the rest of the code, we'll add the FCL configuration. This ensures that FCL is properly configured before we use it.
-Next, use the `useEffect` hook to call `queryCount` when the component mounts:
+Add the following code:
```jsx
-useEffect(() => {
- queryCount();
-}, []);
+import * as fcl from "@onflow/fcl";
+
+// FCL Configuration
+fcl.config({
+ "flow.network": "local",
+ "accessNode.api": "http://localhost:8888", // Flow Emulator
+ "discovery.wallet": "http://localhost:8701/fcl/authn", // Local Wallet Discovery
+});
```
-The empty array `[]` ensures that `queryCount` is called only once when the component first renders.
+This configuration code sets up FCL to work with the local Flow emulator and Dev Wallet. The `flow.network` and `accessNode.api` properties point to the local emulator, while `discovery.wallet` points to the local Dev Wallet for authentication.
-Finally, update the `return` statement to display the count:
+For more information on Discovery configurations, refer to the [Wallet Discovery Guide](../../tools/clients/fcl-js/discovery.md).
-```jsx
-return (
-
-
FCL App Quickstart
-
Count: {count}
-
-);
-```
+#### Implementing the Component
-At this point, your `pages/index.js` file should look like this:
+Now, we'll implement the component to query the count from the `Counter` contract.
+
+Update your `page.js` file to the following:
```jsx
-// pages/index.js
+// src/app/page.js
+
+"use client"; // This directive is necessary when using useState and useEffect in Next.js App Router
import { useState, useEffect } from "react";
import * as fcl from "@onflow/fcl";
+// FCL Configuration
+fcl.config({
+ "flow.network": "local",
+ "accessNode.api": "http://localhost:8888",
+ "discovery.wallet": "http://localhost:8701/fcl/authn", // Local Dev Wallet
+});
+
export default function Home() {
const [count, setCount] = useState(0);
@@ -178,11 +180,19 @@ export default function Home() {
try {
const res = await fcl.query({
cadence: `
- import Counter from 0x8a4dce54554b225d
-
+ import Counter from 0xf8d6e0586b0a20c7
+ import NumberFormatter from 0xf8d6e0586b0a20c7
+
access(all)
- fun main(): Int {
- return Counter.getCount()
+ fun main(): String {
+ // Retrieve the count from the Counter contract
+ let count: Int = Counter.getCount()
+
+ // Format the count using NumberFormatter
+ let formattedCount = NumberFormatter.formatWithCommas(number: count)
+
+ // Return the formatted count
+ return formattedCount
}
`,
});
@@ -205,48 +215,44 @@ export default function Home() {
}
```
-Now, run `npm run dev` again. After a moment, the count from the `Counter` contract should appear on your page!
-
-## Mutating the Chain State
-
-Now that we've successfully read data from the Flow blockchain, let's modify the state by incrementing the `count` in the `Counter` contract. To do this, we'll need to send a transaction to the blockchain, which requires user authentication through a wallet.
+In the above code:
-### Creating a Flow Wallet and Funding Your Testnet Account
+- We import the necessary React hooks (`useState` and `useEffect`) and the FCL library.
+- We define the `Home` component, which is the main page of our app.
+- We set up a state variable `count` using the `useState` hook to store the count value.
+- We define an `async` function `queryCount` to query the count from the `Counter` contract.
+- We use the `useEffect` hook to call `queryCount` when the component mounts.
+- We return a simple JSX structure that displays the count value on the page.
+- If an error occurs during the query, we log it to the console.
+- We use the script from Step 2 to query the count from the `Counter` contract and format it using the `NumberFormatter` contract.
-Before sending transactions, you need a Flow wallet to authenticate and interact with the blockchain. You can create a wallet by visiting the [Flow Testnet Wallet](https://testnet-faucet.onflow.org/authn) website. Follow the on-screen instructions to set up your wallet.
+### Step 2: Run the App
-Once you have a wallet, make sure that your account has enough FLOW tokens to cover transaction fees on the Flow Testnet. You can fund your testnet account using the [Flow Testnet Faucet](https://testnet-faucet.onflow.org/fund-account). Simply enter your account address and submit to receive testnet FLOW tokens.
+Start your development server:
-### Setting Up Wallet Authentication with Discovery
-
-Before we can send a transaction, we need to set up wallet authentication. We'll use FCL's Discovery UI to allow users to connect their wallet with minimal setup.
-
-Add the following line to your FCL configuration in `src/App.js`:
-
-```jsx
-fcl.config({
- 'accessNode.api': 'https://rest-testnet.onflow.org',
- 'discovery.wallet': 'https://fcl-discovery.onflow.org/testnet/authn',
-});
+```bash
+npm run dev
```
-**One-Line Discovery UI Setup**:
+Visit `http://localhost:3000` in your browser. You should see the current count displayed on the page, formatted according to the `NumberFormatter` contract.
-- By adding the `'discovery.wallet'` line to the FCL configuration, we enable the Discovery UI.
-- This provides an interface for users to select and authenticate with a wallet.
-- This is all it takes—just one line—to integrate wallet selection into your app.
+## Mutating the Chain State
-### Adding Authentication Buttons
+Now that we've successfully read data from the Flow blockchain emulator, let's modify the state by incrementing the `count` in the `Counter` contract. We'll set up wallet authentication and send a transaction to the blockchain emulator.
-Let's add a simple authentication flow to our app. We'll allow users to log in and log out, and display their account address when they're logged in.
+### Adding Authentication and Transaction Functionality
-First, add new state variables to manage the user's authentication state:
+#### Step 1: Manage Authentication State
+
+In `src/app/page.js`, add new state variables to manage the user's authentication state:
```jsx
const [user, setUser] = useState({ loggedIn: false });
```
-Then, use `useEffect` to subscribe to the current user's authentication state:
+#### Step 2: Subscribe to Authentication Changes
+
+Update the `useEffect` hook to subscribe to the current user's authentication state:
```jsx
useEffect(() => {
@@ -255,11 +261,11 @@ useEffect(() => {
}, []);
```
-- **Explanation**:
- - `fcl.currentUser.subscribe(setUser)` sets up a listener that updates the `user` state whenever the authentication state changes.
- - We also call `queryCount()` to fetch the count when the component mounts.
+The `currentUser.subscribe` method listens for changes to the current user's authentication state and updates the `user` state accordingly.
-Next, define the `logIn` and `logOut` functions:
+#### Step 3: Define Log In and Log Out Functions
+
+Define the `logIn` and `logOut` functions:
```jsx
const logIn = () => {
@@ -271,49 +277,34 @@ const logOut = () => {
};
```
-- **Explanation**:
- - `fcl.authenticate()` triggers the authentication process using the Discovery UI.
- - `fcl.unauthenticate()` logs the user out.
-
-Now, update the `return` statement to include authentication buttons and display the user's address when they're logged in:
-
-```jsx
-return (
-
-
FCL App Quickstart
-
Count: {count}
- {user.loggedIn ? (
-
-
Address: {user.addr}
-
- {/* We'll add the transaction button here later */}
-
- ) : (
-
- )}
-
-);
-```
-
-### Sending a Transaction to Increment the Counter
+The `authenticate` method opens the Discovery UI for the user to log in, while `unauthenticate` logs the user out.
-Next, we'll add a button to allow the user to increment the count by sending a transaction to the blockchain.
+#### Step 4: Define the `incrementCount` Function
-First, define the `incrementCount` function:
+Add the `incrementCount` function:
```jsx
const incrementCount = async () => {
try {
const transactionId = await fcl.mutate({
cadence: `
- import Counter from 0x8a4dce54554b225d
+ import Counter from 0xf8d6e0586b0a20c7
transaction {
- prepare(acct: AuthAccount) {}
+
+ prepare(acct: &Account) {
+ // Authorizes the transaction
+ }
+
execute {
- Counter.increment()
+ // Increment the counter
+ Counter.increment()
+
+ // Retrieve the new count and log it
+ let newCount = Counter.getCount()
+ log("New count after incrementing: ".concat(newCount.toString()))
}
- }
+ }
`,
proposer: fcl.currentUser,
payer: fcl.currentUser,
@@ -333,43 +324,61 @@ const incrementCount = async () => {
};
```
-- **Explanation**:
- - `fcl.mutate` is used to send a transaction to the Flow blockchain.
- - The Cadence transaction imports the `Counter` contract and calls `increment()`.
- - `proposer`, `payer`, and `authorizations` are set to `fcl.currentUser`, meaning the authenticated user will sign and pay for the transaction.
- - We wait for the transaction to be sealed (completed and finalized on the blockchain) using `fcl.tx(transactionId).onceSealed()`.
- - After the transaction is sealed, we call `queryCount()` to fetch the updated count.
+In the above code:
+
+- We define an `async` function `incrementCount` to send a transaction to increment the count in the `Counter` contract.
+- We use the `mutate` method to send a transaction to the blockchain emulator.
+- The transaction increments the count in the `Counter` contract and logs the new count.
+- We use the `proposer`, `payer`, and `authorizations` properties to set the transaction's proposer, payer, and authorizations to the current user.
+- The `limit` property sets the gas limit for the transaction.
+- We log the transaction ID and wait for the transaction to be sealed before querying the updated count.
+- If an error occurs during the transaction, we log it to the console.
+- After the transaction is sealed, we call `queryCount` to fetch and display the updated count.
+- We use the transaction from Step 2 to increment the count in the `Counter` contract.
-Next, update the `return` statement to include the button for incrementing the count:
+#### Step 5: Update the Return Statement
+
+Update the `return` statement to include authentication buttons and display the user's address when they're logged in:
```jsx
-{user.loggedIn ? (
+return (
-
Address: {user.addr}
-
-
-
-
+
FCL App Quickstart
+
Count: {count}
+ {user.loggedIn ? (
+
+
Address: {user.addr}
+
+
+
+
+
+ ) : (
+
+ )}
-) : (
-
-)}
+);
```
-- **Explanation**:
- - When the user is logged in, we display a button: "Increment Count".
- - Clicking this button triggers the `incrementCount` function to send a transaction to increment the count.
-
-## Full Code
+#### Full `page.js` Code
-Your `pages/index.js` should now look like this:
+Your `src/app/page.js` should now look like this:
```jsx
-// pages/index.js
+// src/app/page.js
+
+"use client";
import { useState, useEffect } from "react";
import * as fcl from "@onflow/fcl";
+// FCL Configuration
+fcl.config({
+ "flow.network": "local",
+ "accessNode.api": "http://localhost:8888",
+ "discovery.wallet": "http://localhost:8701/fcl/authn", // Local Dev Wallet
+});
+
export default function Home() {
const [count, setCount] = useState(0);
const [user, setUser] = useState({ loggedIn: false });
@@ -378,11 +387,19 @@ export default function Home() {
try {
const res = await fcl.query({
cadence: `
- import Counter from 0x8a4dce54554b225d
-
+ import Counter from 0xf8d6e0586b0a20c7
+ import NumberFormatter from 0xf8d6e0586b0a20c7
+
access(all)
- fun main(): Int {
- return Counter.getCount()
+ fun main(): String {
+ // Retrieve the count from the Counter contract
+ let count: Int = Counter.getCount()
+
+ // Format the count using NumberFormatter
+ let formattedCount = NumberFormatter.formatWithCommas(number: count)
+
+ // Return the formatted count
+ return formattedCount
}
`,
});
@@ -409,14 +426,23 @@ export default function Home() {
try {
const transactionId = await fcl.mutate({
cadence: `
- import Counter from 0x8a4dce54554b225d
+ import Counter from 0xf8d6e0586b0a20c7
transaction {
- prepare(acct: AuthAccount) {}
+
+ prepare(acct: &Account) {
+ // Authorizes the transaction
+ }
+
execute {
- Counter.increment()
+ // Increment the counter
+ Counter.increment()
+
+ // Retrieve the new count and log it
+ let newCount = Counter.getCount()
+ log("New count after incrementing: ".concat(newCount.toString()))
}
- }
+ }
`,
proposer: fcl.currentUser,
payer: fcl.currentUser,
@@ -455,35 +481,39 @@ export default function Home() {
}
```
-## Running the App
-
-Now, run your app with `npm run dev` and open it in your browser at `http://localhost:3000`.
+Visit `http://localhost:3000` in your browser.
- **Log In**:
- Click the "Log In" button.
- - The Discovery UI will appear, presenting you with a list of wallets to authenticate with (e.g., Flow Testnet Wallet).
- - Select a wallet and follow the prompts to log in.
+ - The Discovery UI will appear, showing the available wallets. Select the "Dev Wallet" option.
+ - Select the account to log in with.
+ - If prompted, create a new account or use an existing one.
- **Increment Count**:
- - Once logged in, you'll see your account address displayed.
+ - After logging in, you'll see your account address displayed.
- Click the "Increment Count" button.
- Your wallet will prompt you to approve the transaction.
- - After approving, the transaction will be sent to the Flow blockchain.
+ - Approve the transaction to send it to the Flow emulator.
- **View Updated Count**:
- - After the transaction is sealed, the app will automatically fetch and display the updated count.
- - You should see the count updated on the page.
+ - Once the transaction is sealed, the app will automatically fetch and display the updated count.
+ - You should see the count incremented on the page, formatted using the `NumberFormatter` contract.
----
+## Conclusion
+
+By following these steps, you've successfully created a simple frontend application using Next.js that interacts with the `Counter` smart contract on the Flow blockchain emulator. You've learned how to:
-By following these steps, you've successfully created a simple frontend application using Next.js that interacts with the `Counter` smart contract on the Flow blockchain. You've learned how to read data from the blockchain, authenticate users, and send transactions to mutate the state of a smart contract.
+- Add the FCL configuration before the rest of your code within the `page.js` file.
+- Configure FCL to work with the local Flow emulator and Dev Wallet.
+- Start the Dev Wallet using `flow dev-wallet` to enable local authentication.
+- Read data from the local blockchain emulator, utilizing multiple contracts (`Counter` and `NumberFormatter`).
+- Authenticate users using the local Dev Wallet.
+- Send transactions to mutate the state of a smart contract on the local emulator.
-
+## Additional Resources
[Flow Client Library]: https://github.com/onflow/fcl-js
[Cadence]: https://developers.flow.com/cadence
-[React]: https://reactjs.org/docs/getting-started.html
[Next.js]: https://nextjs.org/docs/getting-started
-[Flow Testnet]: https://developers.flow.com/tools/access-api#testnet-access-node
-[Access Node]: https://developers.flow.com/tools/access-api
-[FCL documentation]: ../../tools/clients/fcl-js/index.md
\ No newline at end of file
+[Flow Emulator]: https://developers.flow.com/tools/emulator
+[Flow Dev Wallet]: https://github.com/onflow/fcl-dev-wallet
\ No newline at end of file
From 4986a1049287ea2dc7593d9105bdc6216d87bab1 Mon Sep 17 00:00:00 2001
From: Chase Fleming <1666730+chasefleming@users.noreply.github.com>
Date: Wed, 13 Nov 2024 17:13:58 -0800
Subject: [PATCH 16/18] Add
---
docs/build/getting-started/flow-cli.md | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/docs/build/getting-started/flow-cli.md b/docs/build/getting-started/flow-cli.md
index 7ce38e6a2f..937996c838 100644
--- a/docs/build/getting-started/flow-cli.md
+++ b/docs/build/getting-started/flow-cli.md
@@ -168,7 +168,9 @@ flow dependencies add testnet://8a4dce54554b225d.NumberFormatter
When prompted for the account to deploy the contract to, select any account and ignore the prompt for an alias. This is if you wanted to configure a `mainnet` address for the contract.
-This will add the `NumberFormatter` contract and any of its dependencies to an `imports` directory in your project. It will also add any dependencies to your `flow.json` file. In addition, the prompt will configure the deployment of the contract to the account you selected.
+This will add the `NumberFormatter` contract and any of its dependencies to an `imports` directory in your project. It will also add any dependencies to your `flow.json` file. In addition, the prompt will configure the deployment of the contract to the account you selected. Make sure to select the `test-account` account to deploy the contract to the emulator.
+
+You should then see the `NumberFormatter` in your deployments for emulator in your `flow.json`. If you messed this up, you can always run `flow config add deployment` to add the contract to your deployments.
Now we can deploy the `NumberFormatter` contract to the emulator by running:
From 671161734d1e0b3756a5a177706148da06c8495f Mon Sep 17 00:00:00 2001
From: Chase Fleming <1666730+chasefleming@users.noreply.github.com>
Date: Wed, 13 Nov 2024 17:15:20 -0800
Subject: [PATCH 17/18] Change to emulator account
---
docs/build/getting-started/flow-cli.md | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/docs/build/getting-started/flow-cli.md b/docs/build/getting-started/flow-cli.md
index 937996c838..ee4b8d9143 100644
--- a/docs/build/getting-started/flow-cli.md
+++ b/docs/build/getting-started/flow-cli.md
@@ -90,6 +90,8 @@ flow accounts create
When prompted, give your account the name `test-account` and select `Emulator` as the network. You'll now see this account in your `flow.json`.
+> Note: We won't use this much in this example, but it's good to know how to create an account.
+
#### Configuring the Deployment
To deploy the `Counter` contract to the emulator, you'll need to add it to your project configuration. You can do this by running:
@@ -98,7 +100,7 @@ To deploy the `Counter` contract to the emulator, you'll need to add it to your
flow config add deployment
```
-You'll be prompted to select the contract you want to deploy. Select `Counter` and then select the account you want to deploy it to. For this example, select `test-account`.
+You'll be prompted to select the contract you want to deploy. Select `Counter` and then select the account you want to deploy it to. For this example, select `emulator-account`.
#### Deploying the Contract
@@ -168,7 +170,7 @@ flow dependencies add testnet://8a4dce54554b225d.NumberFormatter
When prompted for the account to deploy the contract to, select any account and ignore the prompt for an alias. This is if you wanted to configure a `mainnet` address for the contract.
-This will add the `NumberFormatter` contract and any of its dependencies to an `imports` directory in your project. It will also add any dependencies to your `flow.json` file. In addition, the prompt will configure the deployment of the contract to the account you selected. Make sure to select the `test-account` account to deploy the contract to the emulator.
+This will add the `NumberFormatter` contract and any of its dependencies to an `imports` directory in your project. It will also add any dependencies to your `flow.json` file. In addition, the prompt will configure the deployment of the contract to the account you selected. Make sure to select the `emulator-account` account to deploy the contract to the emulator.
You should then see the `NumberFormatter` in your deployments for emulator in your `flow.json`. If you messed this up, you can always run `flow config add deployment` to add the contract to your deployments.
From a5eb4fa55130d0fa8a97ba240ce58c4f01869d7a Mon Sep 17 00:00:00 2001
From: Chase Fleming <1666730+chasefleming@users.noreply.github.com>
Date: Thu, 14 Nov 2024 17:19:48 -0800
Subject: [PATCH 18/18] Fix link
---
docs/build/guides/account-linking-with-dapper.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/build/guides/account-linking-with-dapper.md b/docs/build/guides/account-linking-with-dapper.md
index 7716057365..89b8f79ac9 100644
--- a/docs/build/guides/account-linking-with-dapper.md
+++ b/docs/build/guides/account-linking-with-dapper.md
@@ -746,7 +746,7 @@ In this tutorial, you took your first steps towards building powerful new experi
[initializes a project]: ../../tools/flow-cli/super-commands.md#init
[Flow Dependency Manager]: ../../tools/flow-cli/dependency-manager.md
[FCL]: ../../tools/clients/fcl-js/index.md
-[App Quickstart Guide]: ./flow-app-quickstart.md
+[App Quickstart Guide]: ../getting-started/fcl-quickstart.md
[Wallet Connect]: https://cloud.walletconnect.com/sign-in
[Flow Wallet]: https://wallet.flow.com
[link your Dapper Wallet]: https://support.meetdapper.com/hc/en-us/articles/20744347884819-Account-Linking-and-FAQ
\ No newline at end of file