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 bd532d649a..25fe3ee946 100644 --- a/docs/build/getting-started/fcl-quickstart.md +++ b/docs/build/getting-started/fcl-quickstart.md @@ -5,164 +5,515 @@ 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. - -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. +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 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]. +- 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. + +## Prerequisites + +- 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 -## Creating the 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. -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: +**Assumption**: You are already in your project directory. -```zsh -npx create-react-app fcl-app-quickstart -cd fcl-app-quickstart +Run the following command: + +```bash +npx create-next-app@latest fcl-app-quickstart ``` -Open the new project in a new window in your editor. +During the setup process, you'll be prompted with several options. Choose the following: -It comes with a default layout, but let's remove it in `src/App.js` with something simple. Copy and paste this: +- **TypeScript**: **No** +- **Use src directory**: **Yes** +- **Use App Router**: **Yes** -```tsx -// src/App.js +This command will create a new Next.js project named `fcl-app-quickstart` inside your current directory. -import './App.css'; +### Step 2: Move the Next.js App Up a Directory -function App() { - 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. + +#### Remove the README File + +Before moving the files, let's remove the `README.md` file from the `fcl-app-quickstart` directory to avoid conflicts: -export default App; +```bash +rm fcl-app-quickstart/README.md ``` -Now let's run our app with the following `npm` command: +#### Merge `.gitignore` Files and Move Contents -```zsh -npm start +To merge the `.gitignore` files, you can use the `cat` command to concatenate them and then remove duplicates: + +```bash +cat .gitignore fcl-app-quickstart/.gitignore | sort | uniq > temp_gitignore +mv temp_gitignore .gitignore ``` -You'll see a blank page with `FCL App Quickstart` at the top. +Now, move the contents of the `fcl-app-quickstart` directory to your project root: + +On macOS/Linux: -## Setting Up FCL +```bash +mv fcl-app-quickstart/* . +mv fcl-app-quickstart/.* . # This moves hidden files like .env.local if any +rm -r fcl-app-quickstart +``` -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: +On Windows (PowerShell): +```powershell +Move-Item -Path .\fcl-app-quickstart\* -Destination . -Force +Move-Item -Path .\fcl-app-quickstart\.* -Destination . -Force +Remove-Item -Recurse -Force .\fcl-app-quickstart ``` -npm install @onflow/fcl --save + +**Note**: When moving hidden files (those starting with a dot, like `.gitignore`), ensure you don't overwrite important files in your root directory. + +### Step 3: Install FCL + +Now, install the Flow Client Library (FCL) in your project. FCL is a JavaScript library that simplifies interaction with the Flow blockchain: + +```bash +npm install @onflow/fcl ``` -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. +## Setting Up the Local Flow Emulator and Dev Wallet -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`: +Before proceeding, ensure that both the Flow emulator and the Dev Wallet are running. -```tsx -// src/App.js +### Step 1: Start the Flow Emulator -import * as fcl from '@onflow/fcl'; +In a new terminal window, navigate to your project directory and run: -fcl.config({ - 'accessNode.api': 'https://rest-testnet.onflow.org' -}); +```bash +flow emulator start ``` +This starts the Flow emulator on `http://localhost:8888`. + +### Step 2: Start the FCL Dev Wallet + +In another terminal window, run: + +```bash +flow dev-wallet +``` + +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. + ## 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 the `Counter` smart contract deployed on the local Flow emulator. -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). +Since you've already deployed the `Counter` contract in [Step 2: Local Development](./flow-cli.md), we can proceed to query it. -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. +### Step 1: Update the Home Page -```tsx -const [greeting, setGreeting] = useState(""); +Open `src/app/page.js` in your editor. -useEffect(() => { - const queryChain = async () => { - const res = await fcl.query({ - cadence: ` - import HelloWorld from 0xa1296b1e2e90ca5b +#### Adding the FCL Configuration Before the Rest - access(all) fun main(): String { - return HelloWorld.greeting - } - ` - }); +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. - console.log(res); - setGreeting(res); - } +Add the following code: - queryChain(); -}, []); +```jsx +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 +}); ``` -At this point our entire `src/App.js` file should look like this: +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. -```tsx -import { useEffect, useState } from 'react'; -import './App.css'; -import * as fcl from '@onflow/fcl'; +For more information on Discovery configurations, refer to the [Wallet Discovery Guide](../../tools/clients/fcl-js/discovery.md). +#### Implementing the Component + +Now, we'll implement the component to query the count from the `Counter` contract. + +Update your `page.js` file to the following: + +```jsx +// 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({ - 'accessNode.api': 'https://rest-testnet.onflow.org' + "flow.network": "local", + "accessNode.api": "http://localhost:8888", + "discovery.wallet": "http://localhost:8701/fcl/authn", // Local Dev Wallet }); -function App() { - const [greeting, setGreeting] = useState(""); +export default function Home() { + const [count, setCount] = useState(0); + + const queryCount = async () => { + try { + const res = await fcl.query({ + cadence: ` + import Counter from 0xf8d6e0586b0a20c7 + import NumberFormatter from 0xf8d6e0586b0a20c7 + + access(all) + 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 + } + `, + }); + setCount(res); + } catch (error) { + console.error("Error querying count:", error); + } + }; + + useEffect(() => { + queryCount(); + }, []); + + return ( +
+

FCL App Quickstart

+
Count: {count}
+
+ ); +} +``` + +In the above code: - useEffect(() => { - const queryChain = async () => { - const res = await fcl.query({ - cadence: ` - import HelloWorld from 0xa1296b1e2e90ca5b +- 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. - access(all) fun main(): String { - return HelloWorld.greeting - } - ` - }); +### Step 2: Run the App - console.log(res); - setGreeting(res); - }; +Start your development server: + +```bash +npm run dev +``` - queryChain(); - }, []); +Visit `http://localhost:3000` in your browser. You should see the current count displayed on the page, formatted according to the `NumberFormatter` contract. - return ( -
-
FCL App Quickstart
-
{greeting}
+## Mutating the Chain State + +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. + +### Adding Authentication and Transaction Functionality + +#### 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 }); +``` + +#### Step 2: Subscribe to Authentication Changes + +Update the `useEffect` hook to subscribe to the current user's authentication state: + +```jsx +useEffect(() => { + fcl.currentUser.subscribe(setUser); + queryCount(); +}, []); +``` + +The `currentUser.subscribe` method listens for changes to the current user's authentication state and updates the `user` state accordingly. + +#### Step 3: Define Log In and Log Out Functions + +Define the `logIn` and `logOut` functions: + +```jsx +const logIn = () => { + fcl.authenticate(); +}; + +const logOut = () => { + fcl.unauthenticate(); +}; +``` + +The `authenticate` method opens the Discovery UI for the user to log in, while `unauthenticate` logs the user out. + +#### Step 4: Define the `incrementCount` Function + +Add the `incrementCount` function: + +```jsx +const incrementCount = async () => { + try { + const transactionId = await fcl.mutate({ + cadence: ` + import Counter from 0xf8d6e0586b0a20c7 + + transaction { + + prepare(acct: &Account) { + // Authorizes the transaction + } + + execute { + // 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, + 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); + } +}; +``` + +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. + +#### 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 +return ( +
+

FCL App Quickstart

+
Count: {count}
+ {user.loggedIn ? ( +
+

Address: {user.addr}

+ +
+
- ); -} +
+ ) : ( + + )} +
+); +``` + +#### Full `page.js` Code + +Your `src/app/page.js` should now look like this: + +```jsx +// src/app/page.js -export default App; +"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 }); + + const queryCount = async () => { + try { + const res = await fcl.query({ + cadence: ` + import Counter from 0xf8d6e0586b0a20c7 + import NumberFormatter from 0xf8d6e0586b0a20c7 + + access(all) + 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 + } + `, + }); + setCount(res); + } catch (error) { + console.error("Error querying count:", error); + } + }; + + useEffect(() => { + fcl.currentUser.subscribe(setUser); + queryCount(); + }, []); + + const logIn = () => { + fcl.authenticate(); + }; + + const logOut = () => { + fcl.unauthenticate(); + }; + + const incrementCount = async () => { + try { + const transactionId = await fcl.mutate({ + cadence: ` + import Counter from 0xf8d6e0586b0a20c7 + + transaction { + + prepare(acct: &Account) { + // Authorizes the transaction + } + + execute { + // 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, + 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

+
Count: {count}
+ {user.loggedIn ? ( +
+

Address: {user.addr}

+ +
+ +
+
+ ) : ( + + )} +
+ ); +} ``` -You just built an app on Flow! +Visit `http://localhost:3000` in your browser. + +- **Log In**: + - Click the "Log In" button. + - 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**: + - After logging in, you'll see your account address displayed. + - Click the "Increment Count" button. + - Your wallet will prompt you to approve the transaction. + - Approve the transaction to send it to the Flow emulator. + +- **View Updated Count**: + - 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. -Run `npm start` again. After a moment, the greeting from `HelloWorld` will appear! +## Conclusion -## Mutating Chain State and More +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: -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]. +- 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]: ../../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 -[the app quickstart guide]: ../guides/flow-app-quickstart.md -[FCL documentation]: ../../tools/clients/fcl-js/index.md \ No newline at end of file +[Flow Client Library]: https://github.com/onflow/fcl-js +[Cadence]: https://developers.flow.com/cadence +[Next.js]: https://nextjs.org/docs/getting-started +[Flow Emulator]: https://developers.flow.com/tools/emulator +[Flow Dev Wallet]: https://github.com/onflow/fcl-dev-wallet \ No newline at end of file diff --git a/docs/build/getting-started/flow-cli.md b/docs/build/getting-started/flow-cli.md index 7b667444fa..ee4b8d9143 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,63 @@ 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 +``` -To deploy the `HelloWorld` contract to the emulator, return to your first terminal and run the following command: +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: ```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 `emulator-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 +138,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!"` - -## Creating an Account and Running a Transaction +## Executing Transactions -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. +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. -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 +flow transactions send cadence/transactions/IncrementCounter.cdc ``` -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) - } -} -``` - -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 +156,63 @@ 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 + +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. -Let's learn the command for creating accounts. +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. -The easiest way to create an account using CLI is with: +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. + +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. -Give your account the name `emulator-tester`, then select `Emulator` as the network. You'll now see this account in your `flow.json`. +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. -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]. 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 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 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 ( -
- - - FCL Next Scaffold - - - - -
-

- FCL Next Scaffold -

- -

- For the Flow Blockchain -

- - {loggedIn && } - - - -
-
- ) -} - -``` - -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 ( -
- {!user.loggedIn && - - } - {user.loggedIn && - ( - <> -
{ user?.addr }
- - - ) - } -
- ) -} - -``` - -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) diff --git a/docs/tools/clients/fcl-js/api.md b/docs/tools/clients/fcl-js/api.md index acdc7d7ad9..d7716fd7c0 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/vercel.json b/vercel.json index 28e4a74ab3..839bd46cb9 100644 --- a/vercel.json +++ b/vercel.json @@ -1253,6 +1253,11 @@ "destination": "https://cadence-lang.org/docs/", "permanent": true }, + { + "source": "/build/guides/flow-app-quickstart", + "destination": "/build/getting-started/fcl-quickstart", + "permanent": true + }, { "source": "/build/guides/flow-cli", "destination": "/tools/flow-cli/install",